commit 829bddd3166109fff8f122fd174f9b76846f53f5
parent 2d151ca93128a8e01479e1bcec350b73f07aafd4
Author: vaplv <vaplv@free.fr>
Date: Fri, 17 Mar 2023 11:57:40 +0100
Write a POSIX Makefile as an alternative to CMake
Diffstat:
| M | .gitignore | | | 13 | ++++++++----- |
| A | Makefile | | | 177 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | config.mk | | | 36 | ++++++++++++++++++++++++++++++++++++ |
| A | make.sh | | | 182 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | rsimd.pc.in | | | 12 | ++++++++++++ |
5 files changed, 415 insertions(+), 5 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,10 +1,13 @@
.gitignore
-CMakeCache.txt
-CMakeFiles
-Makefile
-tmp
[Bb]uild*
*.sw[po]
-*.[ao]
+*.[aod]
+*.so
*~
tags
+test*
+!test*.[ch]
+.test
+.simd
+.pkg
+rsimd.pc
diff --git a/Makefile b/Makefile
@@ -0,0 +1,177 @@
+# Copyright (C) 2014-2019, 2021, 2023 Vincent Forest (vaplv@free.fr)
+#
+# This CMake script 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 CMake script 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 CMake script. If not, see <http://www.gnu.org/licenses/>.
+
+.POSIX:
+.SUFFIXES: # Clean up default inference rules
+
+include config.mk
+
+################################################################################
+# RSys building
+################################################################################
+SRC = $(SRC_SIMD)\
+ src/aosf44.c\
+ src/aosq.c\
+ src/math4.c
+
+OBJ = $(SRC:.c=.o)
+DEP = $(SRC:.c=.d)
+
+build_library: .simd .pkg $(DEP)
+ @$(MAKE) -f.simd -fMakefile $$(for i in $(DEP); do echo -f $${i}; done) librsimd.so
+
+$(OBJ): config.mk
+
+librsimd.so: $(OBJ)
+ @echo "LD $@"
+ @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
+
+.simd: make.sh config.mk
+ @$(SHELL) make.sh config_simd > $@
+
+.pkg: make.sh config.mk
+ @$(SHELL) make.sh config_pkg && echo "pkg done" > $@ || exit 1
+
+.SUFFIXES: .c .d .o
+.c.d:
+ @$(CC) $(CFLAGS) $(INCS) -MM -MT "$(@:.d=.o) $@" $< -MF $@
+
+.c.o:
+ @echo "CC $@"
+ @$(CC) $(CFLAGS) $(INCS) -DRSIMD_SHARED_BUILD -c $< -o $@
+
+################################################################################
+# Miscellaneous targets
+################################################################################
+all: build_library build_tests
+
+clean: .simd
+ @$(MAKE) -f.simd -fMakefile clean__
+
+clean__: clean_test
+ @rm -f $(OBJ) $(TEST_OBJ) librsimd.so rsimd.pc .pkg .simd
+
+distclean: clean
+ @rm -f $(DEP) $(TEST_DEP) .test
+
+################################################################################
+# Installation
+################################################################################
+API_REGULAR=\
+ src/aosf33.h\
+ src/aosf44.h\
+ src/aosq.h\
+ src/math.h\
+ src/mathX.h\
+ src/math4.h\
+ src/math8.h\
+ src/rsimd.h\
+ src/soaXfY.h\
+ src/soaXfY_begin.h\
+ src/soaXfY_end.h\
+ src/soaXf2.h\
+ src/soaXf3.h\
+ src/soa4f2.h\
+ src/soa4f3.h\
+ src/soa4f4.h\
+ src/soa8f2.h\
+ src/soa8f3.h\
+ src/soa8f4.h\
+ src/vXf_begin.h\
+ src/vXf_end.h
+API_AVX=\
+ src/avx/avx.h\
+ src/avx/avxf.h\
+ src/avx/avxi.h
+API_SSE=\
+ src/sse/sse.h\
+ src/sse/ssef.h\
+ src/sse/ssei.h\
+ src/sse/sse_swz.h
+
+pkg: .simd
+ @$(MAKE) -f.simd -fMakefile pkg__
+
+pkg__:
+ @echo "Setup rsimd.pc"
+ @sed -e 's#@PREFIX@#$(PREFIX)#g' \
+ -e 's#@VERSION@#$(VERSION)#g' \
+ -e 's#@SLEEF_VERSION@#$(SLEEF_VERSION)#g' \
+ -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g' \
+ -e 's#@CFLAGS_SIMD@#$(CFLAGS_SIMD)#g' \
+ rsimd.pc.in > rsimd.pc
+
+install: build_library pkg
+ mkdir -p $(DESTDIR)$(PREFIX)/lib
+ mkdir -p $(DESTDIR)$(PREFIX)/lib/pkgconfig
+ mkdir -p $(DESTDIR)$(PREFIX)/include/rsimd/avx
+ mkdir -p $(DESTDIR)$(PREFIX)/include/rsimd/sse
+ mkdir -p $(DESTDIR)$(PREFIX)/share/doc/rsimd
+ cp librsimd.so $(DESTDIR)$(PREFIX)/lib
+ cp rsimd.pc $(DESTDIR)$(PREFIX)/lib/pkgconfig
+ cp COPYING README.md $(DESTDIR)$(PREFIX)/share/doc/rsimd
+ cp $(API_REGULAR) $(DESTDIR)$(PREFIX)/include/rsimd
+ cp $(API_AVX) $(DESTDIR)$(PREFIX)/include/rsimd/avx
+ cp $(API_SSE) $(DESTDIR)$(PREFIX)/include/rsimd/sse
+
+uninstall:
+ rm -f $(DESTDIR)$(PREFIX)/lib/librsimd.so
+ rm -f $(DESTDIR)$(PREFIX)/lib/pkgconfig/rsimd.pc
+ rm -f $(DESTDIR)$(PREFIX)/share/doc/rsimd/COPYING
+ rm -f $(DESTDIR)$(PREFIX)/share/doc/rsimd/README.md
+ rm -f $$(echo $(API_REGULAR) | sed 's,src\/,$(DESTDIR)$(PREFIX)\/include\/rsimd\/,g')
+ rm -f $$(echo $(API_AVX) | sed 's,src\/,$(DESTDIR)$(PREFIX)\/include\/rsimd\/,g')
+ rm -f $$(echo $(API_SSE) | sed 's,src\/,$(DESTDIR)$(PREFIX)\/include\/rsimd\/,g')
+
+################################################################################
+# Tests
+################################################################################
+TEST_SSE2 =\
+ test_aosf33\
+ test_aosf44\
+ test_aosq\
+ test_math4\
+ test_soa4f2\
+ test_soa4f3\
+ test_soa4f4\
+ test_v4f\
+ test_v4i
+TEST_AVX =\
+ test_math8\
+ test_soa8f2\
+ test_soa8f3\
+ test_soa8f4
+TEST_SSE4_1 =\
+ test_v4f_sse4_1\
+ test_v4i_sse4_1
+TEST_FMA =\
+ test_v4f_fma\
+ test_soa8f2_fma\
+ test_soa8f3_fma\
+ test_soa8f4_fma
+
+TEST = $(TEST_SSE2) $(TEST_AVX) $(TEST_SSE4_1) $(TEST_FMA)
+
+test: build_tests
+ @$(SHELL) make.sh run_test $(TEST)
+
+build_tests: build_library .test
+ @$(MAKE) -fMakefile -f.test test_bin
+
+.test: make.sh config.mk
+ @$(SHELL) make.sh config_test $(TEST) > $@
+
+clean_test:
+ @$(SHELL) make.sh clean_test $(TEST)
diff --git a/config.mk b/config.mk
@@ -0,0 +1,36 @@
+VERSION = 0.3.0 # Library version
+
+PREFIX = /usr/local
+PKG_CONFIG = pkg-config
+
+################################################################################
+# Dependencies
+################################################################################
+RSYS_VERSION = 0.12
+RSYS_INC = $$($(PKG_CONFIG) --cflags rsys)
+RSYS_LIB = $$($(PKG_CONFIG) --libs rsys)
+
+SLEEF_VERSION = 3.6
+SLEEF_INC = $$($(PKG_CONFIG) --cflags sleef)
+SLEEF_LIB = $$($(PKG_CONFIG) --libs sleef)
+
+INCS = $(RSYS_INC) $(SLEEF_INC)
+LIBS = $(RSYS_LIB) $(SLEEF_LIB)
+
+################################################################################
+# Compilation options
+################################################################################
+CC = cc # Compiler
+
+CPPFLAGS = -DNDEBUG
+WFLAGS =\
+ -Wall\
+ -Wconversion\
+ -Wextra\
+ -Wmissing-declarations\
+ -Wmissing-prototypes\
+ -Wshadow
+
+CFLAGS = -O2 -std=c99 -pedantic -fPIC -fvisibility=hidden -fstrict-aliasing\
+ -Wl,--no-undefined $(WFLAGS) $(CPPFLAGS) $(CFLAGS_SIMD)# Compiler options
+LDFLAGS = -shared # Linker options
diff --git a/make.sh b/make.sh
@@ -0,0 +1,182 @@
+#!/bin/sh -e
+
+# Copyright (C) 2014-2019, 2021, 2023 Vincent Forest (vaplv@free.fr)
+#
+# This CMake script 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 CMake script 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 CMake script. If not, see <http://www.gnu.org/licenses/>.
+
+################################################################################
+# Helper functions
+################################################################################
+# Print the value of a variable in config.mk
+showvar()
+{
+ # To avoid messages from Make being displayed instead of the value of the
+ # queried variable, we redirect its output to /dev/null and open a new file
+ # descriptor to stdout to print the variable
+<< EOF make -f 3>&1 1>/dev/null 2>&1 - || kill -HUP $$
+.POSIX:
+include config.mk
+showvar:
+ @1>&3 echo \$(${1})
+EOF
+ exec 3<&- # Close file descriptor 3
+}
+
+check_cpuflag()
+{
+ sed -n "/^flags[[:blank:]]\{1,\}:/{p;q}" /proc/cpuinfo \
+| sed "s/.*[[:blank:]]\{1,\}\($1\)[[:blank:]]\{1,\}.*/\1/"
+}
+
+################################################################################
+# Main functions
+################################################################################
+run_test()
+{
+ n=0
+
+ for i in "$@"; do
+ printf "%s " "${i}"
+ if ./"${i}" > /dev/null 2>&1; then
+ printf "\e[1;32mOK\e[m\n"
+ else
+ printf "\e[1;31mErreur\e[m\n"
+ n=$((n+1))
+ fi
+ done
+
+ if [ "${n}" -ne 0 ]; then
+ printf "%d errors\n" "${n}"
+ exit 1
+ fi
+}
+
+clean_test()
+{
+ for i in "$@"; do
+ rm -f "${i}"
+ done
+}
+
+config_simd()
+{
+ cflags=""
+ src=""
+
+ sse2="$(check_cpuflag sse2)"
+ sse4_1="$(check_cpuflag sse4_1)"
+ avx="$(check_cpuflag avx)"
+ fma="$(check_cpuflag fma)"
+
+ if [ -z "${sse2}" ]; then
+ >&2 echo "The SSE2 instruction set must be supported."
+ exit 1
+ else
+ >&2 echo "Use the SSE2 instruction set"
+ cflags="${cflags} -msse2"
+ fi
+
+ if [ -n "${sse4_1}" ]; then
+ >&2 echo "Use the SSE4.1 instruction set"
+ cflags="${cflags} -msse4.1"
+ fi
+
+ if [ -n "${avx}" ]; then
+ >&2 echo "Use the AVX instruction set"
+ cflags="${cflags} -mavx"
+ src="${src} src/math8.c"
+ fi
+
+ if [ -n "${fma}" ]; then
+ >&2 echo "Use the FMA instruction set"
+ cflags="${cflags} -mfma"
+ fi
+
+ printf "CFLAGS_SIMD = %s\n" "${cflags}"
+ printf "SRC_SIMD = %s\n" "${src}"
+}
+
+config_test()
+{
+ sse4_1="$(check_cpuflag sse4_1)"
+ avx="$(check_cpuflag avx)"
+ fma="$(check_cpuflag fma)"
+
+ cc="$(showvar CC)"
+ cflags="$(showvar CFLAGS)"
+ incs="$(showvar INCS)"
+
+ for i in "$@"; do
+ cflags=""
+ case "${i}" in
+ *_sse4_1)
+ [ -z "${sse4_1}" ] && continue
+ prefix=$(echo "${i}" | sed 's/_sse4_1//')
+ cflags="-msse4.1"
+ ;;
+ *_fma)
+ [ -z "${fma}" ] && continue
+ prefix=$(echo "${i}" | sed 's/_fma//')
+ cflags="-mfma"
+ ;;
+ test_soa8* | test_math8)
+ [ -z "${avx}" ] && continue
+ prefix="${i}"
+ cflags="-mavx"
+ ;;
+ *)
+ prefix="${i}"
+ cflags="-msse2"
+ ;;
+ esac
+
+ printf "%s: librsimd.so\n" "${i}"
+
+ # shellcheck disable=SC2086
+ ${cc} ${cflags} ${incs} -MM -MT "${i}" "src/${prefix}.c" -MF -
+
+ printf "\t@echo \"CC \$@\"\n"
+ printf "\t@\$(CC) \$(CFLAGS) %s \$(RSYS_INC) -L\$\$(pwd) "\
+"-o \$@ src/%s.c -lrsimd -lm\n" "${cflags}" "${prefix}"
+
+ test_list="${test_list} ${i}"
+ done
+ printf "test_bin: %s\n" "${test_list}"
+}
+
+
+config_pkg()
+{
+ pkg_config=$(showvar PKG_CONFIG)
+
+ rsys_version=$(showvar RSYS_VERSION)
+ sleef_version=$(showvar SLEEF_VERSION)
+ dependencies="\
+ RSys rsys ${rsys_version}
+ Sleef sleef ${sleef_version}"
+
+ printf "%s\n" "${dependencies}" | while read -r i; do
+ name=$(printf "%s" "${i}" | cut -d' ' -f1)
+ pc=$(printf "%s" "${i}" | cut -d' ' -f2)
+ version=$(printf "%s" "${i}" | cut -d' ' -f3)
+
+ if ! "${pkg_config}" --atleast-version "${version}" "${pc}"; then
+ >&2 printf "\e[1;31merror\e[0m:%s %s: dependency is missing\n" \
+ "${name}" "${version}"
+ exit 1
+ fi
+ done || exit $?
+}
+
+"$@"
diff --git a/rsimd.pc.in b/rsimd.pc.in
@@ -0,0 +1,12 @@
+prefix=@PREFIX@
+includedir=${prefix}/include
+libdir=${prefix}/lib
+cflags_simd=@CFLAGS_SIMD@
+
+Requires: rsys >= @RSYS_VERSION@
+Requires.private: sleef >= @SLEEF_VERSION@
+Name: RSIMD
+Description: RSIMD library
+Version: @VERSION@
+Libs: -L${libdir} -lrsimd
+CFlags: -I${includedir} ${cflags_simd}