@ -3,12 +3,13 @@
PROJECT = memfd_secret-shim
AUTHOR = Avril ( Flanchan) <flanchan@cumallover.me>
DESCRIPTION =
VERSION = 0.0.0
VERSION = 0.0.0r1
SRC = src
SRC_C = $( shell find $( SRC) / -type f -name \* .c)
SRC_CXX = $( shell find -O2 $( SRC) / -type f -name \* .cpp -or -name \* .cxx)
# Exclude `src/test/*` from search.
SRC_C = $( shell find $( SRC) / -type f -name \* .c -a -not -path src/test/\* )
SRC_CXX = $( shell find -O2 $( SRC) / -type f -name \* .cpp -or -name \* .cxx -a -not -path src/test/\* )
INCLUDE = include
# If PCH should be auto-included for all TUs, set to 1.
@ -17,27 +18,54 @@ INCLUDE_PCH_GLOBAL?=0
INCLUDE_GLOBAL =
# Link to these libraries dynamicalls
SHARED_LIBS = fmt
SHARED_LIBS =
# Link to these libraries statically
STATIC_LIBS =
# Prefix for un/install targets
i f e q ( $( PREFIX ) , )
PREFIX := /usr/local
e n d i f
INCLUDE_PREFIX := $( PROJECT) /
# Default archivers
AR ?= ar
RANLIB ?= ranlib
# Use gcc-{ar,ranlib} when using gcc
i f e q ( $( CXX ) , g + + )
AR:= gcc-ar
RANLIB:= gcc-ranlib
e n d i f
# Pre-compile these headers
PCH_HEADERS +=
# PCH_HEADERS depend on these header files
PCH_INCLUDES +=
# Link executable statically (in release builds only.)
STATIC ?= no
# Compile-time default program features (see `Features application` below.)
FEATURES ?=
# Build constants
CONSTANTS += _GNU_SOURCE
# Testing
# Can be {release,debug}.{a,so}
TARGET ?= debug.a
TEST_LDFLAGS += -lfmt -lstdc++ -Wl,-z,now -Wl,-z -Wl,relro
TEST_CFLAGS += -Og -g -fwhole-program
o v e r r i d e __COMMA = ,
override __VERSION_SPLIT : = $( subst ., ,$ ( VERSION ) )
override __VERSION_REVISION : =$( word 3,$ ( __VERSION_SPLIT ) ) 0
VERSION_MAJOR := $( word 1,$( __VERSION_SPLIT) )
VERSION_MINOR := $( word 2,$( __VERSION_SPLIT) )
VERSION_BUGFIX := $( word 3,$( __VERSION_SPLIT) )
VERSION_REVISION := $( word 2,$( subst r, ,$( __VERSION_REVISION) ) )
override __VERSION_SPLIT : = MAJOR :$( word 1,$ ( __VERSION_SPLIT ) ) MINOR :$( word 2,$ ( __VERSION_SPLIT ) ) BUGFIX :$( word 1,$ ( subst r , ,$ ( __VERSION_REVISION ) ) ) REVISION :$( word 2,$ ( subst r , ,$ ( __VERSION_REVISION ) ) ) REVISION_STRING :$( word 3,$ ( __VERSION_SPLIT ) )
COMMON_FLAGS += -W -Wall
@ -51,14 +79,27 @@ COMMON_FLAGS+= $(addprefix -D_VERSION_,$(subst :,=,$(__VERSION_SPLIT))) '-D_VERS
ARCH ?= native
CPU ?= native
# Enable OpenMP and loop parallelisation? (dyn-links to openmp)
PARALLEL ?= yes
PARALLEL ?= no
# Enable CPU-specific features
CPU_FLAGS ?=
BINFLAGS +=
DEBUG_BINFLAGS +=
RELEASE_BINFLAGS += -fuse-linker-plugin
OPT_FLAGS ?= -fgraphite \
-floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block \
-fno-stack-check
# Static and shared common flags
SHARED_FLAGS += -fPIC
SHARED_RELEASE_FLAGS +=
SHARED_DEBUG_FLAGS +=
STATIC_FLAGS +=
STATIC_RELEASE_FLAGS += -ffat-lto-objects
STATIC_DEBUG_FLAGS +=
# Features application
## Tell program which features are enabled via `FEATURE_<feature name in UPPER_SNAKE_CASE>`.
@ -83,7 +124,8 @@ ifneq ($(CPU),)
e n d i f
i f e q ( $( PARALLEL ) , y e s )
OPT_FLAGS += -fopenmp -floop-parallelize-all -ftree-parallelize-loops= 4
SHARED_FLAGS += -fopenmp
SHARED_RELEASE_FLAGS += -floop-parallelize-all -ftree-parallelize-loops= 4
e n d i f
COMMON_FLAGS += $( addprefix -m,$( CPU_FLAGS) )
@ -103,7 +145,7 @@ DEBUG_COMMON_FLAGS+= -ggdb -gz -ftrapv -fbounds-check
i f n e q ( $( TARGET_SPEC_FLAGS ) , n o )
RELEASE_CFLAGS?= -O3 -flto $( OPT_FLAGS)
RELEASE_CXXFLAGS?= -O3 -flto $( CXX_OPT_FLAGS)
RELEASE_LDFLAGS?= -Wl,-O3 -Wl,-flto -fuse-linker-plugin
RELEASE_LDFLAGS?= -Wl,-O3 -Wl,-flto
DEBUG_CFLAGS?= -Og
DEBUG_CXXFLAGS?= -Og
@ -111,10 +153,6 @@ ifneq ($(TARGET_SPEC_FLAGS),no)
DEBUG_LDFLAGS?=
e n d i f
i f e q ( $( STATIC ) , y e s )
RELEASE_LDFLAGS += -static
e n d i f
DEBUG_CFLAGS += -DDEBUG $( DEBUG_COMMON_FLAGS)
DEBUG_CXXFLAGS += -DDEBUG $( DEBUG_COMMON_FLAGS) -fasynchronous-unwind-tables
@ -169,7 +207,7 @@ CFLAGS += $(COMMON_FLAGS) --std=$(CSTD)
CXXFLAGS += $( COMMON_FLAGS) --std= $( CXXSTD)
LDFLAGS += $( addsuffix .a,$( addprefix -l:lib,$( STATIC_LIBS) ) ) $( addprefix -l,$( SHARED_LIBS) )
# PGO
# PGO (unused for lib targets)
PROF_FLAGS = -D_PGO_GEN -fprofile-generate
PGO_OBJ_C = $( addprefix prof/c/,$( SRC_C:.c= .o) )
@ -184,14 +222,33 @@ PROF_SMALL_BOUND= 1024
# Phonies
# XXX: This doesn't force them to run in series for some reason?
.PHONY : release
release : | dirs $( PROJECT ) -release
release : | dirs
$( MAKE) lib$( PROJECT) .a
@$( MAKE) clean-rebuild >> /dev/null
@$( MAKE) dirs >> /dev/null
$( MAKE) lib$( PROJECT) .so
.PHONY : debug
debug : | dirs $( PROJECT ) -debug
.PHONY : pgo
pgo : | dirs $( PROJECT ) -pgo
debug : | dirs
$( MAKE) lib$( PROJECT) -debug.a
@$( MAKE) clean-rebuild >> /dev/null
@$( MAKE) dirs >> /dev/null
$( MAKE) lib$( PROJECT) -debug.so
# Rebuild both release and debug targets from scratch
.PHONY : all
all : | clean
@$( MAKE) release
@$( MAKE) clean-rebuild
@$( MAKE) debug
.PHONY : test
test : $( PROJECT ) -test
-strace ./$<
-valgrind ./$<
./$( PROJECT) -test
# Targets
@ -239,75 +296,43 @@ prof/cxx/%.o: %.cpp $(PCH_OUTPUT)
$( CXX) -c $< $( CXXFLAGS) -o $@ $( PROF_FLAGS)
#$(LDFLAGS)
$(PROJECT)-release : CFLAGS += $( RELEASE_CFLAGS ) $( PCH_USE_CFLAGS )
$(PROJECT)-release : CXXFLAGS += $( RELEASE_CXXFLAGS ) $( PCH_USE_CXXFLAGS )
$(PROJECT)-release : LDFLAGS += $( RELEASE_LDFLAGS )
$(PROJECT)-release : $( OBJ )
$( CXX) $^ $( CXXFLAGS) -o $@ $( LDFLAGS)
lib$(PROJECT)-release.a : CFLAGS += $( RELEASE_CFLAGS ) $( STATIC_FLAGS ) $( STATIC_RELEASE_FLAGS )
lib$(PROJECT)-release.a : CXXFLAGS += $( RELEASE_CXXFLAGS ) $( STATIC_FLAGS ) $( STATIC_RELEASE_FLAGS )
lib$(PROJECT)-release.a : LDFLAGS += $( RELEASE_LDFLAGS )
lib$(PROJECT)-release.a : $( OBJ )
$( AR) rcs $@ $^
$( RANLIB) $@
lib$(PROJECT)-debug.a : CFLAGS += $( DEBUG_CFLAGS ) $( STATIC_FLAGS ) $( STATIC_DEBUG_FLAGS )
lib$(PROJECT)-debug.a : CXXFLAGS += $( DEBUG_CXXFLAGS ) $( STATIC_FLAGS ) $( STATIC_DEBUG_FLAGS )
lib$(PROJECT)-debug.a : LDFLAGS += $( DEBUG_LDFLAGS )
lib$(PROJECT)-debug.a : $( OBJ )
$( AR) rcs $@ $^
$( RANLIB) $@
lib$(PROJECT)-release.so : CFLAGS += $( RELEASE_CFLAGS ) $( SHARED_FLAGS ) $( SHARED_RELEASE_FLAGS )
lib$(PROJECT)-release.so : CXXFLAGS += $( RELEASE_CXXFLAGS ) $( SHARED_FLAGS ) $( SHARED_RELEASE_FLAGS )
lib$(PROJECT)-release.so : LDFLAGS += $( RELEASE_LDFLAGS )
lib$(PROJECT)-release.so : BINFLAGS += $( RELEASE_BINFLAGS )
lib$(PROJECT)-release.so : $( OBJ )
$( CXX) -shared $^ $( BINFLAGS) $( CXXFLAGS) -o $@ $( LDFLAGS)
$( STRIP) $@
$(PROJECT)-debug : CFLAGS += $( DEBUG_CFLAGS ) $( PCH_USE_CFLAGS )
$(PROJECT)-debug : CXXFLAGS += $( DEBUG_CXXFLAGS ) $( PCH_USE_CXXFLAGS )
$(PROJECT)-debug : LDFLAGS += $( DEBUG_LDFLAGS )
$(PROJECT)-debug : $( OBJ )
$( CXX) $^ $( CXXFLAGS) -o $@ $( LDFLAGS)
pgo-reset :
find -O3 prof -type f -name \* .gcda -exec rm { } +
pgo-generate : CFLAGS += $( RELEASE_CFLAGS ) $( PCH_USE_CFLAGS )
pgo-generate : CXXFLAGS += $( RELEASE_CXXFLAGS ) $( PCH_USE_CXXFLAGS )
pgo-generate : LDFLAGS += $( RELEASE_LDFLAGS )
pgo-generate : $( PGO_OBJ )
$( CXX) $^ $( CXXFLAGS) $( PROF_FLAGS) -o $@ $( LDFLAGS) $( PROF_FLAGS)
pgo-profile : | pgo -generate pgo -reset
set -e errexit && shopt -s inherit_errexit && set -eo pipefail; \
rm -rf $( PROF_LOCATION) ; \
for i in { 0..$( PROF_ITERATIONS) } ; do \
>& 2 printf " >>> Iteration $$ i \b\b " ; \
mkdir -p $( PROF_LOCATION) /{ direct,indirect} ; \
for j in { 0..$( PROF_LARGE_BOUND) } ; do \
./pgo-generate; \
done > $( PROF_LOCATION) /full; \
for j in { 0..$( PROF_SMALL_BOUND) } ; do \
./pgo-generate > $( PROF_LOCATION) /direct/$$ j; \
done ; \
for j in { 0..$( PROF_SMALL_BOUND) } ; do \
./pgo-generate >> $( PROF_LOCATION) /indirect/$$ i; \
done ; \
for j in { 0..$( PROF_SMALL_BOUND) } ; do \
./pgo-generate > $( PROF_LOCATION) /direct/$$ i-$$ j & : ; \
done ; \
for j in { 0..$( PROF_SMALL_BOUND) } ; do \
./pgo-generate >> $( PROF_LOCATION) /indirect/$$ i-$$ j & : ; \
done ; \
for j in { 0..$( PROF_SMALL_BOUND) } ; do \
./pgo-generate >/dev/null & : ; \
done ; \
wait; \
rm -rf $( PROF_LOCATION) /{ direct,indirect,full} ; \
>& 2 printf "OK\r" ; \
done
@echo ""
rm -rf $( PROF_LOCATION)
rm pgo-generate
pgo-use : CFLAGS += $( RELEASE_CFLAGS ) $( PCH_USE_CFLAGS )
pgo-use : CXXFLAGS += $( RELEASE_CXXFLAGS ) $( PCH_USE_CXXFLAGS )
pgo-use : LDFLAGS += $( RELEASE_LDFLAGS )
pgo-use : PROF_FLAGS = -fprofile -use -fprofile -correction
pgo-use : $( PGO_OBJ )
$( CXX) $^ $( CXXFLAGS) $( PROF_FLAGS) -o $@ $( LDFLAGS) $( PROF_FLAGS)
$(PROJECT)-pgo : CFLAGS += $( RELEASE_CFLAGS ) $( PCH_USE_CFLAGS )
$(PROJECT)-pgo : CXXFLAGS += $( RELEASE_CXXFLAGS ) $( PCH_USE_CXXFLAGS )
$(PROJECT)-pgo : LDFLAGS += $( RELEASE_LDFLAGS )
$(PROJECT)-pgo : pgo -profile
find -O3 ./prof -type f -name \* .o -exec rm { } +
$( MAKE) pgo-use
mv pgo-use $@
strip $@
lib$(PROJECT)-debug.so : CFLAGS += $( DEBUG_CFLAGS ) $( SHARED_FLAGS ) $( SHARED_DEBUG_FLAGS )
lib$(PROJECT)-debug.so : CXXFLAGS += $( DEBUG_CXXFLAGS ) $( SHARED_FLAGS ) $( SHARED_DEBUG_FLAGS )
lib$(PROJECT)-debug.so : LDFLAGS += $( DEBUG_LDFLAGS )
lib$(PROJECT)-debug.so : BINFLAGS += $( DEBUG_BINFLAGS )
lib$(PROJECT)-debug.so : $( OBJ )
$( CXX) -shared $^ $( BINFLAGS) $( CXXFLAGS) -o $@ $( LDFLAGS)
lib$(PROJECT).a : lib $( PROJECT ) -release .a
ln -f $< $@
lib$(PROJECT).so : LDFLAGS += -Wl , -soname , lib $( PROJECT ) .so .$( VERSION_MAJOR )
lib$(PROJECT).so : lib $( PROJECT ) -release .so
ln -f $< $@ .$( VERSION)
ln -sf $@ .$( VERSION) $@ .$( VERSION_MAJOR)
ln -sf $@ .$( VERSION_MAJOR) $@
clean-source :
find -O2 { obj,prof} / -type f -exec rm { } +
@ -317,7 +342,26 @@ clean-rebuild: clean-source
clean : clean -rebuild
rm -f $( PROJECT) -{ release,debug,pgo}
rm -f lib$( PROJECT) { ,-{ release,debug,pgo} } .{ a,so{ ,.*} }
rm -f $( PROJECT) -test
clean-full : clean
rm -rf { obj,prof}
install :
install -d $( DESTDIR) $( PREFIX) /lib/
install -m 644 lib$( PROJECT) .a $( DESTDIR) $( PREFIX) /lib/
install -s -m 755 lib$( PROJECT) .so.$( VERSION) $( DESTDIR) $( PREFIX) /lib/
ln -sf lib$( PROJECT) .so.$( VERSION) $( DESTDIR) $( PREFIX) /lib/lib$( PROJECT) .so.$( VERSION_MAJOR)
ln -sf lib$( PROJECT) .so.$( VERSION_MAJOR) $( DESTDIR) $( PREFIX) /lib/lib$( PROJECT) .so
install -d $( DESTDIR) $( PREFIX) /include/$( INCLUDE_PREFIX)
install -m 644 $( wildcard $( INCLUDE) /*.*) $( DESTDIR) $( PREFIX) /include/$( INCLUDE_PREFIX)
uninstall :
-rm $( DESTDIR) $( PREFIX) /lib/lib$( PROJECT) .{ a,so{ ,.*} }
cd $( INCLUDE) && find . -type f | xargs -I { } rm " $( DESTDIR) $( PREFIX) /include/ $( INCLUDE_PREFIX) {} "
[ [ -d " $( DESTDIR) $( PREFIX) /include/ $( INCLUDE_PREFIX) " ] ] && \
rmdir $( DESTDIR) $( PREFIX) /include/$( INCLUDE_PREFIX) || :
#TODO: We can make the target between `{debug,release}{.a,.so}` configurable by call. e.g. `TARGET=release.a make test`
$(PROJECT)-test : lib $( PROJECT ) -$( TARGET )
$( CC) $( CFLAGS) $( TEST_CFLAGS) src/test/*.c -o $@ -l:$< $( LDFLAGS) $( TEST_LDFLAGS)