-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmakefile
176 lines (150 loc) · 4.94 KB
/
makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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
#
# Makefile for ArCTIC
#
# Options
# -------
#
# default
# The main program and the shared object library (used by the python wrapper).
#
# arctic
# The main program. See src/main.cpp.
#
# test, test_arctic
# The unit tests. See test/*.cpp.
#
# lib, libarctic.so
# The dynamic library shared object.
#
# lib_test
# A simple test for using the shared library. See test/test_lib.cpp.
#
# core
# All of the above.
#
# wrapper
# The cython wrapper for the arcticpy python module.
#
# gsl
# The GNU Scientific Library (www.gnu.org/software/gsl/). See get_gsl.sh.
#
# all
# All of the above.
#
# clean
# Remove compiled files.
#
# clean-gsl
# Remove GSL (not done by `clean`).
#
# ========
# Set up
# ========
# Compiler
CXX ?= g++
CXXFLAGS := -std=c++11 -fPIC -O3 # -Wall -Wno-reorder -Wno-sign-compare
#CXXFLAGS := -std=c++11 -fPIC -pg -no-pie -fno-builtin # for gprof
#CXXFLAGS := -std=c++11 -fPIC -g # for valgrind
LDFLAGS := $(LDFLAGS) -shared
VERSION := "7.0.6"
# Executables
TARGET := arctic
TEST_TARGET := test_arctic
LIB_TARGET := libarctic.so
LIB_TEST_TARGET := lib_test
# Directories
DIR_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
DIR_SRC := $(DIR_ROOT)/src
DIR_OBJ := $(DIR_ROOT)/build
DIR_INC := $(DIR_ROOT)/include
DIR_TEST := $(DIR_ROOT)/test
# Use the following on cosma
#DIR_GSL ?= /cosma/local/gsl/2.8
#DIR_OMP ?= /cosma/local/openmpi/gnu_11.1.0/4.1.4
# Use the following on a standalone machine
DIR_HOMEBREW := /usr/local # brew install llvm libomp gsl
DIR_MACPORTS := /opt/local # sudo port install libomp gsl
#DIR_GSL ?= $(DIR_HOMEBREW)
#DIR_OMP ?= $(DIR_HOMEBREW)
#DIR_OMP ?= $(DIR_MACPORTS)/libomp
DIR_OMP ?= $(DIR_MACPORTS)
DIR_GSL ?= $(DIR_MACPORTS)
# Use the following if the above doesn't work - fall back to self-installing GSL
#DIR_GSL ?= $(DIR_ROOT)/gsl
DIR_WRAPPER := $(DIR_ROOT)/python/arcticpy
DIR_WRAPPER_SRC := $(DIR_ROOT)/python/arcticpy
$(shell mkdir -p $(DIR_OBJ))
$(info $(DIR_SRC) $(DIR_OBJ))
# Source and object files, and dependency files to detect header file changes
SOURCES := $(shell find $(DIR_SRC) -type f -name *.cpp)
OBJECTS := $(patsubst $(DIR_SRC)%, $(DIR_OBJ)%, $(SOURCES:.cpp=.o))
DEPENDS := $(patsubst %.o, %.d, $(OBJECTS))
LIB_TEST_SOURCES := $(DIR_TEST)/test_lib.cpp
TEST_SOURCES := $(filter-out $(LIB_TEST_SOURCES), \
$(shell find $(DIR_TEST) -type f -name *.cpp))
TEST_OBJECTS := $(patsubst $(DIR_TEST)%, $(DIR_OBJ)%, $(TEST_SOURCES:.cpp=.o)) \
$(filter-out $(DIR_OBJ)/main.o, $(OBJECTS))
TEST_DEPENDS := $(patsubst %.o, %.d, $(TEST_OBJECTS))
$(info $(SOURCES) $(OBJECTS))
# Headers and library links
INCLUDE := -I $(DIR_INC) -I $(DIR_GSL)/include
LIBS := -L $(DIR_GSL)/lib -Wl,-rpath,$(DIR_GSL)/lib -lgsl -lgslcblas -lm
LIBARCTIC := -L $(DIR_ROOT) -Wl,-rpath,$(DIR_ROOT) -l$(TARGET)
# Add multithreading to reduce runtime (requires OpenMP to have been installed)
CXXFLAGS += -Xpreprocessor -fopenmp
# Use the following on a homebrew mac
#LIBS += -L $(DIR_OMP)/lib -lomp
# Use the following on linux, cosma, or a mac with macports
LIBS += -L $(DIR_OMP)/lib -lgomp
# ========
# Rules
# ========
# Default to main program and library
.DEFAULT_GOAL := default
default: $(TARGET) $(LIB_TARGET)
# Ignore any files with these names
.PHONY: all default test lib lib_test wrapper clean gsl clean-gsl
# Everything
all: gsl core wrapper
# Main program, unit tests, library, library test, and wrapper
core: $(TARGET) $(TEST_TARGET) $(LIB_TARGET) $(LIB_TEST_TARGET)
# Main program
$(TARGET): $(OBJECTS)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LIBS)
$(OBJECTS): $(DIR_GSL)
-include $(DEPENDS)
$(DIR_OBJ)%.o: $(DIR_SRC)/%.cpp makefile
$(CXX) $(CXXFLAGS) $(INCLUDE) -MMD -MP -c $< -o $@ -DVERSION='$(VERSION)'
# Unit tests
test: $(TEST_TARGET)
$(TEST_TARGET): $(TEST_OBJECTS)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LIBS)
-include $(TEST_DEPENDS)
$(DIR_OBJ)%.o: $(DIR_TEST)/%.cpp
$(CXX) $(CXXFLAGS) $(INCLUDE) -MMD -MP -c $< -o $@
# Dynamic library
lib: $(LIB_TARGET)
$(LIB_TARGET): $(OBJECTS)
$(CXX) $(LDFLAGS) $^ -o $@ $(LIBS)
# Test using the library
$(LIB_TEST_TARGET): $(LIB_TARGET)
$(CXX) $(CXXFLAGS) $(INCLUDE) $(LIBARCTIC) $(LIB_TEST_SOURCES) -o $@ $(LIBS)
# Cython wrapper
wrapper: $(LIB_TARGET)
python3 $(DIR_ROOT)/make_setup.py build_ext --inplace
# @mv -v $(DIR_WRAPPER)/../*.cpython*.so $(DIR_WRAPPER)/
# @rm -rfv $(DIR_WRAPPER)build
clean:
@rm -fv $(OBJECTS) $(DEPENDS) $(TEST_OBJECTS) $(TEST_DEPENDS) $(DIR_OBJ)/test_lib.[od]
@rm -fv $(TARGET) $(TEST_TARGET) $(LIB_TARGET) $(LIB_TEST_TARGET)
@rm -fv $(DIR_WRAPPER)/*.cpython*.so $(DIR_WRAPPER_SRC)/wrapper.cpp
@rm -rfv $(DIR_ROOT)/build/temp.*/ $(DIR_WRAPPER)/__pycache__/ \
$(DIR_TEST)/__pycache__/
# GSL
GSL_VERSION := 2.6
gsl:
@if ! [ -d $(DIR_GSL) ]; then \
./get_gsl.sh $(DIR_ROOT) $(DIR_GSL) $(GSL_VERSION); \
fi
clean-gsl:
@rm -rfv gsl*