loader_aw

Load OBJ/MTL file formats
git clone git://git.meso-star.fr/loader_aw.git
Log | Files | Refs | README | LICENSE

commit f66cc60d95f1c5e03393c90d1f95539d5302ff3c
parent 2f7f7b212b870fae8d126666752e38797cea7e98
Author: vaplv <vaplv@free.fr>
Date:   Tue, 27 Jun 2023 14:59:08 +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.

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 | 1+
MMakefile | 115+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mconfig.mk | 63+++++++++++++++++++++++++++++++++++++++++++++++++++------------
Mmake.sh | 45+++++++++++++++++++++++++--------------------
4 files changed, 145 insertions(+), 79 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -10,4 +10,5 @@ test* .config tags aw.pc +aw-local.pc *.mtl diff --git a/Makefile b/Makefile @@ -18,27 +18,37 @@ include config.mk +LIBNAME_STATIC = libaw.a +LIBNAME_SHARED = libaw.so +LIBNAME = $(LIBNAME_$(LIB_TYPE)) + ################################################################################ # RSys building ################################################################################ SRC = src/aw.c src/aw_obj.c src/aw_mtl.c - OBJ = $(SRC:.c=.o) DEP = $(SRC:.c=.d) -build_library: $(DEP) .config - @$(MAKE) -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) libaw.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) $(OBJ): config.mk -libaw.so: $(OBJ) - @echo "LD $@" - @$(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) +$(LIBNAME_SHARED): $(OBJ) + $(CC) $(CFLAGS) $(RSYS_CFLAGS) -o $@ $(OBJ) $(LDFLAGS) $(SOFLAGS) $(RSYS_LIBS) + +$(LIBNAME_STATIC): $(OBJ) + $(AR) -rc $@ $? + $(RANLIB) $@ .config: Makefile config.mk - @echo "Setup .config" @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 @@ -46,34 +56,57 @@ libaw.so: $(OBJ) @$(CC) $(CFLAGS) -MM -MT "$(@:.d=.o) $@" $< -MF $@ .c.o: - @echo "CC $@" - @$(CC) $(CFLAGS) -DAW_SHARED_BUILD -c $< -o $@ + $(CC) $(CFLAGS) $(RSYS_CFLAGS) -DAW_SHARED_BUILD -c $< -o $@ ################################################################################ # Installation ################################################################################ pkg: - sed -e 's#@PREFIX@#$(PREFIX)#g' \ - -e 's#@VERSION@#$(VERSION)#g' \ - -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g' \ - aw.pc.in > aw.pc + @echo "Setup aw.pc" + @sed -e 's#@PREFIX@#$(PREFIX)#g' \ + -e 's#@VERSION@#$(VERSION)#g' \ + -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g' \ + aw.pc.in > aw.pc + +aw-local.pc: aw.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' \ + aw.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/aw - cp libaw.so $(DESTDIR)$(PREFIX)/lib - cp aw.pc $(DESTDIR)$(PREFIX)/lib/pkgconfig - cp COPYING README.md $(DESTDIR)$(PREFIX)/share/doc/aw - cp src/aw.h $(DESTDIR)$(PREFIX)/include + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib" $(LIBNAME) + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib/pkgconfig" aw.pc + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/include" src/aw.h + @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/doc/aw"\ + COPYING README.md uninstall: - rm -f $(DESTDIR)$(PREFIX)/lib/libaw.so - rm -f $(DESTDIR)$(PREFIX)/lib/pkgconfig/aw.pc - rm -f $(DESTDIR)$(PREFIX)/share/doc/aw/COPYING - rm -f $(DESTDIR)$(PREFIX)/share/doc/aw/README.md - rm -f $(DESTDIR)$(PREFIX)/include/aw.h + rm -f "$(DESTDIR)$(PREFIX)/lib/$(LIBNAME)" + rm -f "$(DESTDIR)$(PREFIX)/lib/pkgconfig/aw.pc" + rm -f "$(DESTDIR)$(PREFIX)/include/aw.h" + rm -f "$(DESTDIR)$(PREFIX)/share/doc/aw/COPYING" + rm -f "$(DESTDIR)$(PREFIX)/share/doc/aw/README.md" + +################################################################################ +# Miscellaneous targets +################################################################################ +all: build_library build_tests + +clean: clean_test + rm -f $(OBJ) $(TEST_OBJ) libaw.so .test aw.pc .config + +distclean: clean + rm -f $(DEP) $(TEST_DEP) + +lint: + shellcheck -o all make.sh ################################################################################ # Tests @@ -82,43 +115,31 @@ TEST_SRC =\ src/test_aw.c\ src/test_aw_mtl.c\ src/test_aw_obj.c - TEST_OBJ = $(TEST_SRC:.c=.o) TEST_DEP = $(TEST_SRC:.c=.d) +AW_CFLAGS = $$(PKG_CONFIG_PATH=./:$${PKG_CONFIG_PATH} $(PKG_CONFIG) --cflags aw-local.pc) +AW_LIBS = $$(PKG_CONFIG_PATH=./:$${PKG_CONFIG_PATH} $(PKG_CONFIG) --libs aw-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 - @$(MAKE) -fMakefile -f.test $$(for i in $(TEST_DEP); do echo -f"$${i}"; done) test_run - -.test: Makefile - @echo "Setup tests" - @$(SHELL) make.sh config_test $(TEST_SRC) > .test - -test_run: test_bin @$(SHELL) make.sh run_test src/test_aw_mtl.c src/test_aw_obj.c -$(TEST_OBJ): config.mk - @echo "CC $@" - @$(CC) $(CFLAGS) -c $(@:.o=.c) -o $@ - -test_aw test_aw_mtl test_aw_obj: libaw.so - @echo "LD $@" - @$(CC) $(CFLAGS) -o $@ -L$$(pwd) src/$@.o $$($(PKG_CONFIG) --libs rsys) -law -lrsys +.test: Makefile + @$(SHELL) make.sh config_test $(TEST_SRC) > $@ clean_test: @rm -f test_cbox.obj test_obj_cube.obj test_obj_plane.obj test_obj_squares.obj @rm -f mtl0.mtl test_mtl_common.mtl test_mtl_multi.mtl @$(SHELL) make.sh clean_test $(TEST_SRC) -################################################################################ -# Miscellaneous targets -################################################################################ -all: build_library build_tests +$(TEST_OBJ): config.mk aw-local.pc + $(CC) $(CFLAGS) $(AW_CFLAGS) -c $(@:.o=.c) -o $@ -clean: clean_test - @rm -f $(OBJ) $(TEST_OBJ) libaw.so .test aw.pc .config - -distclean: clean - @rm -f $(DEP) $(TEST_DEP) +test_aw \ +test_aw_mtl \ +test_aw_obj \ +: aw-local.pc + $(CC) -o $@ src/$@.o $(LDFLAGS) $(AW_LIBS) diff --git a/config.mk b/config.mk @@ -1,20 +1,59 @@ VERSION = 2.1.0 - PREFIX = /usr/local -CPPFLAGS = -DNDEBUG -WFLAGS = -Wall -Wextra -Wmissing-declarations -Wmissing-prototypes -Wconversion -Wshadow +LIB_TYPE = SHARED +#LIB_TYPE = STATIC + +BUILD_TYPE = RELEASE +#BUILD_TYPE = DEBUG -PKG_CONFIG=pkg-config +################################################################################ +# Tools +################################################################################ +AR = ar +CC = cc +PKG_CONFIG = pkg-config +RANLIB = ranlib -INCS=$$($(PKG_CONFIG) --cflags rsys) -LIBS=$$($(PKG_CONFIG) --libs rsys) +################################################################################ +# Dependencies +################################################################################ +PCFLAGS_STATIC = --static +PCFLAGS = $(PCFLAGS_$(LIB_TYPE)) -CFLAGS = -O2 -std=c89 -pedantic -fPIC -fvisibility=hidden -fstrict-aliasing\ - -Wl,--no-undefined $(WFLAGS) $(CPPFLAGS) $(INCS) -LDFLAGS = -shared $(LIBS) +RSYS_VERSION = 0.9 +RSYS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys) +RSYS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys) -CC = cc +################################################################################ +# Compilation options +################################################################################ +WFLAGS =\ + -Wall\ + -Wcast-align\ + -Wconversion\ + -Wextra\ + -Wmissing-declarations\ + -Wmissing-prototypes\ + -Wshadow + +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 -# Dependency version -RSYS_VERSION=0.9 +LDFLAGS_DEBUG = +LDFLAGS_RELEASE = -s +LDFLAGS = $(LDFLAGS_$(BUILD_TYPE)) diff --git a/make.sh b/make.sh @@ -17,46 +17,51 @@ config_test() { - if [ $# -lt 1 ]; then - echo "usage: config_test [src ...]" >&2 - exit 1 - fi - 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" - n=$((n+1)) + printf "\e[1;31mError\e[m\n" 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 }