/
Makefile
234 lines (196 loc) · 6.44 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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#
# Petsc relies on a lot of libraries. The easiest way to set compiler
# flags is to use the variables defined by Petsc makefiles. The file
# "variables" included below defines PETSC_CC_INCLUDES and PETSC_LIB
# among other things. To overwrite the default location do e.g.:
#
# export PETSC_DIR=/usr/lib/petsc
#
# On Debian derivatives this is a symbolic link to the actual location
# managed by update-alternatives. The structure of config directory
# was different before Petsc 3.0 --- adapt the include path
# accordingly:
#
PETSC_DIR ?= /usr/lib/petsc
include $(PETSC_DIR)/conf/variables # on Wheezy, Ubuntu 12.04
# include $(PETSC_DIR)/bmake/common/variables # on Lenny
#
# Finally, execute
#
# make clean
# make -s
#
# FIXME: Note that generating dependencies for Fortran files may fail
# in a parallel build (make -j). Delete all the *.d files if you
# encounter the problem with GFortran being unable to generate
# dependencies. A serial "make clean" might be sometimes sufficient
# to initally populate *.d files.
#
# You could change this teporarily to test compilation while there are
# jobs running that use the executable:
exe = bgy3d
all: $(exe)
# Shell
SHELL = /bin/sh
#
# Guile is a Scheme interpreter. Set this to one to compile a
# BGY3d-enabled interpreter:
#
WITH_GUILE = 1
#
# Compile a shared library libbgy3d.so and link that to the
# executable. May require setting LD_LIBRARY_PATH in order to run
# that. The following flag is used in expressions like $(if $(shared),
# ...) so in order to turn the feature off it is not enough to set
# shared = 0, one has to comment the line instead:
#
# shared = 1
USR-FLAGS = -DL_BOUNDARY
# Path to sources
srcdir = .
# Compiler and compiler options. For some reason the Fortran needs to
# be told to return small structs (such as the SCM objects) in
# registers. Otherwise you will encounter a segfault on the first
# call of a foreign (C) function returning a Lisp object in Fortran
# sources.
CC = gcc
FC = gfortran
CFLAGS = -g -std=c99 -Wall -Wextra -Ofast $(PIC-FLAGS) $(USR-FLAGS)
FFLAGS = -g -std=f2008 -Wall -O3 -freg-struct-return $(PIC-FLAGS) $(OMP-FLAGS) $(DBG-FFLAGS)
LDFLAGS = $(OMP-FLAGS)
# Flags to generate position independent code (PIC) for shared objects
# happen to be the same for gcc and gfortran:
PIC-FLAGS = $(if $(shared), -fPIC)
# I was not able to get a real speedup for urany/water with N=8192, so
# this remains disabled. Note that -fopenmp is accepted by both
# gcc/gfortran (not used in C though) and also needs to be supplied at
# link stage:
OMP-FLAGS = # -fopenmp
# Fortran flags to assist debugging and experiments:
DBG-FFLAGS = -fexternal-blas -fblas-matmul-limit=1 # -fcheck-array-temporaries -fbounds-check
INCDIRS = $(PETSC_CC_INCLUDES) -I./fft
fftw3-libs = -lfftw3_mpi -lfftw3
fftw2-libs = -lfftw_mpi -lfftw
rfftw2-libs = -lrfftw_mpi -lfftw_mpi -lrfftw -lfftw
LIBS = $(fftw3-libs) -lm $(PETSC_LIB) -lminpack
#--------------------------------------------------------------------------------
# Make rules
#--------------------------------------------------------------------------------
libbgy3d.a = $(c-objs) $(f-objs)
c-objs = \
hnc3d.o \
hnc3d-sles.o \
rism-dst.o \
rism-rdf.o \
bgy3d.o \
bgy3d-force.o \
bgy3d-pure.o \
bgy3d-impure.o \
bgy3d-solvents.o \
bgy3d-solutes.o \
bgy3d-poisson.o \
bgy3d-dirichlet.o \
bgy3d-snes.o \
bgy3d-vec.o \
bgy3d-mat.o \
bgy3d-interp.o \
bgy3d-fft.o \
bgy3d-fftw3.o \
bgy3d-potential.o
ifeq ($(WITH_GUILE),1)
c-objs += bgy3d-guile.o
LIBS += $(shell guile-config link)
INCDIRS += $(shell guile-config compile)
USR-FLAGS += -DWITH_GUILE
endif
#
# There is a chicken and egg problem here. To make GFortran generate
# dependencies for Fortran files the compiler expects all *.mod files
# the source depends on to be present. The order of the files here was
# manually crafted so that a *serial* make will generate dependencies
# of Fortran modules in the proper sequence simultaneousely producing
# the *.mod files. FIXME: sill fails for parallel build as in make
# -j4.
#
f-objs += \
rism.o \
closures.o \
drism.o \
snes.o \
bessel.o \
fft.o \
linalg.o \
options.o \
foreign.o \
eos.o \
lisp.o \
units.o \
kinds.o \
lebed/lebed.o \
lebed/Lebedev-Laikov.o
OBJECTS = bgy3d-main.o
libbgy3d.a: $(libbgy3d.a)
$(AR) ruv $@ $(^)
$(RANLIB) $@
libbgy3d.so: $(libbgy3d.a)
$(CC) -shared -Wl,-soname,libbgy3d.so.1 -o libbgy3d.so.1.0 $(libbgy3d.a)
ln -sf libbgy3d.so.1.0 libbgy3d.so.1
ln -sf libbgy3d.so.1 libbgy3d.so
$(exe): $(OBJECTS) $(if $(shared), libbgy3d.so, libbgy3d.a)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) -L. -lbgy3d $(LIBS)
#
# Dont call the target "test" because we have a directory called so:
#
test-all:
$(MAKE) -C ./test
clean:
rm -f $(generated-depfiles)
rm -f *.a *.so *.o *.mod *.bin *.info
rm -f $(exe)
$(MAKE) -C test clean
distclean:
rm -f *.o *.so *.d
rm -f $(exe)
.PHONY: distclean
# Even if you issue "make clean" the uncoditional include will lead to
# attempts to rebuild the C/Fortran dependencies, that is why the
# conditional:
generated-depfiles = $(OBJECTS:.o=.d) $(libbgy3d.a:.o=.d)
ifneq ($(MAKECMDGOALS),clean)
include $(generated-depfiles)
endif
# This do-it-all rule is specific to gcc version >= 3.0, and updates
# the object file and the dependency file at the same time. The -MP
# also causes it to output empty targets for each header. Comment out
# this rule if you are using a different compiler.
# %.o %.d: %.c
# $(CC) -MT "$*.o $*.d " -MD -MP $(CFLAGS) $(LDFLAGS) $(INCDIRS) -c $<
%.d: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $(INCDIRS) -M -MF $(*).d -MP $(<)
#
# FIXME: running the command also produces the *.mod file, but no *.o
# file. Also GFortran expects the *.mod files of the prerequisites to
# exist when parsing the source:
#
%.d: %.f90
$(FC) -cpp -M -MF $(@) $(<)
%.d: %.F
touch $(@)
# The next two rules are fairly portable across compilers.
%.o: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $(INCDIRS) -o $(*).o -c $(<)
%.o %.mod: %.f90
$(FC) $(FFLAGS) -o $(*).o -c $(<)
# For lebed/Lebedev-Laikov.o only. FIXME: rename?
%.o: %.F
$(FC) $(FFLAGS) -o $(*).o -c $(<)
# Note capital D here, this rule has no effect:
%.D: %.c
set -e; $(CC) -M $(CFLAGS) $(LDFLAGS) $(INCDIRS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@
TAGS: $(OBJECTS:.o=.c) $(c-objs:.o=.c) $(f-objs:.o=.f90)
etags $(^)
tags: $(OBJECTS:.o=.c) $(c-objs:.o=.c) $(f-objs:.o=.f90)
ctags $(^)
#---End of Makefile---