commit ccc1539f48939f472e65a75ce31e287a95f4b19c
parent d43545ee5a9d408c1f366a84e4dfc038f75afc43
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 29 Jun 2023 09:31:53 +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 targets are also displayed to
show what they do.
Add the lint target which uses shellcheck to check the make.sh script.
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.
Clean up the make.sh script by replacing the sed directives with
basename, which is what these seds were actually doing. We also removed
an unnecessary input argument check in the config_test function since it
is only called internally and should be called correctly, except for a
bug. We 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.
Diffstat:
| M | .gitignore | | | 2 | +- |
| M | Makefile | | | 110 | +++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
| M | config.mk | | | 52 | ++++++++++++++++++++++++++++++++++++++++------------ |
| M | make.sh | | | 39 | +++++++++++++++++++++++++-------------- |
4 files changed, 129 insertions(+), 74 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -9,4 +9,4 @@ test*
.test
.config
tags
-polygon.pc
+polygon*.pc
diff --git a/Makefile b/Makefile
@@ -18,48 +18,45 @@
include config.mk
+LIBNAME_STATIC = libpolygon.a
+LIBNAME_SHARED = libpolygon.so
+LIBNAME = $(LIBNAME_$(LIB_TYPE))
+
################################################################################
-# RSys building
+# Library building
################################################################################
SRC = src/polygon.c
-
OBJ = $(SRC:.c=.o)
DEP = $(SRC:.c=.d)
build_library: .config $(DEP)
- @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) libpolygon.so
+ @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) \
+ $$(if [ -n "$(LIBNAME)" ]; then\
+ echo "$(LIBNAME)";\
+ else\
+ echo "$(LIBNAME_SHARED)";\
+ fi)
$(OBJ): config.mk
-libpolygon.so: $(OBJ)
- @echo "LD $@"
- @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
+$(LIBNAME_SHARED): $(OBJ)
+ $(CC) $(CFLAGS) $(DPDC_CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(SOFLAGS) $(DPDC_LIBS)
+
+$(LIBNAME_STATIC): $(OBJ)
+ $(AR) -rc $@ $?
+ $(RANLIB) $@
.config: Makefile config.mk
- @echo "Find packages"
@if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \
- echo "rsys $(RSYS_VERSION) not found"; exit 1; fi
+ echo "rsys $(RSYS_VERSION) not found"; exit 1; fi
@echo "config done" > .config
.SUFFIXES: .c .d .o
.c.d:
- @echo "DEP $@"
- @$(CC) $(CFLAGS) $(INCS) -MM -MT "$(@:.d=.o) $@" $< -MF $@
+ @$(CC) $(CFLAGS) $(DPDC_CFLAGS) -MM -MT "$(@:.d=.o) $@" $< -MF $@
.c.o:
- @echo "CC $@"
- @$(CC) $(CFLAGS) $(INCS) -DPOLYGON_SHARED_BUILD -c $< -o $@
-
-################################################################################
-# Miscellaneous targets
-################################################################################
-all: build_library build_tests
-
-clean: clean_test
- @rm -f $(OBJ) $(TEST_OBJ) libpolygon.so .test polygon.pc .config
-
-distclean: clean
- @rm -f $(DEP) $(TEST_DEP)
+ $(CC) $(CFLAGS) $(DPDC_CFLAGS) -DPOLYGON_SHARED_BUILD -c $< -o $@
################################################################################
# Installation
@@ -71,22 +68,41 @@ pkg:
-e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g' \
polygon.pc.in > polygon.pc
+polygon-local.pc: polygon.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'\
+ polygon.pc.in > $@
+
install: build_library pkg
- mkdir -p $(DESTDIR)$(PREFIX)/lib
- mkdir -p $(DESTDIR)$(PREFIX)/lib/pkgconfig
- mkdir -p $(DESTDIR)$(PREFIX)/include/
- mkdir -p $(DESTDIR)$(PREFIX)/share/doc/polygon
- cp libpolygon.so $(DESTDIR)$(PREFIX)/lib
- cp polygon.pc $(DESTDIR)$(PREFIX)/lib/pkgconfig
- cp COPYING README.md $(DESTDIR)$(PREFIX)/share/doc/polygon
- cp src/polygon.h $(DESTDIR)$(PREFIX)/include
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib" $(LIBNAME)
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib/pkgconfig" polygon.pc
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/include" src/polygon.h
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/doc/polygon"\
+ COPYING README.md
uninstall:
- rm -f $(DESTDIR)$(PREFIX)/lib/libpolygon.so
- rm -f $(DESTDIR)$(PREFIX)/lib/pkgconfig/polygon.pc
- rm -f $(DESTDIR)$(PREFIX)/share/doc/polygon/COPYING
- rm -f $(DESTDIR)$(PREFIX)/share/doc/polygon/README.md
- rm -f $(DESTDIR)$(PREFIX)/include/polygon.h
+ rm -f "$(DESTDIR)$(PREFIX)/lib/$(LIBNAME)"
+ rm -f "$(DESTDIR)$(PREFIX)/lib/pkgconfig/polygon.pc"
+ rm -f "$(DESTDIR)$(PREFIX)/share/doc/polygon/COPYING"
+ rm -f "$(DESTDIR)$(PREFIX)/share/doc/polygon/README.md"
+ rm -f "$(DESTDIR)$(PREFIX)/include/polygon.h"
+
+################################################################################
+# Miscellaneous targets
+################################################################################
+all: build_library build_tests
+
+clean: clean_test
+ @rm -f $(OBJ) $(TEST_OBJ) $(LIBNAME) .test polygon.pc polygon-local.pc .config
+
+distclean: clean
+ @rm -f $(DEP) $(TEST_DEP)
+
+lint:
+ shellcheck -o all make.sh
################################################################################
# Tests
@@ -94,27 +110,27 @@ uninstall:
TEST_SRC =\
src/test_polygon.c\
src/test_polygon1.c
-
TEST_OBJ = $(TEST_SRC:.c=.o)
TEST_DEP = $(TEST_SRC:.c=.d)
-test: build_tests
- @$(SHELL) make.sh run_test $(TEST_SRC)
+PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./:$${PKG_CONFIG_PATH}" $(PKG_CONFIG)
+POLYGON_CFLAGS = $$($(PKG_CONFIG_LOCAL) --cflags polygon-local.pc)
+POLYGON_LIBS = $$($(PKG_CONFIG_LOCAL) --libs polygon-local.pc)
build_tests: build_library $(TEST_DEP) .test
@$(MAKE) -fMakefile -f.test $$(for i in $(TEST_DEP); do echo -f"$${i}"; done) test_bin
+test: build_tests
+ @$(SHELL) make.sh run_test $(TEST_SRC)
+
.test: Makefile
- @echo "Setup tests"
- @$(SHELL) make.sh config_test $(TEST_SRC) > .test
+ @$(SHELL) make.sh config_test $(TEST_SRC) > $@
clean_test:
@$(SHELL) make.sh clean_test $(TEST_SRC)
-$(TEST_OBJ): config.mk
- @echo "CC $@"
- @$(CC) $(CFLAGS) $(RSYS_INC) -c $(@:.o=.c) -o $@
+$(TEST_OBJ): config.mk polygon-local.pc
+ $(CC) $(CFLAGS) $(POLYGON_CFLAGS) $(RSYS_CFLAGS) -c $(@:.o=.c) -o $@
-test_polygon test_polygon1: libpolygon.so
- @echo "LD $@"
- @$(CC) $(CFLAGS) -o $@ src/$@.o -L$$(pwd) -lpolygon $(RSYS_LIB)
+test_polygon test_polygon1: polygon-local.pc
+ $(CC) -o $@ src/$@.o $(LDFLAGS) $(POLYGON_LIBS) $(RSYS_LIBS) -lm
diff --git a/config.mk b/config.mk
@@ -1,34 +1,62 @@
-VERSION = 0.1.4 # Library version
-
+VERSION = 0.1.4
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
################################################################################
+PCFLAGS_STATIC = --static
+PCFLAGS = $(PCFLAGS_$(LIB_TYPE))
+
RSYS_VERSION = 0.6
-RSYS_INC = $$($(PKG_CONFIG) --cflags rsys)
-RSYS_LIB = $$($(PKG_CONFIG) --libs rsys)
+RSYS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys)
+RSYS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys)
-INCS = $(RSYS_INC)
-LIBS = $(RSYS_LIB)
+DPDC_CFLAGS = $(RSYS_CFLAGS)
+DPDC_LIBS = $(RSYS_LIBS) -lm
################################################################################
# Compilation options
################################################################################
-CC = cc # Compiler
-
-CPPFLAGS = -DNDEBUG
WFLAGS =\
-Wall\
+ -Wcast-align\
-Wconversion\
-Wextra\
-Wmissing-declarations\
-Wmissing-prototypes\
-Wshadow
-CFLAGS = -O2 -std=c89 -pedantic -fPIC -fvisibility=hidden -fstrict-aliasing\
- -Wl,--no-undefined $(WFLAGS) $(CPPFLAGS) # Compiler options
-LDFLAGS = -shared # Linker 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_DEBUG =
+LDFLAGS_RELEASE = -s
+LDFLAGS = $(LDFLAGS_$(BUILD_TYPE))
diff --git a/make.sh b/make.sh
@@ -18,40 +18,51 @@
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"
+ printf "%s: src/%s.o\n" "${test}" "${test}"
done
printf "test_bin: %s\n" "${test_list}"
}
run_test()
{
- n=0
-
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
printf "\e[1;32mOK\e[m\n"
else
- printf "\e[1;31mErreur\e[m\n"
+ printf "\e[1;31mError\e[m\n"
n=$((n+1))
fi
- done
-
- if [ "${n}" -ne 0 ]; then
- printf "%d errors\n" "${n}"
- exit 1
- fi
+ 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
}