forked from libprima/prima
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
136 lines (116 loc) · 4.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
cmake_minimum_required (VERSION 3.13)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
project (prima Fortran)
option (BUILD_SHARED_LIBS "shared/static" ON)
include (GNUInstallDirs)
# the compiler enables an executable stack because of nested functions and this is fine
if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU" AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
include (CheckLinkerFlag)
check_linker_flag (Fortran "-Wl,--no-warn-execstack" HAVE_WARN_EXECSTACK)
endif ()
# Set additional Fortran compiler flags
# 1. We require the compilers to allocate arrays on the heap instead of the stack, which is
# slower (does not matter for DFO applications) but can avoid memory errors on large problems.
# 2. We require the compilers to compile the solvers so that they can be called recursively.
# See https://fortran-lang.discourse.group/t/frecursive-assume-recursion-and-recursion-thread-safety
option (PRIMA_HEAP_ARRAYS "allocate arrays on heap" ON)
if (PRIMA_HEAP_ARRAYS)
if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fno-stack-arrays -frecursive")
elseif (CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
if (WIN32)
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} /heap-arrays /assume:recursion")
else ()
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -heap-arrays -assume recursion")
endif ()
elseif (CMAKE_Fortran_COMPILER_ID MATCHES "NVHPC")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Mnostack_arrays -Mrecursive")
elseif (CMAKE_Fortran_COMPILER_ID MATCHES "NAG")
set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -recursive") # What about stack/heap?
endif ()
endif ()
# Set additional linker flags
# Zaikun 20240217: Fix https://github.com/libprima/prima/issues/158, which is due to the new linker
# implemented in Xcode 15 on macOS. It happens only if the Fortran compiler is ifort.
# An alternative is `add_link_options("-ld_classic")`, which forces Xcode to use the old linker.
# Will CMake adapt itself to the new linker later? Will a newer version of CMake make the fix unnecessary?
# See
# https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#Linking
# https://stackoverflow.com/questions/77525544/apple-linker-warning-ld-warning-undefined-error-is-deprecated
# https://medium.com/@hackingwithcode/cmake-and-xcode-15-solving-the-undefined-error-puzzle-3c847e6d1008
if((APPLE) AND (CMAKE_Fortran_COMPILER_ID MATCHES "Intel"))
add_link_options("-Wl,-undefined,dynamic_lookup")
endif()
# For running tests with gdb. $_exitcode != 0 means the program ran without exiting
# normally, and in this case we want to show a stack trace
file(WRITE ${CMAKE_BINARY_DIR}/cmdfile.gdb "init-if-undefined $_exitcode = 0
run
set language c
if $_exitcode != 0
where
end
quit $_exitcode
")
option(PRIMA_ENABLE_EXAMPLES "build examples by default" OFF)
add_custom_target (examples)
enable_testing ()
option(PRIMA_ENABLE_TESTING "build tests" OFF)
add_custom_target (tests)
add_dependencies(tests examples)
add_subdirectory(fortran)
option (PRIMA_ENABLE_C "C binding" ON)
if (PRIMA_ENABLE_C)
enable_language(C)
add_subdirectory(c)
set(primac_target "primac")
endif ()
# Get the version number
find_package(Git)
if(GIT_EXECUTABLE)
# --always means git describe will output the commit hash if no tags are found
# This is usually the case for forked repos since they do not clone tags by default.
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE PRIMA_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
# If git is not available, that may indicate we are building on macports which
# downloads the bundle from github (which uses git archive) and so the version
# number should be in .git-archival.txt
file(STRINGS .git-archival.txt PRIMA_VERSION)
if(PRIMA_VERSION MATCHES "describe")
message(WARNING "No git detected and .git-archival.txt does not contain a version number")
set(PRIMA_VERSION "unknown")
endif()
endif()
# Remove the leading v from PRIMA_VERSION, if it contains one.
string(REGEX REPLACE "^v" "" PRIMA_VERSION ${PRIMA_VERSION})
message(STATUS "Setting PRIMA version to ${PRIMA_VERSION}")
install(
TARGETS primaf ${primac_target}
EXPORT prima-targets
INCLUDES DESTINATION include
)
install(
EXPORT prima-targets
FILE prima-targets.cmake
NAMESPACE prima::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/prima
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/prima-config.cmake.in
${CMAKE_BINARY_DIR}/prima-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/prima
)
write_basic_package_version_file(
${CMAKE_BINARY_DIR}/prima-config-version.cmake
VERSION ${PRIMA_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(
FILES
${CMAKE_BINARY_DIR}/prima-config.cmake
${CMAKE_BINARY_DIR}/prima-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/prima
)