-
Notifications
You must be signed in to change notification settings - Fork 3
/
CMakeLists.txt
229 lines (194 loc) · 7.56 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
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
cmake_minimum_required(VERSION 3.11)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
project(surfex LANGUAGES Fortran)
set(SURFEX_VERSION_MAJOR 8)
set(SURFEX_VERSION_BUGFIX 1)
option(INSPECT_MASTER_SOURCES "check main source files tree for top-level routines" OFF)
option(ENABLE_MPI "enable MPI" OFF)
option(ENABLE_OMP "enable OpenMP" OFF)
option(ENABLE_XIOS "use XIOS library for parallel IO" OFF)
option(ENABLE_OASIS "use OASIS3-MCT coupler" OFF)
if(ENABLE_OASIS AND NOT ENABLE_MPI)
message(FATAL_ERROR "OASIS3-MCT coupler requires MPI")
endif()
if(ENABLE_XIOS)
message(FATAL_ERROR "Not implemented yet")
endif()
option(MANGLE_SURFEX_BINARIES "add to executables a suffix based on build configuration" OFF)
option(BUILD_GRIB_API "build a copy of grib_api library provided with SURFEX" ON)
option(BUILD_NETCDF "build a copy of netcdf library provided with SURFEX" ON)
option(BUILD_XIOS "build a copy of XIOS io server library provided with SURFEX" OFF)
option(USE_ECCODES "use eccodes library for reading GRIB files" OFF)
if(USE_ECCODES AND BUILD_GRIB_API)
message(FATAL_ERROR "Can not use eccodes if internal GRIB API library is requested")
endif()
set(USER_SOURCES_DIR "" CACHE PATH "Path to directory with user-provided source files")
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "CMAKE_BUILD_TYPE is not set, switching to RELEASE")
set(CMAKE_BUILD_TYPE "RELEASE" CACHE STRING
"Choose the type of build, options are: NONE DEBUG RELEASE."
FORCE)
endif()
set(CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/conf/config.${CMAKE_Fortran_COMPILER_ID}.cmake")
if(EXISTS ${CONFIG_FILE} AND NOT IS_DIRECTORY ${CONFIG_FILE})
message(STATUS "Using ${CONFIG_FILE}")
include(${CONFIG_FILE})
else()
message(FATAL_ERROR "Unable to load config ${CONFIG_FILE}")
endif()
include(GNUInstallDirs)
include(Dependencies)
include(InspectSources)
function(list_sources dir sources)
set(endings "*.F90" "*.F")
if(NOT WIN32 AND NOT CYGWIN AND NOT MINGW)
list(APPEND endings "*.f90" "*.f")
endif()
set(result ${${sources}})
foreach(item ${endings})
file(GLOB sources_chunk "${dir}/${item}")
list(APPEND result ${sources_chunk})
endforeach(item)
set(${sources} ${result} PARENT_SCOPE)
endfunction(list_sources)
function(build_sources_master sources programs)
set(ALL_FORTRAN_SOURCES "")
list_sources("src/ASSIM" ALL_FORTRAN_SOURCES)
list_sources("src/SURFEX" ALL_FORTRAN_SOURCES)
list_sources("src/LIB/TOPD" ALL_FORTRAN_SOURCES)
list_sources("src/LIB/GELATO" ALL_FORTRAN_SOURCES)
list_sources("src/LIB/DRHOOK/BYPASS" ALL_FORTRAN_SOURCES)
list_sources("src/OFFLIN" ALL_FORTRAN_SOURCES)
set(MAIN_PROGRAMS
"oi_main"
"soda"
"varassim"
"ncpost"
"offline"
"pgd"
"prep"
"sxpost" )
set(FORTRAN_SOURCES "")
set(FORTRAN_PROGRAMS "")
foreach(item ${ALL_FORTRAN_SOURCES})
get_filename_component(current "${item}" NAME_WE)
list(FIND MAIN_PROGRAMS "${current}" found)
if(found EQUAL -1)
list(APPEND FORTRAN_SOURCES "${item}")
else()
list(APPEND FORTRAN_PROGRAMS "${item}")
endif()
endforeach(item)
set(${sources} ${FORTRAN_SOURCES} PARENT_SCOPE)
set(${programs} ${FORTRAN_PROGRAMS} PARENT_SCOPE)
endfunction(build_sources_master)
function(merge_user_sources user_dir_arg master user)
set(current_user_dir ${${user_dir_arg}})
set(master_sources ${${master}})
set(user_sources ${${user}})
set(result "")
foreach(item ${master_sources})
get_filename_component(current_master "${item}" NAME)
list(FIND user_sources "${current_user_dir}/${current_master}" found)
if(found EQUAL -1)
list(APPEND result "${item}")
else()
list(APPEND result "${current_user_dir}/${current_master}")
list(REMOVE_ITEM user_sources "${current_user_dir}/${current_master}")
endif()
endforeach()
list(APPEND result "${user_sources}")
set(${master} "${result}" PARENT_SCOPE)
endfunction()
function(get_mangled_name base_name mangled_name)
set(output "${base_name}-V${SURFEX_VERSION_MAJOR}-${SURFEX_VERSION_BUGFIX}")
if(USER_SOURCES_DIR)
set(output "${output}${USER_SOURCES_SUFFIX}")
else()
set(output "${output}-MASTER")
endif()
set(output "${output}-${CMAKE_BUILD_TYPE}-${CMAKE_Fortran_COMPILER_ID}")
if(ENABLE_OMP)
set(output "${output}-OMP")
endif()
if(ENABLE_MPI)
set(output "${output}-MPI")
endif()
string(TOUPPER "${output}" output)
set(${mangled_name} "${output}" PARENT_SCOPE)
endfunction()
build_sources_master(FORTRAN_SOURCES FORTRAN_PROGRAMS)
# Check source files for top-level routines in the master tree
if(INSPECT_MASTER_SOURCES)
find_top_level_routines("${FORTRAN_SOURCES}")
endif()
if(USER_SOURCES_DIR)
set(USER_SOURCES_SUFFIX "")
foreach(user_dir IN LISTS USER_SOURCES_DIR)
message(STATUS "User source directory: ${user_dir}")
get_filename_component(
user_dir "${user_dir}" ABSOLUTE
BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
if(IS_DIRECTORY "${user_dir}")
set(USER_SOURCES "")
list_sources(${user_dir} USER_SOURCES)
find_top_level_routines("${USER_SOURCES}" USER_PROGRAMS)
if(USER_PROGRAMS)
list(REMOVE_ITEM USER_SOURCES ${USER_PROGRAMS})
merge_user_sources(user_dir FORTRAN_PROGRAMS USER_PROGRAMS)
endif()
merge_user_sources(user_dir FORTRAN_SOURCES USER_SOURCES)
get_filename_component(user_sources_id "${user_dir}" NAME)
set(USER_SOURCES_SUFFIX "${USER_SOURCES_SUFFIX}-${user_sources_id}")
endif()
endforeach()
endif()
add_library( surfex-static STATIC ${FORTRAN_SOURCES})
set_target_properties(surfex-static PROPERTIES OUTPUT_NAME "surfex")
if(${BUILD_NETCDF})
add_dependencies(surfex-static ${LOCAL_NETCDF})
endif(${BUILD_NETCDF})
if(${BUILD_GRIB_API})
add_dependencies(surfex-static ${LOCAL_GRIB_API})
endif(${BUILD_GRIB_API})
set_target_properties(surfex-static PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/mod)
target_include_directories(surfex-static PUBLIC ${CMAKE_BINARY_DIR}/mod)
target_compile_definitions(surfex-static PUBLIC -Din_surfex)
target_compile_definitions(surfex-static PUBLIC -DSFX_BIN)
target_compile_definitions(surfex-static PUBLIC -DSFX_TXT)
target_compile_definitions(surfex-static PUBLIC -DSFX_OL)
target_compile_definitions(surfex-static PUBLIC -DSFX_NC)
target_compile_definitions(surfex-static PUBLIC -DSFX_ASC)
target_compile_definitions(surfex-static PUBLIC -DUSE_SODA)
if(ENABLE_OMP)
target_link_libraries(surfex-static PUBLIC OpenMP::OpenMP_Fortran)
endif()
if(ENABLE_MPI)
target_compile_definitions(surfex-static PUBLIC "-DSFX_MPI")
target_link_libraries(surfex-static PUBLIC MPI::MPI_Fortran)
endif()
if(ENABLE_OASIS)
add_dependencies(surfex-static oasis)
target_compile_definitions(surfex-static PUBLIC "-DCPLOASIS")
target_link_libraries(surfex-static PUBLIC oasis::oasis)
endif()
target_link_libraries(surfex-static PUBLIC NetCDF::NetCDF_Fortran)
if(USE_ECCODES)
target_link_libraries(surfex-static PUBLIC eccodes::eccodes_Fortran)
else()
target_link_libraries(surfex-static PUBLIC grib_api::grib_api_Fortran)
endif()
foreach(item ${FORTRAN_PROGRAMS})
get_filename_component(current "${item}" NAME_WE)
if(MANGLE_SURFEX_BINARIES)
get_mangled_name("${current}" program_name)
else()
string(TOUPPER "${current}" program_name)
endif()
add_executable(${current} "${item}")
set_target_properties(${current} PROPERTIES OUTPUT_NAME "${program_name}")
target_link_libraries(${current} surfex-static)
install(TARGETS ${current} DESTINATION bin)
set_property(TARGET ${current} APPEND PROPERTY
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/surfex/lib")
endforeach(item)