commit 3fc6b954cd129e416ca125a2eab7353d24e31090
parent 7307b7b3bcdd9d30da75fdafd301eb31d4a86e18
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 21 Jul 2023 15:21:38 +0200
Extensive rework of the POSIX Makefile
Split the linker flags in 2 different macros: the SOFLAGS macro defines
the flags when creating a shared object, i.e. a dynamic library, and the
LDFLAGS macro defines the linker options for all linking operations,
i.e. when creating a shared object or an executable.
Add the BUILD_TYPE macro which controls if the compilation is done in
RELEASE or in DEBUG: the CFLAGS and LDFLAGS macros are defined according
to BUILD_TYPE.
Add building the library as a static library. The new LIB_TYPE macro
controls whether the generated library is a shared object or an archive,
depending on whether its value is SHARED or STATIC respectively. Note
that the new macro PCFLAGS, whose value depends on LIB_TYPE, controls
whether pkg-config fetches dependencies for static linking or not.
Do not hide the compiler commands anymore (except for the file
dependency check). There is no particular advantage in doing this and it
is sane to see the compiler options used. In the same spirit, the
commands executed by the clean, distclean and lint targets are also
displayed to show what they do.
Clean up the make.sh script by replacing the sed directives with
basename, which is what these seds were actually doing. Redirect error
messages from the for loop into the run_test function to show only the
defined error message and no longer show the number of failed tests as
it seems unnecessary.
Use the new install function in the make.sh script to install the files.
It creates the target directory if necessary and copies the files only
if they are updated, thus avoiding forcing the reconstruction for
projects relying on the library after copying its unchanged header
files.
Generate a pkg-config file to build the tests from the locally compiled
library. The local library is effectively a dependency of the tests, and
therefore can be tracked through a pkg-config file. Moreover, relying
on it allows us to manage static links easily.
Diffstat:
| M | .gitignore | | | 4 | ++-- |
| M | Makefile | | | 108 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
| M | config.mk | | | 52 | +++++++++++++++++++++++++++++++++++++++------------- |
| M | make.sh | | | 31 | +++++++++++++++++++++++++------ |
4 files changed, 125 insertions(+), 70 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -6,8 +6,8 @@
*~
test*
!test*.[ch]
-.pkg
+.config
.test
tags
-smsh.pc
+*.pc
smsh.5
diff --git a/Makefile b/Makefile
@@ -18,42 +18,48 @@
include config.mk
+LIBNAME_STATIC = libsmsh.a
+LIBNAME_SHARED = libsmsh.so
+LIBNAME = $(LIBNAME_$(LIB_TYPE))
+
################################################################################
-# Star-Mesh building
+# Library building
################################################################################
-SRC =\
- src/smsh.c\
- src/smsh_log.c
-
+SRC = src/smsh.c src/smsh_log.c
OBJ = $(SRC:.c=.o)
DEP = $(SRC:.c=.d)
-build_library: .pkg $(DEP)
- @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) libsmsh.so
+build_library: .config $(DEP)
+ @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) \
+ $$(if [ -n "$(LIBNAME)" ]; then\
+ echo "$(LIBNAME)";\
+ else\
+ echo "$(LIBNAME_SHARED)";\
+ fi)
+
+$(DEP) $(OBJ): config.mk
-$(OBJ): config.mk
+$(LIBNAME_SHARED): $(OBJ)
+ $(CC) $(CFLAGS) $(RSYS_CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(SOFLAGS) $(RSYS_LIBS)
-libsmsh.so: $(OBJ)
- @echo "LD $@"
- @$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@ $(OBJ)
+$(LIBNAME_STATIC): $(OBJ)
+ $(AR) -rc $@ $?
+ $(RANLIB) $@
-.pkg: config.mk
+.config: config.mk
@if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then\
- >&2 printf "\e[1;31merror\e[0m: RSys $(RSYS_VERSION): dependency is missing\n";\
- exit 1;\
- fi
+ echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi
@echo "config done" > $@
.SUFFIXES: .c .d .o
.c.d:
- @$(CC) $(CFLAGS) $(INCS) -MM -MT "$(@:.d=.o) $@" $< -MF $@
+ @$(CC) $(CFLAGS) $(RSYS_CFLAGS) -MM -MT "$(@:.d=.o) $@" $< -MF $@
.c.o:
- @echo "CC $@"
- @$(CC) $(CFLAGS) $(INCS) -DSMSH_SHARED_BUILD -c $< -o $@
+ $(CC) $(CFLAGS) $(RSYS_CFLAGS) -DSMSH_SHARED_BUILD -c $< -o $@
smsh.5: doc/smsh.5.scd
- scdoc < $< > $@
+ scdoc < doc/$@.scd > $@
################################################################################
# Installation
@@ -65,25 +71,28 @@ pkg:
-e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g' \
smsh.pc.in > smsh.pc
+smsh-local.pc: smsh.pc.in
+ @sed -e '1d'\
+ -e 's#^includedir=.*#includedir=./src/#'\
+ -e 's#^libdir=.*#libdir=./#'\
+ -e 's#@VERSION@#$(VERSION)#g'\
+ -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g'\
+ smsh.pc.in > $@
+
install: build_library pkg smsh.5
- mkdir -p $(DESTDIR)$(PREFIX)/lib
- mkdir -p $(DESTDIR)$(PREFIX)/lib/pkgconfig
- mkdir -p $(DESTDIR)$(PREFIX)/include/star
- mkdir -p $(DESTDIR)$(PREFIX)/share/man/man5
- mkdir -p $(DESTDIR)$(PREFIX)/share/doc/star-mesh
- cp libsmsh.so $(DESTDIR)$(PREFIX)/lib
- cp smsh.pc $(DESTDIR)$(PREFIX)/lib/pkgconfig
- cp src/smsh.h $(DESTDIR)$(PREFIX)/include/star
- cp smsh.5 $(DESTDIR)$(PREFIX)/share/man/man5
- cp COPYING README.md $(DESTDIR)$(PREFIX)/share/doc/star-mesh
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib" $(LIBNAME)
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib/pkgconfig" smsh.pc
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/include/star" src/smsh.h
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/doc/star-mesh" COPYING README.md
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/man/man5" smsh.5
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/lib/libsmsh.so
- rm -f $(DESTDIR)$(PREFIX)/lib/pkgconfig/smsh.pc
- rm -f $(DESTDIR)$(PREFIX)/share/doc/star-mesh/COPYING
- rm -f $(DESTDIR)$(PREFIX)/share/doc/star-mesh/README.md
- rm -f $(DESTDIR)$(PREFIX)/include/star/smsh.h
- rm -f $(DESTDIR)$(PREFIX)/share/man/man5/smsh.5
+ rm -f "$(DESTDIR)$(PREFIX)/lib/$(LIBNAME)"
+ rm -f "$(DESTDIR)$(PREFIX)/lib/pkgconfig/smsh.pc"
+ rm -f "$(DESTDIR)$(PREFIX)/share/doc/star-mesh/COPYING"
+ rm -f "$(DESTDIR)$(PREFIX)/share/doc/star-mesh/README.md"
+ rm -f "$(DESTDIR)$(PREFIX)/include/star/smsh.h"
+ rm -f "$(DESTDIR)$(PREFIX)/share/man/man5/smsh.5"
################################################################################
# Miscellaneous targets
@@ -91,24 +100,25 @@ uninstall:
all: build_library build_tests smsh.5
clean: clean_test
- @rm -f $(OBJ) $(TEST_OBJ) libsmsh.so .test .pkg smsh.pc smsh.5
+ rm -f $(OBJ) $(TEST_OBJ) $(LIBNAME) .config .test smsh.5 smsh.pc smsh-local.pc
distclean: clean
- @rm -f $(DEP) $(TEST_DEP)
+ rm -f $(DEP) $(TEST_DEP)
lint:
- @shellcheck -o all make.sh
+ shellcheck -o all make.sh
################################################################################
# Tests
################################################################################
-TEST_SRC =\
- src/test_smsh.c\
- src/test_smsh_load.c
-
+TEST_SRC = src/test_smsh.c src/test_smsh_load.c
TEST_OBJ = $(TEST_SRC:.c=.o)
TEST_DEP = $(TEST_SRC:.c=.d)
+PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./:$${PKG_CONFIG_PATH}" $(PKG_CONFIG)
+SMSH_CFLAGS = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags smsh-local.pc)
+SMSH_LIBS = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs smsh-local.pc)
+
test: build_tests
@$(SHELL) make.sh run_test $(TEST_SRC)
@@ -122,12 +132,12 @@ build_tests: build_library $(TEST_DEP) .test
clean_test:
@$(SHELL) make.sh clean_test $(TEST_SRC)
-$(TEST_OBJ) $(TEST_DEP): config.mk
+$(TEST_DEP): config.mk smsh-local.pc
+ @$(CC) $(CFLAGS) $(RSYS_CFLAGS) $(SMSH_CFLAGS) \
+ -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@
-$(TEST_OBJ): config.mk
- @echo "CC $@"
- @$(CC) $(CFLAGS) $(RSYS_INC) -c $(@:.o=.c) -o $@
+$(TEST_OBJ): config.mk smsh-local.pc
+ $(CC) $(CFLAGS) $(RSYS_CFLAGS) $(SMSH_CFLAGS) -c $(@:.o=.c) -o $@
-test_smsh test_smsh_load: src/test_smsh.o libsmsh.so config.mk
- @echo "LD $@"
- @$(CC) $(CFLAGS) -o $@ src/$@.o -L$$(pwd) -lsmsh $(RSYS_LIB)
+test_smsh test_smsh_load: config.mk smsh-local.pc
+ $(CC) -o $@ src/$@.o $(RSYS_LIBS) $(SMSH_LIBS)
diff --git a/config.mk b/config.mk
@@ -1,24 +1,34 @@
-VERSION = 0.0.0 # Library version
-
+VERSION = 0.0.0
PREFIX = /usr/local
+
+LIB_TYPE = SHARED
+#LIB_TYPE = STATIC
+
+BUILD_TYPE = RELEASE
+#BUILD_TYPE = DEBUG
+
+################################################################################
+# Tools
+################################################################################
+AR = ar
+CC = cc
PKG_CONFIG = pkg-config
+RANLIB = ranlib
################################################################################
# Dependencies
################################################################################
-RSYS_VERSION=0.13
-RSYS_INC = $$($(PKG_CONFIG) --cflags rsys)
-RSYS_LIB = $$($(PKG_CONFIG) --libs rsys)
+PCFLAGS_SHARED =
+PCFLAGS_STATIC = --static
+PCFLAGS = $(PCFLAGS_$(LIB_TYPE))
-INCS=$(RSYS_INC)
-LIBS=$(RSYS_LIB)
+RSYS_VERSION=0.13
+RSYS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys)
+RSYS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys)
################################################################################
# Compilation options
################################################################################
-CC = cc # Compiler
-
-CPPFLAGS = -DNDEBUG
WFLAGS =\
-Wall\
-Wcast-align\
@@ -28,7 +38,23 @@ WFLAGS =\
-Wmissing-prototypes\
-Wshadow
-CFLAGS = -O3 -std=c89 -pedantic -fPIC -fvisibility=hidden -fstrict-aliasing\
- -Wl,--no-undefined $(WFLAGS) $(CPPFLAGS) # Compiler options
+CFLAGS_COMMON =\
+ -std=c89\
+ -pedantic\
+ -fPIC\
+ -fvisibility=hidden\
+ -fstrict-aliasing\
+ $(WFLAGS)
+
+CFLAGS_RELEASE = -O2 -DNDEBUG $(CFLAGS_COMMON)
+CFLAGS_DEBUG = -g $(CFLAGS_COMMON)
+CFLAGS = $(CFLAGS_$(BUILD_TYPE))
+
+################################################################################
+# Linker options
+################################################################################
+SOFLAGS = -shared -Wl,--no-undefined
-LDFLAGS = -shared # Linker options
+LDFLAGS_DEBUG =
+LDFLAGS_RELEASE = -s
+LDFLAGS = $(LDFLAGS_$(BUILD_TYPE))
diff --git a/make.sh b/make.sh
@@ -18,7 +18,7 @@
config_test()
{
for i in "$@"; do
- test=$(echo "${i}" | sed 's/src\/\(.\{1,\}\).c$/\1/')
+ test=$(basename "${i}" ".c")
test_list="${test_list} ${test}"
printf "%s: %s\n" "${test}" "src/${test}.o"
done
@@ -28,21 +28,40 @@ config_test()
run_test()
{
for i in "$@"; do
- test=$(echo "${i}" | sed 's/src\/\(.\{1,\}\).c$/\1/')
+ test=$(basename "${i}" ".c")
+
printf "%s " "${test}"
- if ./"${test}" > /dev/null 2>&1; then
+ if "./${test}" > /dev/null 2>&1; then
printf "\e[1;32mOK\e[m\n"
else
printf "\e[1;31mErreur\e[m\n"
fi
- done
+ done 2> /dev/null
}
clean_test()
{
for i in "$@"; do
- test=$(echo "${i}" | sed 's/src\/\(.\{1,\}\).c$/\1/')
- rm -f "${test}"
+ rm -f "$(basename "${i}" ".c")"
+ done
+}
+
+install()
+{
+ prefix=$1
+ shift 1
+
+ mkdir -p "${prefix}"
+
+ for i in "$@"; do
+ dst="${prefix}/${i##*/}"
+
+ if cmp -s "${i}" "${dst}"; then
+ printf "Up to date %s\n" "${dst}"
+ else
+ printf "Installing %s\n" "${dst}"
+ cp "${i}" "${prefix}"
+ fi
done
}