Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
makefile 8.79 KiB
SHELL:=/bin/bash
USE_RAMDISK ?= 0
-include makefile.conf

FULL_LIBRARY:=lib$(LIBRARY).so
define NEW_LINE


endef

export NEW_LINE

CXX_FLAGS := -Wall -pedantic -Wextra -Werror -Wshadow -Wpointer-arith -Wcast-qual -Wdelete-non-virtual-dtor -Wredundant-decls

space := $(eval) $(eval)

LDFLAGS_DEBUG:=-rdynamic -shared
TEST_LDFLAGS_DEBUG:=-Wl,-no-as-needed -Llib-debug $(addprefix -L, $(addsuffix lib-debug, $(LINK_PATHS))) -rdynamic -l$(LIBRARY) $(addprefix -l, $(LINK_LIBRARIES)) -lcppunit -Wl,-rpath,.

LDFLAGS_RELEASE:=-rdynamic -shared
TEST_LDFLAGS_RELEASE:=-Wl,-no-as-needed -Llib-release $(addprefix -L, $(addsuffix lib-release, $(LINK_PATHS))) -rdynamic -l$(LIBRARY) $(addprefix -l, $(LINK_LIBRARIES)) -lcppunit -Wl,-rpath,.

OBJECTS_DEBUG:=$(patsubst src/%.cpp,obj-debug/%.o, $(shell find src/ -name *cpp))
TEST_OBJECTS_DEBUG:=$(patsubst test-src/%.cpp,test-obj-debug/%.o, $(shell find test-src/ -name *cpp))

OBJECTS_RELEASE:=$(patsubst src/%.cpp,obj-release/%.o, $(filter-out $(wildcard src/debug/*), $(shell find src/ -name *cpp)))
TEST_OBJECTS_RELEASE:=$(patsubst test-src/%.cpp,test-obj-release/%.o, $(shell find test-src/ -name *cpp))

.PHONY: all debug release clean build-debug build-release clean-debug clean-release doc

all:
	@echo "What to do master?"

FORCE:

# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# make subdir makefile

%/makefile: makefile makefile.conf
	if [ ! -w $(dir $@) ] && [ $(USE_RAMDISK) -eq 1 ]; then\
		ln -s /tmp/`date +'%s%N'`-$(dir $@) $(subst /,, $(dir $@)) 2>/dev/null;\
	fi;\
	if [ -L $(subst /,, $(dir $@)) ]; then\
		mkdir -p `readlink $(subst /,, $(dir $@))`;\
	else\
		mkdir -p $(dir $@);\
	fi
	echo "\
	SHELL:=/bin/bash$${NEW_LINE}\
	SRCDIR:=$${NEW_LINE}\
	$${NEW_LINE}\
	define NEW_LINE$${NEW_LINE}\
	$${NEW_LINE}\
	$${NEW_LINE}\
	endef$${NEW_LINE}\
	$${NEW_LINE}\
	export NEW_LINE$${NEW_LINE}\
	$${NEW_LINE}\
	CXXFLAGS:= -pipe -std=c++11 \$$(CXX_OTHER_FLAGS) -c $(CXX_FLAGS) -fPIC \$$(addprefix -I, \$$(realpath $(INCLUDE_PATHS))) -I\$$(realpath \$$(SOURCES_BASE_DIR)/../src/)$${NEW_LINE}\
	$${NEW_LINE}\
	SOURCES:= \$$(shell find \$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -type f -name \"*.cpp\")$${NEW_LINE}\
	DEPENDENCIES:= \$$(patsubst \$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d, \$$(SOURCES))$${NEW_LINE}\
	OBJECTS:= \$$(patsubst %.d, %.o, \$$(DEPENDENCIES))$${NEW_LINE}\
	SOURCES_DIRS:= \$$(shell find \$$(SOURCES_BASE_DIR)/\$$(SRCDIR) -maxdepth 1 -mindepth 1 -type d)$${NEW_LINE}\
	OBJECTS_DIRS:= \$$(patsubst \$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%, %/, \$$(SOURCES_DIRS))$${NEW_LINE}\
	OBJECTS_DIRS_MAKEFILES:= \$$(patsubst %, %makefile, \$$(OBJECTS_DIRS))$${NEW_LINE}\
	$${NEW_LINE}\
	.PHONY: all$${NEW_LINE}\
	.PRECIOUS: \$$(DEPENDECIES) \$$(OBJECTS_DIRS_MAKEFILES)$${NEW_LINE}\
	$${NEW_LINE}\
	all: \$$(OBJECTS_DIRS) \$$(OBJECTS)$${NEW_LINE}\
	$${NEW_LINE}\
	%.d: makefile$${NEW_LINE}\
		@echo \"\\$${NEW_LINE}\
		\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\") = \\$$\$$(shell (\\$$\$$(CXX) -M \\$$\$$(CXXFLAGS) \$$(patsubst \$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) 2>/dev/null || echo \\\"\$$(patsubst \$$(OBJECTS_BASE_DIR)/\$$(SRCDIR)%.d,\$$(SOURCES_BASE_DIR)/\$$(SRCDIR)%.cpp, \$$@) FORCE\\\") | sed \\\"s/.*://g;s/\\\\\\\\\\\\\\\\//g\\\")\$$\$${NEW_LINE}\\$${NEW_LINE}\
		\$$(patsubst %.d,%.o, \$$@): \\$$\$$(\$$(shell sha1sum <<< \"\$$@\" | sed \"s/  -//g\")) makefile\$$\$${NEW_LINE}\\$${NEW_LINE}\
			\\$$\$$(CXX) \\$$\$$(CXXFLAGS) \\$$\$$< -o \$$(patsubst %.d,%.o, \$$@)\$$\$${NEW_LINE}\\$${NEW_LINE}\
		\" > \$$@$${NEW_LINE}\
	$${NEW_LINE}\
	%/makefile: makefile$${NEW_LINE}\
		mkdir -p \$$(dir \$$@)$${NEW_LINE}\
		cp makefile \$$@$${NEW_LINE}\
	$${NEW_LINE}\
	%/: FORCE | %/makefile$${NEW_LINE}\
		@accesstime=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
		\$$(MAKE) -C \$$@ SRCDIR=\$$(SRCDIR)\$$(notdir \$$(patsubst %/, %, \$$@))/ OBJECTS_BASE_DIR=\$$(OBJECTS_BASE_DIR) SOURCES_BASE_DIR=\$$(SOURCES_BASE_DIR) CXX_OTHER_FLAGS=\"\$$(CXX_OTHER_FLAGS)\" && \\$${NEW_LINE}\
		accesstime2=\`stat -c %Y \$$@\` && \\$${NEW_LINE}\
		if [ "\$$\$$accesstime" -ne "\$$\$$accesstime2" ]; then \\$${NEW_LINE}\
			touch .; \\$${NEW_LINE}\
		fi$${NEW_LINE}\
	$${NEW_LINE}\
	FORCE:$${NEW_LINE}\
	$${NEW_LINE}\
	-include \$$(DEPENDENCIES)" > $@

# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# final lib/bin construction

lib-debug/$(FULL_LIBRARY): $(OBJECTS_DEBUG) obj-debug/
	if [ ! -w $(dir $@) ] && [ $(USE_RAMDISK) -eq 1 ]; then\
		ln -s /tmp/`date +'%s%N'`-$(dir $@) $(subst /,, $(dir $@)) 2>/dev/null;\
	fi;\
	if [ -L $(subst /,, $(dir $@)) ]; then\
		mkdir -p `readlink $(subst /,, $(dir $@))`;\
	else\
		mkdir -p $(dir $@);\
	fi
	$(CXX) $(OBJECTS_DEBUG) -o $@ $(LDFLAGS_DEBUG)

lib-release/$(FULL_LIBRARY): $(OBJECTS_RELEASE) obj-release/
	if [ ! -w $(dir $@) ] && [ $(USE_RAMDISK) -eq 1 ]; then\
		ln -s /tmp/`date +'%s%N'`-$(dir $@) $(subst /,, $(dir $@)) 2>/dev/null;\
	fi;\
	if [ -L $(subst /,, $(dir $@)) ]; then\
		mkdir -p `readlink $(subst /,, $(dir $@))`;\
	else\
		mkdir -p $(dir $@);\
	fi
	$(CXX) $(OBJECTS_RELEASE) -o $@ $(LDFLAGS_RELEASE)

test-bin-debug/$(TESTBIN): lib-debug/$(FULL_LIBRARY) $(TEST_OBJECTS_DEBUG) test-obj-debug/
	if [ ! -w $(dir $@) ] && [ $(USE_RAMDISK) -eq 1 ]; then\
		ln -s /tmp/`date +'%s%N'`-$(dir $@) $(subst /,, $(dir $@)) 2>/dev/null;\
	fi;\
	if [ -L $(subst /,, $(dir $@)) ]; then\
		mkdir -p `readlink $(subst /,, $(dir $@))`;\
	else\
		mkdir -p $(dir $@);\
	fi
	$(CXX) $(TEST_OBJECTS_DEBUG) -o $@ $(TEST_LDFLAGS_DEBUG)

test-bin-release/$(TESTBIN): lib-release/$(FULL_LIBRARY) $(TEST_OBJECTS_RELEASE) test-obj-release/
	if [ ! -w $(dir $@) ] && [ $(USE_RAMDISK) -eq 1 ]; then\
		ln -s /tmp/`date +'%s%N'`-$(dir $@) $(subst /,, $(dir $@)) 2>/dev/null;\
	fi;\
	if [ -L $(subst /,, $(dir $@)) ]; then\
		mkdir -p `readlink $(subst /,, $(dir $@))`;\
	else\
		mkdir -p $(dir $@);\
	fi
	$(CXX) $(TEST_OBJECTS_RELEASE) -o $@ $(TEST_LDFLAGS_RELEASE)

# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# subdir make calls

obj-debug/: FORCE obj-debug/makefile
	$(MAKE) -C $@ OBJECTS_BASE_DIR=$(realpath obj-debug) SOURCES_BASE_DIR=$(realpath src) CXX_OTHER_FLAGS="-g -O0 -DDEBUG"

obj-release/: FORCE obj-release/makefile
	$(MAKE) -C $@ OBJECTS_BASE_DIR=$(realpath obj-release) SOURCES_BASE_DIR=$(realpath src) CXX_OTHER_FLAGS="-O3 -DNDEBUG -DRELEASE"

test-obj-debug/: FORCE test-obj-debug/makefile
	$(MAKE) -C $@ OBJECTS_BASE_DIR=$(realpath test-obj-debug) SOURCES_BASE_DIR=$(realpath test-src) CXX_OTHER_FLAGS="-g -O0 -DDEBUG"

test-obj-release/: FORCE test-obj-release/makefile
	$(MAKE) -C $@ OBJECTS_BASE_DIR=$(realpath test-obj-release) SOURCES_BASE_DIR=$(realpath test-src) CXX_OTHER_FLAGS="-O3 -DNDEBUG -DRELEASE"

# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# objects dependencies

$(OBJECTS_DEBUG): obj-debug/

$(OBJECTS_RELEASE): obj-release/

$(TEST_OBJECTS_DEBUG): test-obj-debug/

$(TEST_OBJECTS_RELEASE): test-obj-release/

# -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# main targets

debug: test-bin-debug/$(TESTBIN)
	LD_LIBRARY_PATH="$(subst $(space),,$(addsuffix lib-debug;,$(LINK_PATHS)))lib-debug" test-bin-debug/$(TESTBIN)

release: test-bin-release/$(TESTBIN)
	LD_LIBRARY_PATH="$(subst $(space),,$(addsuffix lib-release;,$(LINK_PATHS)))lib-release" test-bin-release/$(TESTBIN)

clean: clean-debug clean-release
	$(RM) -r doc

build-debug: lib-debug/$(FULL_LIBRARY)

build-release: lib-release/$(FULL_LIBRARY)

clean-debug:
	if [ -L obj-debug ]; then\
		$(RM) -r `readlink obj-debug`;\
	fi
	if [ -L lib-debug ]; then\
		$(RM) -r `readlink lib-debug`;\
	fi
	if [ -L test-obj-debug ]; then\
		$(RM) -r `readlink test-obj-debug`;\
	fi
	if [ -L test-bin-debug ]; then\
		$(RM) -r `readlink test-bin-debug`;\
	fi
	$(RM) -r *.o *.d lib-debug obj-debug test-bin-debug test-obj-debug CppUnitTestResults.xml

clean-release:
	if [ -L obj-release ]; then\
		$(RM) -r `readlink obj-release`;\
	fi
	if [ -L lib-release ]; then\
		$(RM) -r `readlink lib-release`;\
	fi
	if [ -L test-obj-release ]; then\
		$(RM) -r `readlink test-obj-release`;\
	fi
	if [ -L test-bin-release ]; then\
		$(RM) -r `readlink test-bin-release`;\
	fi
	$(RM) -r *.o *.d lib-release obj-release test-bin-release test-obj-release CppUnitTestResults.xml

doc:
	doxygen