-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathBioDynaMo.cmake
More file actions
250 lines (227 loc) · 12 KB
/
Copy pathBioDynaMo.cmake
File metadata and controls
250 lines (227 loc) · 12 KB
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# -----------------------------------------------------------------------------
#
# Copyright (C) 2021 CERN & University of Surrey for the benefit of the
# BioDynaMo collaboration. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
#
# See the LICENSE file distributed with this work for details.
# See the NOTICE file distributed with this work for additional information
# regarding copyright ownership.
#
# -----------------------------------------------------------------------------
# This file contains functions required to build BioDynaMo
# function get_implicit_dependencies( RET_VAR
# SOURCES source1 source2 ...)
# Returns a list of biodynamo headers that are included from a list of source
# files.
# \param RET_VAR variable in which the list of headers will be stored
# \param SOURCES list of source files that should be analyzed
function(get_implicit_dependencies RET_VAR)
cmake_parse_arguments(ARG "" "" "SOURCES" ${ARGN} )
# build include path string
get_directory_property(INCLUDE_DIRS INCLUDE_DIRECTORIES)
set(INCLUDE_OPTIONS)
foreach( DIR ${INCLUDE_DIRS})
set(INCLUDE_OPTIONS "${INCLUDE_OPTIONS} -I${DIR}")
endforeach()
# grep pattern to extract bdm headers
set(BDM_HEADER_PATTERN "^${PROJECT_SOURCE_DIR}/src/|^${PROJECT_SOURCE_DIR}/test/|^${PROJECT_SOURCE_DIR}/demo/|^src/|^test/|^demo/")
# execute shell script and store result into variable
execute_process(
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMAND cmake/get_bdm_includes.sh ${CMAKE_CXX_COMPILER} "${INCLUDE_OPTIONS}" ${BDM_HEADER_PATTERN} ${ARG_SOURCES}
OUTPUT_VARIABLE CMD_RESULT)
# return result
set(${RET_VAR} ${CMD_RESULT} PARENT_SCOPE)
endfunction(get_implicit_dependencies)
# function bdm_add_executable( TARGET
# SOURCES source1 source2 ...
# HEADERS header1 header2 ...
# LIBRARIES lib1 lib2 ...)
# BioDynaMo's version of add_executable
# This is required because ROOT dictionaries must be built beforehand.
# To make debugging of compile errors easier an object library with SOURCES
# is compiled first, then dictionaries are generated. Afterwards these
# dictionaries are compiled and linked with the object files compiled in the
# first step.
# Uses the variable `BDMSYS` to point to the cmake directory. This is
# necessary, since this function is used from within the BioDynaMo repository
# and external simulation projects.
# \param TARGET target name for the executable
# \param SOURCES list of source files
# \param LIBRARIES list of *shared* libraries that should be linked to the executable.
# can also be a target name of a library.
# STATIC libraries not compiled with -fPIC must be linked in a separate command using
# target_link_libraries(${TARGET} static-lib-wo-fpic)
function(bdm_add_executable TARGET)
cmake_parse_arguments(ARG "" "" "SOURCES;HEADERS;LIBRARIES" ${ARGN} )
if(dict)
if (OPENCL_FOUND)
# Do this here; we don't want libbiodynamo.so to contain any OpenCL symbols
set(ARG_LIBRARIES ${ARG_LIBRARIES} ${OPENCL_LIBRARIES})
endif()
if(mpi AND MPI_FOUND)
set(ARG_LIBRARIES ${ARG_LIBRARIES} ${MPI_mpi_LIBRARY})
set(ARG_LIBRARIES ${ARG_LIBRARIES} ${MPI_mpi_cxx_LIBRARY})
endif()
build_shared_library(${TARGET}
SELECTION selection.xml
HEADERS ${ARG_HEADERS}
SOURCES ${ARG_SOURCES}
LIBRARIES ${ARG_LIBRARIES})
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TARGET}-main.cc "int main(int argc, const char** argv);")
add_executable(${TARGET}-bin ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${TARGET}-main.cc)
target_link_libraries(${TARGET}-bin ${TARGET})
if (LINUX)
set_target_properties(${TARGET}-bin PROPERTIES LINK_FLAGS "-Wl,-rpath,$ORIGIN")
else()
set_target_properties(${TARGET}-bin PROPERTIES LINK_FLAGS "-Wl,-rpath,@loader_path")
endif()
set_target_properties(${TARGET}-bin PROPERTIES OUTPUT_NAME ${TARGET})
else()
add_executable(${TARGET} ${ARG_SOURCES})
target_link_libraries(${TARGET} ${ARG_LIBRARIES})
endif()
endfunction(bdm_add_executable)
# function build_shared_library( TARGET
# SELECTION selection.xml
# SOURCES source1 source2 ...
# HEADERS header1 header2 ...
# LIBRARIES lib1 lib2 ...
# PLUGIN <"TRUE">)
# build shared library with ROOT dictionaries. If ARG_PLUGIN is set, we will
# always generate dictionaries (as required by ROOT's plugin manager)
function(build_shared_library TARGET)
cmake_parse_arguments(ARG "" "" "SELECTION;SOURCES;HEADERS;LIBRARIES;PLUGIN" ${ARGN} )
# We always need dictionaries for the plugins (plugin manager requires class
# information)
if(dict OR DEFINED ARG_PLUGIN)
# generate dictionary using rootcling reflex
set(DICT_FILE "${CMAKE_CURRENT_BINARY_DIR}/lib${TARGET}_dict")
set(BDM_DICT_FILE "${CMAKE_CURRENT_BINARY_DIR}/lib${TARGET}_bdm_dict.cc")
set(ROOT_HEADERS)
string(REPLACE "${CMAKE_SOURCE_DIR}/src/" "" ROOT_HEADERS_TEMP "${ARG_HEADERS}")
string(REPLACE "${CMAKE_SOURCE_DIR}/test/" "" ROOT_HEADERS "${ROOT_HEADERS_TEMP}")
if (runtime_cxxmodules)
set(MODULEMAP "--moduleMapFile=${CMAKE_BINARY_DIR}/include/module.modulemap")
else()
set(NO_MODULE "NO_CXXMODULE")
endif()
if (NOT ${TARGET} STREQUAL "biodynamo")
#set(DEPENDENCY_OPTION "-m ${CMAKE_CURRENT_BINARY_DIR}/lib/biodynamo.pcm")
#set(NO_MODULE "NO_CXXMODULE")
#set(MODULEMAP)
endif()
# Since the location of the CMake files differ in the build and installation
# directory, we check if BDM_CMAKE_DIR is already set (in build directory
# case). Otherwise, set it to the installation directory
if(NOT DEFINED BDM_CMAKE_DIR)
set(BDM_CMAKE_DIR $ENV{BDMSYS}/share/cmake)
endif()
ROOT_GENERATE_DICTIONARY(${DICT_FILE} ${ROOT_HEADERS} MODULE ${TARGET} LINKDEF ${BDM_CMAKE_DIR}/${ARG_SELECTION} REFLEX ${NO_MODULE} OPTIONS ${DEPENDENCY_OPTION} -I src --inlineInputHeader --noIncludePaths ${MODULEMAP})
if (BDM_OUT_OF_SOURCE)
set(BDM_DICT_BIN_PATH "$ENV{BDMSYS}/bin")
else()
set(BDM_DICT_BIN_PATH "${PROJECT_SOURCE_DIR}/cmake")
endif()
get_property(INCLUDE_DIRS DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
if (BDM_OUT_OF_SOURCE)
set(BDM_OUT_OF_SRC_ARG "--out-of-source")
else()
set(BDM_OUT_OF_SRC_ARG --bdm-source ${CMAKE_SOURCE_DIR})
endif()
if (BDM_CXXMODULES)
set(BDM_CXX_MODULES_ARG "--cxxmodules")
endif()
add_custom_command(OUTPUT "${BDM_DICT_FILE}"
COMMAND ${Python_EXECUTABLE} ${BDM_DICT_BIN_PATH}/bdm-dictionary ${BDM_OUT_OF_SRC_ARG} ${BDM_CXX_MODULES_ARG} --output ${BDM_DICT_FILE} --include-dirs ${INCLUDE_DIRS} --headers ${ARG_HEADERS}
DEPENDS ${ARG_HEADERS} ${BDM_DICT_BIN_PATH}/bdm-dictionary)
# generate shared library
add_library(${TARGET} SHARED ${ARG_SOURCES} ${DICT_FILE}.cc ${BDM_DICT_FILE})
if (OPENCL_FOUND)
target_compile_definitions(${TARGET} PUBLIC -DUSE_OPENCL)
endif()
target_link_libraries(${TARGET} ${ARG_LIBRARIES})
if (DEFINED CMAKE_INSTALL_LIBDIR)
# add_custom_command(TARGET ${TARGET}
# POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy ${DICT_FILE}_rdict.pcm ${CMAKE_INSTALL_LIBDIR})
endif()
else()
add_library(${TARGET} SHARED ${ARG_SOURCES})
target_link_libraries(${TARGET} ${ARG_LIBRARIES})
endif()
endfunction(build_shared_library)
# function generate_rootlogon
# generates rootlogon.C which is required by ROOT's C++ interpreter cling
function(generate_rootlogon)
get_directory_property(INCLUDE_DIRS INCLUDE_DIRECTORIES)
set(INCLUDE_OPTIONS)
set(CONTENT "{")
# if USE_DICT is set for libbiodynamo.so, we also need to set it for rootcling
# when we want to use the interpreter or notebooks. Otherwise there would break
# the one-definition rule
if(real_t)
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"#define BDM_REALT ${real_t}\")\;")
endif()
if (dict)
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"#define USE_DICT\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"R__ADD_INCLUDE_PATH($BDMSYS/include)\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"R__ADD_LIBRARY_PATH($BDMSYS/lib)\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"R__LOAD_LIBRARY(libbiodynamo)\")\;")
# We add this one because the ROOT visualization require it, and it's not one
# of the core libraries that is loaded by default in rootcling
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"R__LOAD_LIBRARY(GenVector)\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"#include \\\"biodynamo.h\\\"\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"using namespace bdm\;\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"Simulation simulation(\\\"simulation\\\")\;\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"cout << \\\"INFO: Created simulation object 'simulation' with UniqueName='simulation'.\\\" << endl\;\")\;")
else()
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"cout << \\\"ERROR: Loading BioDynaMo into ROOT failed!\\\" << endl\;\")\;")
set(CONTENT "${CONTENT}\n gROOT->ProcessLine(\"cout << \\\" BioDynaMo was not built with dict=ON\\\" << endl\;\")\;")
endif()
set(CONTENT "${CONTENT}\n}\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/rootlogon.C" ${CONTENT})
endfunction(generate_rootlogon)
# Fix for rootcling not able to find omp.h. We cannot include the entire include
# directory of the compiler (where omp.h is in), because rootcling starts using
# the intrinsics found in there. Therefore we do a local copy into the build dir.
function(fix_rootcling_omp_issue)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=include/omp.h
OUTPUT_VARIABLE OMP_HEADER_PATH)
# above command returns path with "\n" appended
string(REGEX REPLACE "\n$" "" OMP_HEADER_PATH "${OMP_HEADER_PATH}")
if ("${OMP_HEADER_PATH}" STREQUAL "include/omp.h")
if(EXISTS "${CMAKE_SOURCE_DIR}/third_party/omp/omp.h")
execute_process(COMMAND cp -a ${CMAKE_SOURCE_DIR}/third_party/omp ${CMAKE_BINARY_DIR})
elseif(EXISTS "$ENV{BDMSYS}/third_party/omp/omp.h")
execute_process(COMMAND cp -a $ENV{BDMSYS}/third_party/omp ${CMAKE_BINARY_DIR})
elseif(EXISTS "$ENV{BDMSYS}/omp/omp.h")
execute_process(COMMAND cp -a $ENV{BDMSYS}/omp ${CMAKE_BINARY_DIR})
else()
message(FATAL_ERROR "The BioDynaMo environment is not set up correctly. Please execute 'source <path-to-bdm-installation>/bin/thisbdm.sh' and retry this command.")
endif()
else()
execute_process(COMMAND mkdir -p ${CMAKE_BINARY_DIR}/omp)
execute_process(COMMAND cp -f ${OMP_HEADER_PATH} ${CMAKE_BINARY_DIR}/omp)
endif()
include_directories("${CMAKE_BINARY_DIR}/omp")
endfunction(fix_rootcling_omp_issue)
# Fix to be able to find opencl C++ include file cl2.hpp. On macOS this include
# is missing so we should make sure it is available during compilation on macOS.
function(fix_macos_opencl_header_issue)
if (APPLE)
if(EXISTS "${CMAKE_SOURCE_DIR}/third_party/opencl/cl2.hpp")
execute_process(COMMAND cp -a ${CMAKE_SOURCE_DIR}/third_party/opencl ${CMAKE_BINARY_DIR})
elseif(EXISTS "$ENV{BDMSYS}/third_party/opencl/cl2.hpp")
execute_process(COMMAND cp -a $ENV{BDMSYS}/third_party/opencl ${CMAKE_BINARY_DIR})
elseif(EXISTS "$ENV{BDMSYS}/opencl/cl2.hpp")
execute_process(COMMAND cp -a $ENV{BDMSYS}/opencl ${CMAKE_BINARY_DIR})
else()
message(FATAL_ERROR "The BioDynaMo environment is not set up correctly. Please execute 'source <path-to-bdm-installation>/bin/thisbdm.sh' and retry this command.")
endif()
include_directories("${CMAKE_BINARY_DIR}/opencl")
endif()
endfunction(fix_macos_opencl_header_issue)