-
Notifications
You must be signed in to change notification settings - Fork 4
/
CMakeLists.txt
392 lines (337 loc) · 13.7 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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# Support for the CMake of the oldest supported Ubuntu LTS
cmake_minimum_required(VERSION 3.16.3)
# Get project version from the cpp file
file(READ "src/Learning/KWUtils/KWKhiopsVersion.h" CPP_FILE)
string(REGEX MATCH "#define KHIOPS_VERSION KHIOPS_STR\\(([^)]*)\\)" _ ${CPP_FILE})
set(KHIOPS_VERSION ${CMAKE_MATCH_1})
string(REGEX REPLACE "-.*" "" VERSION ${KHIOPS_VERSION})
message(STATUS "Building Khiops Version: ${KHIOPS_VERSION} (CMake version : ${VERSION})")
# Specify the project's language to C++
project(
Khiops
LANGUAGES CXX
VERSION ${VERSION}
HOMEPAGE_URL "https://khiops.org")
# Specify CMake policies
cmake_policy(SET CMP0015 NEW)
cmake_policy(SET CMP0048 NEW)
cmake_policy(SET CMP0053 NEW)
cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0058 NEW)
cmake_policy(SET CMP0063 NEW)
cmake_policy(SET CMP0083 NEW)
# Do not add warning flags for MSVC cmake_policy(SET CMP0092 NEW)
# Warn about in-source builds
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(
FATAL_ERROR
"Do not build in-source. Please remove CMakeCache.txt and the CMakeFiles/ directory. Then build out-of-source.")
endif()
# Set the build type to Debug if not set
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif(NOT CMAKE_BUILD_TYPE)
# Remove always the files from a precedent installation
set(CMAKE_INSTALL_ALWAYS TRUE)
# Set up the custom configuration options (if customisation is required, update the options in CMakePresets.json)
option(MPI "Use MPI libraries (ON,OFF)" ON)
option(TESTING "Build unit tests (ON,OFF)" ON)
option(BUILD_LEX_YACC "Re-generate parsing files with lex & yacc" OFF)
option(BUILD_JARS "Re-generate norm.jar and khiops.jar" OFF)
option(GENERATE_VIEWS "Generate views sources from dd files" OFF)
option(C11 "Build whith C++11 libraries (ON,OFF)" ON)
# Print the options
message("\nKhiops build options:\n")
message(" CMAKE_BUILD_TYPE=\"${CMAKE_BUILD_TYPE}\"")
message(" MPI=\"${MPI}\"")
message(" TESTING=\"${TESTING}\"")
message(" C11=\"${C11}\"")
message(" BUILD_LEX_YACC=\"${BUILD_LEX_YACC}\"")
message(" BUILD_JARS=\"${BUILD_JARS}\"")
message(" GENERATE_VIEWS=\"${GENERATE_VIEWS}\"")
message("\n")
# Check if the os is a linux fedora-like distro (CentOS, Rocky etc...)
#
# The good way to do this is to use cmake_host_system_information but the the os-name is avalaible starting from the
# cmake version 3.22. Below, we just grep 'fedora' on /etc/os-release file. It is present on the line ID_LIKE="rhel
# centos fedora"
set(IS_FEDORA_LIKE false)
if(EXISTS "/etc/os-release")
file(READ "/etc/os-release" OS_RELEASE)
string(FIND "${OS_RELEASE}" "fedora" FEDORA_FOUND)
if(FEDORA_FOUND GREATER -1)
set(IS_FEDORA_LIKE true)
endif()
endif()
# Check if it is conda environment
set(IS_CONDA false)
if(DEFINED ENV{CONDA_PREFIX})
set(IS_CONDA true)
message(STATUS "Auto-detected conda environment")
endif()
if(IS_CONDA AND MPI)
if(NOT DEFINED ENV{mpi})
message(
WARNING "You are building in a conda environment without using `conda build`. find_mpi may not work as expected.")
endif()
endif()
# On Fedora distros, the binaries compiled with mpi must be located under the mpi location furthermore they have to be
# suffixed by the name of the mpi implementation. These 2 items are given by MPI_BIN and MPI_SUFFIX when the module
# environment is loaded source /etc/profile.d/modules.sh module load mpi/mpich-x86_64
if(IS_FEDORA_LIKE AND NOT IS_CONDA)
if(DEFINED ENV{MPI_BIN})
set(MPI_BIN $ENV{MPI_BIN})
else()
message(
FATAL_ERROR
"MPI_BIN is not defined, you have to load the mpi module e.g.:\n source /etc/profile.d/modules.sh && module load mpi/mpich-x86_64"
)
endif(DEFINED ENV{MPI_BIN})
if(DEFINED ENV{MPI_SUFFIX})
set(MPI_SUFFIX $ENV{MPI_SUFFIX})
else()
message(
FATAL_ERROR
"MPI_SUFFIX is not defined, you have to load the mpi module e.g.:\n source /etc/profile.d/modules.sh && module load mpi/mpich-x86_64"
)
endif(DEFINED ENV{MPI_SUFFIX})
endif(IS_FEDORA_LIKE AND NOT IS_CONDA)
# Set the location of the built artifacts:
#
# - Shared and static library target directory: lib
# - Executable target directory: bin
# - We must use these weird generator expressions to avoid the Debug and Release directories in VS
# - More info: https://stackoverflow.com/q/47175912
#
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/lib/>)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/lib/>)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/bin/>)
message(STATUS "Executables will be stored in ${CMAKE_BINARY_DIR}/bin/")
message(STATUS "Libraries will be stored in ${CMAKE_BINARY_DIR}/lib/")
# Temporary directory used in install and packaging steps
set(TMP_DIR ${PROJECT_BINARY_DIR}/tmp)
# Set module path for the project
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/packaging" ; "${CMAKE_CURRENT_SOURCE_DIR}/scripts")
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# Force clang to use RTTI on Debug
if(CMAKE_BUILD_TYPE EQUAL "Debug")
set(LLVM_REQUIRES_RTTI 1)
endif()
# Process dependencies: Find MPI if required
if(MPI)
find_package(MPI 2.0 REQUIRED)
message(
STATUS
"MPI command line: ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS"
)
endif()
# Detects the mpi implementation
if(UNIX AND MPI)
include(get_mpi_implementation)
get_mpi_implementation()
# Set MPI suffix if it is not defined with the environment variables (like on Fedora distros)
if(NOT MPI_SUFFIX AND MPI_IMPL)
set(MPI_SUFFIX "_${MPI_IMPL}")
endif()
endif()
# Set C++ revision globally if required
if(TESTING)
# Google test requires C++14
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
elseif(C11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
# Find Bison/Flex if required
if(BUILD_LEX_YACC)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
endif()
# Find Java if required
if(BUILD_JARS)
find_package(Java REQUIRED COMPONENTS Development)
include(UseJava)
set(KHIOPS_BUILD_JAR_DIR "${CMAKE_BINARY_DIR}/jars")
message(STATUS "Java JARs will be stored at ${KHIOPS_BUILD_JAR_DIR}")
# Note: For final builds we recommend to use java 1.8 to ensure that the jar is compatible with all posterior java
# versions (from # 1.8 to the most recent ones). The following setting accomplish that:
#
# - find_package(Java 1.8 EXACT REQUIRED COMPONENTS Development)
endif()
# Check for support of position independent code/executable
include(CheckPIESupported)
check_pie_supported()
# Message the current C++ configuration
message(STATUS "CMake generator is: ${CMAKE_GENERATOR}")
message(STATUS "CMake compiler is: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CMake C++ standard is: ${CMAKE_CXX_STANDARD}")
# MSVC: Eliminate some options the old CMake way because VS sets them with undesired default values
#
# - the C++ exception flags
# - the runtime information flags
# - the debug information generation flags
#
if(MSVC)
string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
endif()
# Sets the compiling options for Khiops
function(set_khiops_options target)
# Show the current target information
get_target_property(target_type ${target} TYPE)
message(STATUS "Setting up ${target_type} ${target}")
# General compiler properties and definitions
set_property(TARGET ${target} PROPERTY POSITION_INDEPENDENT_CODE TRUE)
target_compile_definitions(${target} PRIVATE UNICODE _UNICODE)
if(MPI)
target_compile_definitions(${target} PRIVATE USE_MPI)
endif()
target_compile_definitions(${target} PRIVATE $<$<CONFIG:RELEASE,RELWITHDEBINFO>:NOALL>)
target_compile_definitions(${target} PRIVATE $<$<CONFIG:RELWITHDEBINFO>:__ALPHA__>)
# Delegate to specialized function for Windows and Unix-like
if(MSVC)
set_msvc_khiops_options(${target})
else()
set_unix_khiops_options(${target})
endif()
endfunction(set_khiops_options)
# Sets the compiling options for unix environments
function(set_unix_khiops_options target)
# Improve size optimisation, to ckeck, MinSizeRel is perhaps enough with -Os
if(CMAKE_BUILD_TYPE MATCHES MinSizeRel)
target_link_options(${target} PRIVATE "LINKER:--gc-sections")
target_compile_options(${target} PRIVATE -ffunction-sections -fdata-sections)
endif()
# Do not include RPATHs in the build tree (Debian policy).
set(CMAKE_SKIP_BUILD_RPATH TRUE)
# Hardening (mandatory by debian policy)
#
# - relro: (relocation read-Only linking) the linker resolves all dynamically linked functions at the beginning of the
# execution
# - noexecstack: do not use executable stack
#
if(NOT APPLE) # TODO bring back macOS to hardening
target_link_options(${target} PRIVATE "LINKER:SHELL:-z noexecstack" "LINKER:SHELL:-z relro")
endif()
# Stripping only in Linux + Release (-s is not supported in macOS)
if(NOT APPLE)
target_link_options(${target} PRIVATE $<$<CONFIG:RELEASE>:-s>)
endif()
#
# - fno-rtti: no run-time type information in Release or RelWithDebInfo .
# - fno-exceptions: disables exceptions support
#
target_compile_options(${target} PRIVATE $<$<CONFIG:RELEASE,RELWITHDEBINFO>:-fno-rtti> -fno-exceptions)
# Disable "floating-point expression contraction" on clang and gcc to improve reproducibility beetween x86_64 and
# arm64
target_compile_options(${target} PRIVATE -ffp-contract=off)
endfunction(set_unix_khiops_options)
# Sets the compiling options for MSVC
function(set_msvc_khiops_options target)
# General options:
#
# - /W4: Show warnings up to level 4.
# - /MP: Build with multiple processes.
# - /EHs-c-: C++ Exceptions fully dissabled.
#
target_compile_options(${target} PRIVATE /W4 /MP /EHs-c-)
# Debug only compiling options
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
# Definitions
target_compile_definitions(${target} PRIVATE _DEBUG _CONSOLE)
# Options
#
# - /RTC1: Enable run-time error checks.
# - /ZI: Generates "Format Database for 'Edit and Continue'" debug information format.
# - /MTd: Use multithread debug runtime (set via MSVC_RUNTIME_LIBRARY property).
#
target_compile_options(${target} PRIVATE /RTC1 /ZI)
set_target_properties(${target} PROPERTIES MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
# Release only compiling options
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
# Options
#
# - /GR-: Do not generate runtime information.
# - /Oi: Generate instrinsic functions.
# - /Zi: Generates "Format Database" debug information format.
# - /MT: Use multithread runtime (set via MSVC_RUNTIME_LIBRARY property).
#
target_compile_options(${target} PRIVATE /GR- /Oi /Zi)
set_target_properties(${target} PROPERTIES MSVC_RUNTIME_LIBRARY MultiThreaded)
else()
message(ERROR "Unsuported MSVC CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
endif()
endfunction(set_msvc_khiops_options)
# Display all variables
function(display_variables)
get_cmake_property(_variableNames VARIABLES)
list(SORT _variableNames)
foreach(_variableName ${_variableNames})
message(STATUS "${_variableName}=${${_variableName}}")
endforeach()
endfunction()
# This function set up a JAR target. Arguments:
#
# - NAME: Name of the JAR target
# - IMAGES: Paths of the image files to include in the JAR
function(add_khiops_jar)
# Parse the function arguments
set(options "")
set(oneValueArgs "NAME")
set(multiValueKwargs "JAVA_FILES" "IMAGES")
cmake_parse_arguments(ADD_KHIOPS_JAR "${options}" "${oneValueArgs}" "${multiValueKwargs}" ${ARGN})
# Add the JAR target with its resources and install
message(STATUS "Setting up JAR ${ADD_KHIOPS_JAR_NAME}.jar")
add_jar(
"${ADD_KHIOPS_JAR_NAME}_jar" ${ADD_KHIOPS_JAR_JAVA_FILES}
OUTPUT_NAME ${ADD_KHIOPS_JAR_NAME} RESOURCES NAMESPACE "images" ${ADD_KHIOPS_JAR_IMAGES}
OUTPUT_DIR "${CMAKE_BINARY_DIR}/jars" COMPONENT KHIOPS)
install_jar("${ADD_KHIOPS_JAR_NAME}_jar" DESTINATION usr/share/khiops)
endfunction()
# Load module to generate views from .dd files
include(generate_gui)
# Add targets for Norm Parallel and Learning modules
add_subdirectory(src/Norm)
add_subdirectory(src/Parallel)
add_subdirectory(src/Learning)
# Testing settings
if(TESTING)
# Disable gMock from the building of googletest
set(BUILD_GMOCK OFF)
# Fetch googletest from its Git repo
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY "https://github.com/google/googletest.git"
GIT_TAG "v1.13.0")
# For Windows: Prevent overriding the parent project's compiler/linker settings
#
# - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# - ** This doesn't work due to a bug ** see below for the workaround
FetchContent_MakeAvailable(googletest)
# Workaround for windows: https://github.com/actions/virtual-environments/issues/5900
if(CMAKE_BUILD_TYPE STREQUAL "Release")
set_property(TARGET gtest PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded)
set_property(TARGET gtest_main PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded)
else()
set_property(TARGET gtest PROPERTY MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
set_property(TARGET gtest_main PROPERTY MSVC_RUNTIME_LIBRARY MultiThreadedDebug)
endif()
# Include and enable googletest
include(GoogleTest)
enable_testing()
# Add testing targets
add_subdirectory(test/UnitTests/Norm)
add_subdirectory(test/UnitTests/Parallel)
add_subdirectory(test/UnitTests/Parallel-mpi)
add_subdirectory(test/UnitTests/Learning)
add_subdirectory(test/UnitTests/KNITest)
add_subdirectory(test/UnitTests/Utils)
endif(TESTING)
# Exclude googletest from the installation
set(INSTALL_GTEST OFF)
# Add packaging directory for CPack scripts
include(packaging)