-
Notifications
You must be signed in to change notification settings - Fork 1
/
CMakeLists.txt
190 lines (146 loc) · 6.96 KB
/
CMakeLists.txt
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
# Specify the minimum version
# 3.9 required for regex submatches
# 3.12 required for policy CMP0074 (using *_ROOT variables)
cmake_minimum_required ( VERSION 3.12 )
# Reconfigure if Project.toml has changed
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/LibTrixi.jl/Project.toml")
# Get project version from LibTrixi.jl
file(READ "${CMAKE_SOURCE_DIR}/LibTrixi.jl/Project.toml" libtrixi_project_toml)
# Parse string
if (${libtrixi_project_toml} MATCHES "version = \"(([0-9]+)\\.([0-9]+)\\.([0-9]+)([+-]([A-Za-z0-9_-]+))?)\"")
set(LIBTRIXI_VERSION ${CMAKE_MATCH_1})
set(LIBTRIXI_VERSION_MAJOR ${CMAKE_MATCH_2})
set(LIBTRIXI_VERSION_MINOR ${CMAKE_MATCH_3})
set(LIBTRIXI_VERSION_PATCH ${CMAKE_MATCH_4})
set(LIBTRIXI_VERSION_PRERELEASE ${CMAKE_MATCH_6})
else()
message(FATAL_ERROR "Unable to parse version from LibTrixi.jl/Project.toml")
endif()
file(WRITE "${CMAKE_BINARY_DIR}/LIBTRIXI_VERSION" "${LIBTRIXI_VERSION}\n")
# Specify the project info.
project ( trixi VERSION ${LIBTRIXI_VERSION_MAJOR}.${LIBTRIXI_VERSION_MINOR}.${LIBTRIXI_VERSION_PATCH}
DESCRIPTION "Interface library for using Trixi.jl from C/C++/Fortran" )
# Enable C and Fortran
enable_language(C Fortran)
# Enabling setting rpath for installation
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# Additional cmake modules
list ( APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" )
# Find Julia
find_package( Julia REQUIRED )
# Find t8code
find_package( T8CODE CONFIG )
if ( NOT T8CODE_FOUND )
message( NOTICE "t8code not found: t8code examples will NOT be built")
endif()
# Find MPI
find_package( MPI REQUIRED )
# Find Google Test and test-drive on demand
option( ENABLE_TESTING "Build tests using Google Test (C) and test-drive (Fortran)" )
if( ENABLE_TESTING )
if ( NOT DEFINED JULIA_PROJECT_PATH )
message( FATAL_ERROR "JULIA_PROJECT_PATH not set, tests will not work.")
endif()
set( JULIA_PROJECT_PATH ${JULIA_PROJECT_PATH} CACHE PATH
"Path to Julia project (typically 'libtrixi-julia').")
find_package( GTest REQUIRED )
set ( TEST_DRIVE_FIND_METHOD fetch )
# Option TEST_DRIVE_BUILD_TESTING is hard-coded to ON, could be spared
find_package( test-drive REQUIRED )
endif()
# Optionally use PackageCompiler.jl to build standalone libtrixi.so
option( USE_PACKAGE_COMPILER "Build standalone libtrixi.so using PackageCompiler.jl" )
# Fortran mod file location
set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR})
if( USE_PACKAGE_COMPILER )
if ( NOT DEFINED JULIA_PROJECT_PATH )
message( FATAL_ERROR "JULIA_PROJECT_PATH needs to be set for PackageCompiler.jl.")
endif()
if ( ENABLE_TESTING )
message( NOTICE "Testing is not supported when PackageCompiler is used.")
endif()
# Define PackageCompiler.jl output file
set( PC_LIBTRIXI_SO ${CMAKE_BINARY_DIR}/prefix-pc/lib/libtrixi.so )
# Define PackageCompiler.jl initialization source file
set( PC_INIT_SOURCE ${CMAKE_SOURCE_DIR}/LibTrixi.jl/lib/init.c )
set( PC_INIT_BUILD ${CMAKE_BINARY_DIR}/build-pc/init.c )
# Copy initialization source to build directory
add_custom_command( OUTPUT ${PC_INIT_BUILD}
COMMENT "Copying `init.c` to build folder..."
COMMAND ${CMAKE_COMMAND} -E copy ${PC_INIT_SOURCE} ${PC_INIT_BUILD}
DEPENDS ${PC_INIT_SOURCE} )
# Add a library target (libtrixi), only for Fortran module
add_library( ${PROJECT_NAME} OBJECT
src/api.f90
)
# Custom command to run PackageCompiler.jl to produce libtrixi.so
add_custom_command( OUTPUT ${PC_LIBTRIXI_SO}
COMMENT "Building ${PROJECT_NAME} with PackageCompiler.jl..."
COMMAND ${JULIA_EXECUTABLE}
--project=${CMAKE_SOURCE_DIR}/LibTrixi.jl/lib
${CMAKE_SOURCE_DIR}/LibTrixi.jl/lib/build.jl
${JULIA_PROJECT_PATH}
${CMAKE_BINARY_DIR}/prefix-pc
DEPENDS ${PC_INIT_BUILD}
${CMAKE_SOURCE_DIR}/LibTrixi.jl/lib/build.jl
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/build-pc )
# Custom target for PackageCompiler.jl's libtrixi.so
add_custom_target( PC_LIBTRIXI DEPENDS ${PC_LIBTRIXI_SO} )
# Dependency of main library target on PackageCompiler.jl target
add_dependencies( ${PROJECT_NAME} PC_LIBTRIXI )
# Add linking to PackageCompiler.jl's libtrixi.so
target_link_libraries( ${PROJECT_NAME} INTERFACE ${PC_LIBTRIXI_SO} )
# Install configuration
install( DIRECTORY "${CMAKE_BINARY_DIR}/prefix-pc/lib/" TYPE LIB )
install( DIRECTORY "${CMAKE_BINARY_DIR}/prefix-pc/share/julia"
DESTINATION share )
else()
# Library target
add_library ( ${PROJECT_NAME} SHARED
src/api.c
src/api.f90
src/auxiliary.h
src/auxiliary.c
src/trixi.h
)
# Include directories, private
target_include_directories ( ${PROJECT_NAME} PRIVATE src )
# Version info
set_target_properties ( ${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} )
# Version info for the shared object
set_target_properties ( ${PROJECT_NAME} PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR} )
# Include directories
target_include_directories( ${PROJECT_NAME} PRIVATE src ${JULIA_INCLUDE_DIRS} )
# Libraries to link
target_link_libraries( ${PROJECT_NAME} PRIVATE ${JULIA_LIBRARY} )
# Set appropriate compile flags
target_compile_options( ${PROJECT_NAME} PUBLIC "-fPIC" )
target_compile_options( ${PROJECT_NAME} PRIVATE -Wall -Wextra -Werror)
# Require C11 standard with GNU extensions for C files
target_compile_options( ${PROJECT_NAME} PRIVATE $<$<COMPILE_LANGUAGE:C>:-std=gnu11>)
# Require Fortran 2018 standard for Fortran files
target_compile_options( ${PROJECT_NAME} PRIVATE $<$<COMPILE_LANGUAGE:Fortran>:-std=f2018>)
# Add auxiliary *object* library to support fast thread-local storage (TLS)
add_library ( ${PROJECT_NAME}_tls OBJECT
src/tls.c
)
target_include_directories( ${PROJECT_NAME}_tls PRIVATE ${JULIA_INCLUDE_DIRS} )
# Add test on demand
if( ENABLE_TESTING )
enable_testing()
add_subdirectory( test/c )
add_subdirectory( test/fortran )
endif()
# Install configuration
install( FILES $<TARGET_OBJECTS:${PROJECT_NAME}_tls> TYPE LIB RENAME lib${PROJECT_NAME}_tls.o )
install( FILES "${CMAKE_BINARY_DIR}/LIBTRIXI_VERSION" DESTINATION share/julia )
endif()
# Public header for libtrixi
set_target_properties ( ${PROJECT_NAME} PROPERTIES PUBLIC_HEADER src/trixi.h )
# Common install configuration
install( TARGETS ${PROJECT_NAME} )
install( DIRECTORY LibTrixi.jl DESTINATION share/libtrixi PATTERN "lib" EXCLUDE )
install( FILES ${CMAKE_Fortran_MODULE_DIRECTORY}/libtrixi.mod TYPE INCLUDE)
install( PROGRAMS utils/libtrixi-init-julia TYPE BIN )
# Add examples
add_subdirectory( examples )