Makefile 14.9 KB
Newer Older
1
.PHONY: help shared static python2 python3 doc install test clean version opt warn printBoostVersion
2

3
# ------------------------------------------------------------------------------------------------------
4
#				Default rule should be the help message
5
# ------------------------------------------------------------------------------------------------------
6 7
help:
	@printf "Possible make targets are:\n \
8 9 10 11 12 13
	\t\tversion \t -- Print the version of xerus.\n \
	\t\tshared  \t -- Build xerus as a shared library.\n \
	\t\tstatic  \t -- Build xerus as a static library.\n \
	\t\tpython2 \t -- Build the xerus python2 wrappers.\n \
	\t\tpython3 \t -- Build the xerus python3 wrappers.\n \
	\t\tdoc     \t -- Build the html documentation for the xerus library.\n \
14
	\t\tinstall \t -- Install the shared library and header files (may require root).\n \
15 16
	\t\ttest    \t -- Build and run the xerus unit tests.\n \
	\t\tclean   \t -- Remove all object, library and executable files.\n"
17

18

19
# ------------------------------------------------------------------------------------------------------
20
#				Set the names of the resulting binary codes
21
# ------------------------------------------------------------------------------------------------------
22 23 24 25

# Name of the test executable
TEST_NAME = XerusTest

Ben Huber's avatar
Ben Huber committed
26

27
# ------------------------------------------------------------------------------------------------------
Sebastian Wolf's avatar
Sebastian Wolf committed
28
#			Extract Xerus version from VERSION file and the git repository
29 30 31 32 33 34
# ------------------------------------------------------------------------------------------------------

VERSION_STRING = $(shell git describe --tags --always 2>/dev/null || cat VERSION)
VERSION = -D XERUS_VERSION="$(VERSION_STRING)"

XERUS_MAJOR_V = $(word 1, $(subst ., ,$(VERSION_STRING)) )
35 36 37
ifneq (,$(findstring v, $(XERUS_MAJOR_V)))
	XERUS_MAJOR_V := $(strip $(subst v, ,$(XERUS_MAJOR_V)) )
endif
38 39 40 41
VERSION += -D XERUS_VERSION_MAJOR=$(XERUS_MAJOR_V)
XERUS_MINOR_V = $(word 2, $(subst ., ,$(VERSION_STRING)) )
VERSION += -D XERUS_VERSION_MINOR=$(XERUS_MINOR_V)
XERUS_REVISION_V = $(word 3, $(subst ., ,$(VERSION_STRING)) )
42 43 44 45 46 47
ifneq (,$(findstring -, $(XERUS_REVISION_V)))
	XERUS_COMMIT_V := $(word 2, $(subst -, ,$(XERUS_REVISION_V)) )
	XERUS_REVISION_V := $(word 1, $(subst -, ,$(XERUS_REVISION_V)) )
else
	XERUS_COMMIT_V = 0
endif
48 49
VERSION += -D XERUS_VERSION_REVISION=$(XERUS_REVISION_V)
VERSION += -D XERUS_VERSION_COMMIT=$(XERUS_COMMIT_V)
50

51

52
# ------------------------------------------------------------------------------------------------------
53
#				Register source files for the xerus library
54 55
# ------------------------------------------------------------------------------------------------------

56 57 58
# Register the source files
XERUS_SOURCES = $(wildcard src/xerus/*.cpp)
XERUS_SOURCES += $(wildcard src/xerus/algorithms/*.cpp)
59
XERUS_SOURCES += $(wildcard src/xerus/applications/*.cpp)
60 61 62 63 64 65 66
XERUS_SOURCES += $(wildcard src/xerus/examples/*.cpp)

MISC_SOURCES = $(wildcard src/xerus/misc/*.cpp)

PYTHON_SOURCES = $(wildcard src/xerus/python/*.cpp)

TEST_SOURCES = $(wildcard src/xerus/test/*.cpp)
67

68
UNIT_TEST_SOURCES = $(wildcard src/unitTests/*.cxx)
69

70 71
TUTORIAL_SOURCES = $(wildcard tutorials/*.cpp)

72
# Create lists of the corresponding objects and dependency files
73 74 75 76 77
XERUS_OBJECTS = $(XERUS_SOURCES:%.cpp=build/.libObjects/%.o)
XERUS_DEPS    = $(XERUS_SOURCES:%.cpp=build/.libObjects/%.d)

MISC_OBJECTS = $(MISC_SOURCES:%.cpp=build/.miscObjects/%.o)
MISC_DEPS    = $(MISC_SOURCES:%.cpp=build/.miscObjects/%.d)
78

79 80
# PYTHON_OBJECTS = $(PYTHON_SOURCES:%.cpp=build/.pythonObjects/%.o)
# PYTHON_DEPS    = $(PYTHON_SOURCES:%.cpp=build/.pyhtonObjects/%.d)
81 82 83

TEST_OBJECTS = $(TEST_SOURCES:%.cpp=build/.testObjects/%.o)
TEST_DEPS    = $(TEST_SOURCES:%.cpp=build/.testObjects/%.d)
84

85 86 87
UNIT_TEST_OBJECTS = $(UNIT_TEST_SOURCES:%.cxx=build/.unitTestObjects/%.o)
UNIT_TEST_DEPS    = $(UNIT_TEST_SOURCES:%.cxx=build/.unitTestObjects/%.d)

88
TUTORIALS	= $(TUTORIAL_SOURCES:%.cpp=build/.tutorialObjects/%)
89 90
TUTORIAL_DEPS   = $(TUTORIAL_SOURCES:%.cpp=build/.tutorialObjects/%.d)

91 92

# ------------------------------------------------------------------------------------------------------
93
#		Load the configurations provided by the user and set up general options
94 95 96
# ------------------------------------------------------------------------------------------------------
include config.mk

97 98 99
include makeIncludes/general.mk
include makeIncludes/warnings.mk
include makeIncludes/optimization.mk
100

101

102
# ------------------------------------------------------------------------------------------------------
103
#					Set additional compiler options
104
# ------------------------------------------------------------------------------------------------------
Sebastian Wolf's avatar
Sebastian Wolf committed
105 106 107
ifdef ACTIVATE_CODE_COVERAGE
	DEBUG += -D XERUS_TEST_COVERAGE
endif
108

109
# ------------------------------------------------------------------------------------------------------
110
#					Convinience variables
111
# ------------------------------------------------------------------------------------------------------
112

113 114 115 116 117 118
# Small hack to get newlines...
define \n


endef

119 120
FLAGS = $(strip $(COMPATIBILITY) $(WARNINGS) $(OPTIMIZE) $(VERSION) $(LOGGING) $(DEBUG) $(ADDITIONAL_INCLUDE) $(OTHER))
PYTHON_FLAGS = $(strip $(COMPATIBILITY) $(WARNINGS) $(VERSION) $(LOGGING) $(DEBUG) $(ADDITIONAL_INCLUDE) $(OTHER) -fno-var-tracking-assignments)
121 122 123
MINIMAL_DEPS = Makefile config.mk makeIncludes/general.mk makeIncludes/warnings.mk makeIncludes/optimization.mk


124 125 126
# ------------------------------------------------------------------------------------------------------
#					Load dependency files
# ------------------------------------------------------------------------------------------------------
127

128 129 130 131 132 133
-include $(XERUS_DEPS)
-include $(MISC_DEPS)
-include $(TEST_DEPS)
-include $(UNIT_TEST_DEPS)
-include $(TUTORIAL_DEPS)
-include build/.preCompileHeaders/xerus.h.d
134

135

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
# ------------------------------------------------------------------------------------------------------
#					Custom functions
# ------------------------------------------------------------------------------------------------------

# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
# Params:
#   1. Variable name(s) to test.
#   2. (optional) Error message to print.
check_defined = \
	$(strip $(foreach 1,$1, \
		$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
	$(if $(value $1),, \
		$(error Undefined $1$(if $2, ($2))$(if $(value @), \
				required by target `$@')))

# Check that given variables are declared (they may have empty values),
# die with an error otherwise.
#
# Params:
#   1. Variable name(s) to test.
#   2. (optional) Error message to print.
check_declared = \
	$(strip $(foreach 1,$1, \
		$(call __check_defined,$1,$(strip $(value 2)))))
__check_declared = \
	$(if $(filter undefined,$(origin $1)), \
		$(error Undeclared $1$(if $2, ($2))$(if $(value @), \
                required by target `$@' (variable may be empty but must be defined))))

# Check that a variable specified through the stem is defined and has
# a non-empty value, die with an error otherwise.
#
#   %: The name of the variable to test.
#
check-defined-%: __check_defined_FORCE
    @:$(call check_defined, $*, target-specific)

# Since pattern rules can't be listed as prerequisites of .PHONY,
# we use the old-school and hackish FORCE workaround.
# You could go without this, but otherwise a check can be missed
# in case a file named like `check-defined-...` exists in the root
# directory, e.g. left by an accidental `make -t` invocation.
.PHONY: __check_defined_FORCE
__check_defined_FORCE:


185
# ------------------------------------------------------------------------------------------------------
186
#					Make Rules
187 188
# ------------------------------------------------------------------------------------------------------

189 190
opt:
	$(CXX) $(FLAGS) -Q --help=optimizers
191 192 193 194 195 196


warn:
	$(CXX) $(FLAGS) -Q --help=warnings


197
# Fake rule to create arbitary headers, to prevent errors if files are moved/renamed
198
%.h:
199

200
shared: build/libxerus_misc.so build/libxerus.so
201

202 203 204 205
.PHONY: libxerus_misc_dependencies
libxerus_misc_dependencies:
	@:$(call check_defined, BOOST_LIBS, include and link paths)
build/libxerus_misc.so: libxerus_misc_dependencies $(MINIMAL_DEPS) $(MISC_SOURCES)
206
	mkdir -p $(dir $@)
207
	$(CXX) -shared -fPIC -Wl,-soname,libxerus_misc.so $(FLAGS) -I include $(MISC_SOURCES) -Wl,--as-needed $(CALLSTACK_LIBS) $(BOOST_LIBS) -o build/libxerus_misc.so
208

209 210 211 212
.PHONY: libxerus_dependencies
libxerus_dependencies:
	@:$(call check_defined, SUITESPARSE LAPACK_LIBRARIES BLAS_LIBRARIES, include and link paths)
build/libxerus.so: libxerus_dependencies $(MINIMAL_DEPS) $(XERUS_SOURCES) build/libxerus_misc.so
213
	mkdir -p $(dir $@)
Michael Goette's avatar
Michael Goette committed
214
	$(CXX) -shared -fPIC -Wl,-soname,libxerus.so $(FLAGS) -I include $(XERUS_SOURCES) -L ./build/ -Wl,--as-needed -lxerus_misc $(SUITESPARSE) $(LAPACK_LIBRARIES) $(ARPACK_LIBRARIES) $(BLAS_LIBRARIES) -o build/libxerus.so
215

216

217 218
python2: build/python2/xerus.so
python3: build/python3/xerus.so
219 220

build/python2/xerus.so: $(MINIMAL_DEPS) $(PYTHON_SOURCES) build/libxerus.so
221
	@:$(call check_defined, PYTHON2_CONFIG BOOST_PYTHON2, include and link paths)
222
	mkdir -p $(dir $@)
223
	$(CXX) -shared -fPIC -Wl,-soname,xerus.so $(PYTHON2_CONFIG) $(PYTHON_FLAGS) -I include $(PYTHON_SOURCES) -L ./build/ -Wl,--as-needed -lxerus $(BOOST_PYTHON2) -o $@
224

225
build/python3/xerus.so: $(MINIMAL_DEPS) $(PYTHON_SOURCES) build/libxerus.so
226
	@:$(call check_defined, PYTHON3_CONFIG BOOST_PYTHON3, include and link paths)
227
	mkdir -p $(dir $@)
228
	@# -fpermissive is needed because of a bug in the definition of BOOST_PYTHON_MODULE_INIT in <boost/python/module_init.h>
229
	$(CXX) -shared -fPIC -Wl,-soname,xerus.so $(PYTHON3_CONFIG) $(PYTHON_FLAGS) -fpermissive -I include $(PYTHON_SOURCES) -L ./build/ -Wl,--as-needed -lxerus $(BOOST_PYTHON3) -o $@
230

231

232
static: build/libxerus_misc.a build/libxerus.a
233

234
build/libxerus_misc.a: libxerus_misc_dependencies $(MINIMAL_DEPS) $(MISC_OBJECTS)
235
	mkdir -p $(dir $@)
236 237 238 239 240 241
ifdef USE_LTO
	gcc-ar rcs ./build/libxerus_misc.a $(MISC_OBJECTS)
else
	ar rcs ./build/libxerus_misc.a $(MISC_OBJECTS)
endif

242
build/libxerus.a: libxerus_dependencies $(MINIMAL_DEPS) $(XERUS_OBJECTS)
243
	mkdir -p $(dir $@)
244 245 246 247
ifdef USE_LTO
	gcc-ar rcs ./build/libxerus.a $(XERUS_OBJECTS)
else
	ar rcs ./build/libxerus.a $(XERUS_OBJECTS)
248 249
endif

250

251 252 253 254 255
ifdef INSTALL_PYTHON2_PATH
install: build/python2/xerus.so
endif
ifdef INSTALL_PYTHON3_PATH
install: build/python3/xerus.so
256
endif
257 258
ifdef INSTALL_LIB_PATH
ifdef INSTALL_HEADER_PATH
259
install: shared
260 261
	test -d $(strip $(INSTALL_LIB_PATH));
	test -d $(strip $(INSTALL_HEADER_PATH));
262 263 264
	@printf "Installing libxerus.so to $(strip $(INSTALL_LIB_PATH)) and storing the header files in $(strip $(INSTALL_HEADER_PATH)).\n"
	cp include/xerus.h $(INSTALL_HEADER_PATH)
	cp -r include/xerus $(INSTALL_HEADER_PATH)
265 266
	cp build/libxerus_misc.so $(INSTALL_LIB_PATH)
	cp build/libxerus.so $(INSTALL_LIB_PATH)
267
ifdef INSTALL_PYTHON2_PATH
268
	test -d $(strip $(INSTALL_PYTHON2_PATH));
269 270 271 272
	@printf "Installing xerus.so to $(strip $(INSTALL_PYTHON2_PATH)).\n"
	cp build/python2/xerus.so $(INSTALL_PYTHON2_PATH)
endif
ifdef INSTALL_PYTHON3_PATH
273
	test -d $(strip $(INSTALL_PYTHON3_PATH));
274 275
	@printf "Installing xerus.so to $(strip $(INSTALL_PYTHON3_PATH)).\n"
	cp build/python3/xerus.so $(INSTALL_PYTHON3_PATH)
276
endif
277
else
278
install:
279
	@printf "Cannot install xerus: INSTALL_HEADER_PATH not set. Please set the path in config file.\n"
280 281 282
endif
else
install:
283
	@printf "Cannot install xerus: INSTALL_LIB_PATH not set.  Please set the path in config file.\n"
284
endif
285

286
$(TEST_NAME): libxerus_misc_dependencies libxerus_dependencies $(MINIMAL_DEPS) $(UNIT_TEST_OBJECTS) $(TEST_OBJECTS) build/libxerus.a build/libxerus_misc.a
Sebastian Wolf's avatar
Sebastian Wolf committed
287
	$(CXX) -D XERUS_UNITTEST $(FLAGS) $(UNIT_TEST_OBJECTS) $(TEST_OBJECTS) build/libxerus.a build/libxerus_misc.a $(SUITESPARSE) $(LAPACK_LIBRARIES) $(ARPACK_LIBRARIES) $(BLAS_LIBRARIES) $(BOOST_LIBS) $(CALLSTACK_LIBS) -o $(TEST_NAME)
288

289 290 291 292 293
build/print_boost_version: src/print_boost_version.cpp
	@$(CXX) -o $@ $<

printBoostVersion: build/print_boost_version
	@build/print_boost_version
294

Sebastian Wolf's avatar
Sebastian Wolf committed
295
ifdef ACTIVATE_CODE_COVERAGE
296
ifdef BROCKEN_CI
Sebastian Wolf's avatar
Sebastian Wolf committed
297 298
test:
	mkdir -p build
299
	make $(TEST_NAME)
300
	@cat build/build_output.txt | grep "REQUIRE_TEST @" > build/required_tests.txt
Sebastian Wolf's avatar
Sebastian Wolf committed
301 302
	./$(TEST_NAME) all
else
303 304 305 306

MAKE_PID := $(shell echo $$PPID)
JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))

307 308
test:
	mkdir -p build
309
	make $(TEST_NAME) $(JOB_FLAG) &> build/build_output.txt || cat build/build_output.txt
310
	@cat build/build_output.txt | grep "REQUIRE_TEST @" > build/required_tests.txt
311 312 313
	./$(TEST_NAME) all
endif
else
314 315
test:  $(TEST_NAME)
	./$(TEST_NAME) all
Sebastian Wolf's avatar
Sebastian Wolf committed
316 317
endif

318

319 320
.PHONY: test_python2_dependencies
test_python2_dependencies:
321
	@:$(call check_defined, PYTEST2, pytest executable)
322
test_python2: test_python2_dependencies build/libxerus.so build/python2/xerus.so
323 324
	@PYTHONPATH=build/python2:${PYTHONPATH} LD_LIBRARY_PATH=build:${LD_LIBRARY_PATH} $(PYTEST2) src/pyTests

325 326
.PHONY: test_python3_dependencies
test_python3_dependencies:
327
	@:$(call check_defined, PYTEST3, pytest executable)
328
test_python3: test_python3_dependencies build/libxerus.so build/python3/xerus.so
329
	@PYTHONPATH=build/python3:${PYTHONPATH} LD_LIBRARY_PATH=build:${LD_LIBRARY_PATH} $(PYTEST3) src/pyTests
330 331


332
fullTest: $(TUTORIALS) $(TEST_NAME)
333
	$(foreach x,$(TUTORIALS),./$(x)$(\n))
334
	./$(TEST_NAME) all
335

336

Philipp  Trunschke's avatar
Philipp Trunschke committed
337
doc:
338 339 340
	make -C doc doc


341 342 343 344
clean:
	rm -fr build
	-rm -f $(TEST_NAME)
	-rm -f include/xerus.h.gch
345
	make -C doc clean
346

347
version:
348
	@echo $(XERUS_MAJOR_V).$(XERUS_MINOR_V).$(XERUS_REVISION_V)
349

350

351

352 353
# Build rule for normal misc objects
build/.miscObjects/%.o: %.cpp $(MINIMAL_DEPS)
354
	mkdir -p $(dir $@)
355 356 357
	$(CXX) -I include $< -c $(FLAGS) -MMD -o $@


358 359
# Build rule for normal lib objects
build/.libObjects/%.o: %.cpp $(MINIMAL_DEPS)
360
	mkdir -p $(dir $@)
361
	$(CXX) -I include $< -c $(FLAGS) -MMD -o $@
362

363

364 365 366
# Build rule for test lib objects
build/.testObjects/%.o: %.cpp $(MINIMAL_DEPS)
	mkdir -p $(dir $@)
367
	$(CXX) -D XERUS_UNITTEST -I include $< -c $(FLAGS) -MMD -o $@
368

369

370
# Build rule for unit test objects
Ben Huber's avatar
Ben Huber committed
371
ifdef USE_GCC
372
build/.unitTestObjects/%.o: %.cxx $(MINIMAL_DEPS) build/.preCompileHeaders/xerus.h.gch build/.preCompileHeaders/common.hxx.gch
373
	mkdir -p $(dir $@)
374
	$(CXX) -D XERUS_UNITTEST -I build/.preCompileHeaders $< -c $(FLAGS) -MMD -o $@
375
else
376
build/.unitTestObjects/%.o: %.cxx $(MINIMAL_DEPS)
377
	mkdir -p $(dir $@)
378
	$(CXX) -D XERUS_UNITTEST -I include -I src/unitTests $< -c $(FLAGS) -MMD -o $@
379
endif
380

381

382
# Build and execution rules for tutorials
383
build/.tutorialObjects/%: %.cpp $(MINIMAL_DEPS) build/libxerus.a build/libxerus_misc.a
384
	mkdir -p $(dir $@)
Sebastian Wolf's avatar
Sebastian Wolf committed
385
	$(CXX) -I include $< build/libxerus.a build/libxerus_misc.a $(SUITESPARSE) $(LAPACK_LIBRARIES) $(ARPACK_LIBRARIES) $(BLAS_LIBRARIES) $(BOOST_LIBS) $(CALLSTACK_LIBS) $(FLAGS) -MMD -o $@
386

387

388
# Build rule for the preCompileHeader
389
build/.preCompileHeaders/xerus.h.gch: include/xerus.h $(MINIMAL_DEPS) .git/ORIG_HEAD
390
	mkdir -p $(dir $@)
391
	$(CXX) -D XERUS_UNITTEST $< -c $(FLAGS) -MMD -o $@
392

393

394 395 396 397 398 399
# Build rule for the other preCompileHeader
build/.preCompileHeaders/common.hxx.gch: src/unitTests/common.hxx $(MINIMAL_DEPS) .git/ORIG_HEAD
	mkdir -p $(dir $@)
	$(CXX) -D XERUS_UNITTEST $< -c $(FLAGS) -MMD -o $@


400 401 402 403 404
# dummy rule in case files were downloaded without git
.git/ORIG_HEAD:
	mkdir -p .git
	touch .git/ORIG_HEAD