commit aa2203f3538761d72a97147434a6f4b3a53bc8fc
parent a1e8e755e5ce53ad59b2885f704f89b2a6739d2d
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 3 May 2024 18:38:32 +0200
Write a POSIX Makefile to replace CMake
The build procedure is written in POSIX make, which the user can
configure via the config.mk file. The make.sh script contains commands
that could be found directly in POSIX make, but which are placed here to
simplify writing the Makefile. Finally, a pkg-config file is provided to
link the library as an external dependency.
In addition to the features already provided in its CMake alternative,
this Makefile supports the use of static libraries and provides an
uninstall target. It also enable compiler and linker options that
activate various hardening features aimed at increasing the security and
robustness of generated binaries. In any case, the main motivation
behind its writing is to use a good old well-established standard with
simple features, available on all UNIX systems, thus simplifying its
portability and support while being much lighter.
Diffstat:
| M | .gitignore | | | 14 | +++++++------- |
| A | Makefile | | | 164 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | cmake/CMakeLists.txt | | | 118 | ------------------------------------------------------------------------------- |
| A | config.mk | | | 92 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | make.sh | | | 70 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | scad.pc.in | | | 12 | ++++++++++++ |
6 files changed, 345 insertions(+), 125 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,12 +1,12 @@
.gitignore
-CMakeCache.txt
-CMakeFiles
-Makefile
-tmp
[Bb]uild*
*.sw[po]
-*.[ao]
-*.orig
+*.[aod]
+*.so
*~
+test*
+!test*.[ch]
+.config
+.test
tags
-test
+*.pc
diff --git a/Makefile b/Makefile
@@ -0,0 +1,164 @@
+# Copyright (C) 2022 |Méso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+.POSIX:
+.SUFFIXES: # Clean up default inference rules
+
+include config.mk
+
+LIBNAME_STATIC = libscad.a
+LIBNAME_SHARED = libscad.so
+LIBNAME = $(LIBNAME_$(LIB_TYPE))
+
+################################################################################
+# Library building
+################################################################################
+SRC =\
+ src/scad.c\
+ src/scad_device.c\
+ src/scad_geometry.c
+OBJ = $(SRC:.c=.o)
+DEP = $(SRC:.c=.d)
+
+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
+
+$(LIBNAME_SHARED): $(OBJ)
+ $(CC) $(CFLAGS_SO) $(DPDC_CFLAGS) -o $@ $(OBJ) $(LDFLAGS_SO) $(DPDC_LIBS)
+
+$(LIBNAME_STATIC): libscad.o
+ $(AR) -rc $@ $?
+ $(RANLIB) $@
+
+libscad.o: $(OBJ)
+ $(LD) -r $(OBJ) -o $@
+ $(OBJCOPY) $(OCPFLAGS) $@
+
+.config: config.mk
+ @if ! $(PKG_CONFIG) --atleast-version $(GMSH_VERSION) gmsh; then \
+ echo "gmsh $(GMSH_VERSION) not found" >&2; exit 1; fi
+ @if ! $(PKG_CONFIG) --atleast-version $(RSYS_VERSION) rsys; then \
+ echo "rsys $(RSYS_VERSION) not found" >&2; exit 1; fi
+ @if ! $(PKG_CONFIG) --atleast-version $(SENC3D_VERSION) senc3d; then \
+ echo "senc3d $(SENC3D_VERSION) not found" >&2; exit 1; fi
+ @if ! $(PKG_CONFIG) --atleast-version $(SG3D_VERSION) sg3d; then \
+ echo "sg3d $(SG3D_VERSION) not found" >&2; exit 1; fi
+ @echo "config done" > $@
+
+.SUFFIXES: .c .d .o
+.c.d:
+ @$(CC) $(CFLAGS_SO) $(DPDC_CFLAGS) -MM -MT "$(@:.d=.o) $@" $< -MF $@
+
+.c.o:
+ $(CC) $(CFLAGS_SO) $(DPDC_CFLAGS) -DSCAD_SHARED_BUILD -c $< -o $@
+
+################################################################################
+# Installation
+################################################################################
+pkg:
+ sed -e 's#@PREFIX@#$(PREFIX)#g'\
+ -e 's#@VERSION@#$(VERSION)#g'\
+ -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g'\
+ -e 's#@SENC3D_VERSION@#$(SENC3D_VERSION)#g'\
+ -e 's#@SG3D_VERSION@#$(SG3D_VERSION)#g'\
+ scad.pc.in > scad.pc
+
+scad-local.pc: scad.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'\
+ -e 's#@SENC3D_VERSION@#$(SENC3D_VERSION)#g'\
+ -e 's#@SG3D_VERSION@#$(SG3D_VERSION)#g'\
+ scad.pc.in > $@
+
+install: build_library pkg
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib" $(LIBNAME)
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/lib/pkgconfig" scad.pc
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/include/star" src/scad.h
+ @$(SHELL) make.sh install "$(DESTDIR)$(PREFIX)/share/doc/star-cad" COPYING README.md
+
+uninstall:
+ rm -f "$(DESTDIR)$(PREFIX)/lib/$(LIBNAME)"
+ rm -f "$(DESTDIR)$(PREFIX)/lib/pkgconfig/scad.pc"
+ rm -f "$(DESTDIR)$(PREFIX)/include/star/scad.h"
+ rm -f "$(DESTDIR)$(PREFIX)/share/doc/star-cad/COPYING"
+ rm -f "$(DESTDIR)$(PREFIX)/share/doc/star-cad/README.md"
+
+################################################################################
+# Miscellaneous targets
+################################################################################
+all: build_library build_tests
+
+clean: clean_test
+ rm -f $(OBJ) $(TEST_OBJ) $(LIBNAME)
+ rm -f .config .test libscad.o scad.pc scad-local.pc
+
+distclean: clean
+ rm -f $(DEP) $(TEST_DEP)
+
+lint:
+ shellcheck -o all make.sh
+
+################################################################################
+# Tests
+################################################################################
+TEST_SRC =\
+ src/test_api.c\
+ src/test_export.c\
+ src/test_lifetime.c\
+ src/test_partition.c
+TEST_OBJ = $(TEST_SRC:.c=.o)
+TEST_DEP = $(TEST_SRC:.c=.d)
+
+PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./:$${PKG_CONFIG_PATH}" $(PKG_CONFIG)
+SCAD_CFLAGS = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags scad-local.pc)
+SCAD_LIBS = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs scad-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
+ @$(SHELL) make.sh config_test $(TEST_SRC) > $@
+
+clean_test:
+ $(SHELL) make.sh clean_test $(TEST_SRC)
+
+$(TEST_DEP): config.mk scad-local.pc
+ @$(CC) $(CFLAGS_EXE) $(RSYS_CFLAGS) $(SCAD_CFLAGS) \
+ -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@
+
+$(TEST_OBJ): config.mk scad-local.pc
+ $(CC) $(CFLAGS_EXE) $(RSYS_CFLAGS) $(SCAD_CFLAGS) -c $(@:.o=.c) -o $@
+
+test_api \
+test_export \
+test_lifetime \
+test_partition \
+: config.mk scad-local.pc $(LIBNAME)
+ $(CC) $(CFLAGS_EXE) -o $@ src/$@.o $(LDFLAGS_EXE) $(SCAD_LIBS) $(RSYS_LIBS) -lm
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -1,118 +0,0 @@
-# Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-cmake_minimum_required(VERSION 3.1)
-project(star-cad C)
-enable_testing()
-
-set(SCAD_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
-option(NO_TEST "Disable the test" OFF)
-
-################################################################################
-# Check dependencies
-################################################################################
-find_package(gmsh 4.12.2 REQUIRED)
-find_package(RCMake 0.4.1 REQUIRED)
-find_package(RSys 0.12.1 REQUIRED)
-find_package(StarGeom3D 0.1.3 REQUIRED)
-find_package(StarEnc3D 0.6 REQUIRED)
-
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
-include(rcmake)
-include(rcmake_runtime)
-
-include_directories(
- ${GMSH_INCLUDE_DIR}
- ${RSys_INCLUDE_DIR}
- ${StarGeom3D_INCLUDE_DIR}
- ${StarEnc3D_INCLUDE_DIR})
-
-################################################################################
-# Configure and define targets
-################################################################################
-set(VERSION_MAJOR 0)
-set(VERSION_MINOR 4)
-set(VERSION_PATCH 1)
-set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-
-set(SCAD_FILES_SRC
- scad.c
- scad_device.c
- scad_geometry.c)
-set(SCAD_FILES_INC_API scad.h)
-set(SCAD_FILES_INC
- scad_device.h
- scad_geometry.h)
-set(SCAD_FILES_DOC COPYING README.md)
-
-# Prepend each file in the `SCAD_FILES_<SRC|INC>' list by `SCAD_SOURCE_DIR'
-rcmake_prepend_path(SCAD_FILES_SRC ${SCAD_SOURCE_DIR})
-rcmake_prepend_path(SCAD_FILES_INC ${SCAD_SOURCE_DIR})
-rcmake_prepend_path(SCAD_FILES_INC_API ${SCAD_SOURCE_DIR})
-rcmake_prepend_path(SCAD_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
-
-add_library(scad SHARED ${SCAD_FILES_SRC} ${SCAD_FILES_INC} ${SCAD_FILES_INC_API})
-target_link_libraries(scad RSys gmsh StarGeom3D StarEnc3D m)
-
-set_target_properties(scad PROPERTIES
- DEFINE_SYMBOL SCAD_SHARED_BUILD
- VERSION ${VERSION}
- SOVERSION ${VERSION_MAJOR})
-
-rcmake_setup_devel(scad StarCAD ${VERSION} star/scad_version.h)
-
-################################################################################
-# Add tests
-################################################################################
-if(NOT NO_TEST)
- function(build_test _name)
- add_executable(${_name}
- ${SCAD_SOURCE_DIR}/${_name}.c
- ${SCAD_SOURCE_DIR}/test_common.h)
- target_link_libraries(${_name} scad RSys)
- set(_libraries ${ARGN})
- foreach(_lib ${_libraries})
- target_link_libraries(${_name} ${_lib})
- endforeach()
- endfunction()
-
- function(register_test _name)
- add_test(${_name} ${ARGN})
- endfunction()
-
- function(new_test _name)
- build_test(${_name} ${ARGN})
- register_test(${_name} ${_name})
- endfunction()
-
- new_test(test_api)
- new_test(test_export)
- new_test(test_partition)
- new_test(test_lifetime)
-
- rcmake_copy_runtime_libraries(test)
-
-endif(NOT NO_TEST)
-
-################################################################################
-# Define output & install directories
-################################################################################
-install(TARGETS scad
- ARCHIVE DESTINATION bin
- LIBRARY DESTINATION lib
- RUNTIME DESTINATION bin)
-install(FILES ${SCAD_FILES_INC_API} DESTINATION include/star)
-install(FILES ${SCAD_FILES_DOC} DESTINATION share/doc/star-cad)
-
diff --git a/config.mk b/config.mk
@@ -0,0 +1,92 @@
+VERSION = 0.5.0
+PREFIX = /usr/local
+
+LIB_TYPE = SHARED
+#LIB_TYPE = STATIC
+
+BUILD_TYPE = RELEASE
+#BUILD_TYPE = DEBUG
+
+################################################################################
+# Tools
+################################################################################
+AR = ar
+CC = cc
+LD = ld
+OBJCOPY = objcopy
+PKG_CONFIG = pkg-config
+RANLIB = ranlib
+
+################################################################################
+# Dependencies
+################################################################################
+PCFLAGS_STATIC = --static
+PCFLAGS = $(PCFLAGS_$(LIB_TYPE))
+
+GMSH_VERSION = 4.12.2
+GMSH_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags gmsh)
+GMSH_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs gmsh)
+
+RSYS_VERSION = 0.14
+RSYS_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags rsys)
+RSYS_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs rsys)
+
+SENC3D_VERSION = 0.7
+SENC3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags senc3d)
+SENC3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs senc3d)
+
+SG3D_VERSION = 0.2
+SG3D_CFLAGS = $$($(PKG_CONFIG) $(PCFLAGS) --cflags sg3d)
+SG3D_LIBS = $$($(PKG_CONFIG) $(PCFLAGS) --libs sg3d)
+
+DPDC_CFLAGS = $(GMSH_CFLAGS) $(RSYS_CFLAGS) $(SENC3D_CFLAGS) $(SG3D_CFLAGS)
+DPDC_LIBS = $(GMSH_LIBS) $(RSYS_LIBS) $(SENC3D_LIBS) $(SG3D_LIBS) -lm
+
+################################################################################
+# Compilation options
+################################################################################
+WFLAGS =\
+ -Wall\
+ -Wcast-align\
+ -Wconversion\
+ -Wextra\
+ -Wmissing-declarations\
+ -Wmissing-prototypes\
+ -Wshadow
+
+CFLAGS_HARDENED =\
+ -D_FORTIFY_SOURCES=2\
+ -fcf-protection=full\
+ -fstack-clash-protection\
+ -fstack-protector-strong
+
+CFLAGS_COMMON =\
+ -std=c89\
+ -pedantic\
+ -fPIC\
+ -fvisibility=hidden\
+ -fstrict-aliasing\
+ $(CFLAGS_HARDENED)\
+ $(WFLAGS)
+
+CFLAGS_DEBUG = -g $(CFLAGS_COMMON)
+CFLAGS_RELEASE = -O2 -DNDEBUG $(CFLAGS_COMMON)
+CFLAGS = $(CFLAGS_$(BUILD_TYPE))
+
+CFLAGS_SO = $(CFLAGS) -fPIC
+CFLAGS_EXE = $(CFLAGS) -fPIE
+
+################################################################################
+# Linker options
+################################################################################
+LDFLAGS_HARDENED = -Wl,-z,relro,-z,now
+LDFLAGS_DEBUG = $(LDFLAGS_HARDENED)
+LDFLAGS_RELEASE = -s $(LDFLAGS_HARDENED)
+LDFLAGS = $(LDFLAGS_$(BUILD_TYPE))
+
+LDFLAGS_SO = $(LDFLAGS) -shared -Wl,--no-undefined
+LDFLAGS_EXE = $(LDFLAGS) -pie
+
+OCPFLAGS_DEBUG = --localize-hidden
+OCPFLAGS_RELEASE = --localize-hidden --strip-unneeded
+OCPFLAGS = $(OCPFLAGS_$(BUILD_TYPE))
diff --git a/make.sh b/make.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+# Copyright (C) 2022 |Méso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+set -e
+
+config_test()
+{
+ for i in "$@"; do
+ test=$(basename "${i}" ".c")
+ test_list="${test_list} ${test}"
+ printf "%s: %s\n" "${test}" "src/${test}.o"
+ done
+ printf "test_bin: %s\n" "${test_list}"
+}
+
+run_test()
+{
+ for i in "$@"; do
+ test=$(basename "${i}" ".c")
+
+ printf "%s " "${test}"
+ if "./${test}" > /dev/null 2>&1; then
+ printf "\033[1;32mOK\033[m\n"
+ else
+ printf "\033[1;31mError\033[m\n"
+ fi
+ done 2> /dev/null
+}
+
+clean_test()
+{
+ for i in "$@"; do
+ 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
+}
+
+"$@"
diff --git a/scad.pc.in b/scad.pc.in
@@ -0,0 +1,12 @@
+prefix=@PREFIX@
+includedir=${prefix}/include
+libdir=${prefix}/lib
+
+Requires: rsys >= @RSYS_VERSION@
+Requires.private: senc3d >= @SENC3D_VERSION@, sg3d >= @SG3D_VERSION@
+Name: Star-CAD
+Description: Star CAD
+Version: @VERSION@
+Libs: -L${libdir} -lscad
+Libs.private: -lm
+CFlags: -I${includedir}