-
Notifications
You must be signed in to change notification settings - Fork 32
/
CMakeLists.txt
393 lines (342 loc) · 12.8 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
cmake_minimum_required(VERSION 3.3)
project(crab)
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
message (FATAL_ERROR
"In-source builds are not allowed. Please clean your source tree and try again.")
endif()
# Determine if this is top-level or embedded project
if (PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME)
set(TopLevel TRUE)
else()
set(TopLevel FALSE)
endif()
# Default is release with debug info
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo Coverage." FORCE)
endif()
# Add path for custom modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
#--------------- Crab Options ---------------------#
option(CRAB_USE_LDD "Enable Ldd library" OFF)
option(CRAB_USE_APRON "Enable Apron library" OFF)
option(CRAB_USE_PPLITE "Enable PPLite library" OFF)
option(CRAB_USE_ELINA "Enable Elina library" OFF)
option(CRAB_BUILD_LIBS_SHARED "Build all Crab libraries dynamically." OFF)
option(CRAB_ENABLE_STATS "Enable stats" ON)
if (CRAB_USE_APRON AND CRAB_USE_ELINA)
message(FATAL_ERROR "Crab: Apron and Elina are not compatible. Choose one")
endif()
## Only for developers use
option(CRAB_ENABLE_TESTS "Enable tests" OFF)
option(CRAB_ENABLE_ASAN "Enable Address Sanitizer" OFF)
option(CRAB_USE_GENERIC_WRAPPER
"If tests enabled then use the generic abstract domain" OFF)
# Enforce c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#--------------- TESTS ----------------------------#
if (CRAB_ENABLE_TESTS)
#Setup CMake to run tests
enable_testing()
## Enforce these flags only when compiling our tests
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
if (CRAB_ENABLE_ASAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
message(STATUS "Crab: enabled Address Sanitizer")
endif()
# Directory where all (binary) tests will be located
# Binary tests do not go to install directory by default
if (NOT TEST_DIR)
set(TEST_DIR ${CMAKE_BINARY_DIR}/test-bin)
endif()
endif()
# Save old CMAKE_FIND_LIBRARY_SUFFIXES
set(_CRAB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
#------------ Static/Dynamic libraries ----------------#
# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
#set(CMAKE_FIND_LIBRARY_SUFFIXES .so .dylib .a)
if (NOT CRAB_BUILD_LIBS_SHARED)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif ()
if (CRAB_BUILD_LIBS_SHARED)
set(_DYNAMIC_LIBS_EXC_STR "")
if(CRAB_USE_LDD)
set(_DYNAMIC_LIBS_EXC_STR "${_DYNAMIC_LIBS_EXC_STR}\n - except ldd ")
endif()
if(CRAB_USE_APRON)
set(_DYNAMIC_LIBS_EXC_STR "${_DYNAMIC_LIBS_EXC_STR}\n - except apron")
endif()
if(CRAB_USE_PPLITE)
set(_DYNAMIC_LIBS_EXC_STR "${_DYNAMIC_LIBS_EXC_STR}\n - except pplite")
endif()
message (STATUS "Crab: libraries and dependencies are built dynamically ${_DYNAMIC_LIBS_EXC_STR}")
set(CRAB_LIBS_TYPE SHARED)
else()
set(_STATIC_LIBS_EXC_STR "")
if(CRAB_USE_ELINA)
set(_STATIC_LIBS_EXC_STR "${_STATIC_LIBS_EXC_STR}\n - except elina")
endif()
message (STATUS "Crab: libraries and dependencies are built statically ${_STATIC_LIBS_EXC_STR}")
set(CRAB_LIBS_TYPE STATIC)
endif ()
# So that executables outside the build tree can find later dynamic
# libraries. Even if CRAB_LIBS_TYPE=STATIC we could have a mix of
# dynamic and static libraries
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Mac OS X specific code
set(CMAKE_MACOSX_RPATH TRUE)
endif ()
if (NOT CMAKE_INSTALL_RPATH )
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/crab/lib")
endif()
#---------- BOOST --------#
set (CUSTOM_BOOST_ROOT "" CACHE PATH "Path to custom boost installation.")
if (CUSTOM_BOOST_ROOT)
set (BOOST_ROOT ${CUSTOM_BOOST_ROOT})
set (Boost_NO_SYSTEM_PATHS "ON")
endif()
if (CRAB_ENABLE_TESTS)
find_package (Boost 1.65.0 COMPONENTS program_options REQUIRED)
set(Boost_USE_STATIC_LIBS ON)
if (CRAB_BUILD_LIBS_SHARED)
set(Boost_USE_STATIC_LIBS OFF)
endif ()
if (CRAB_USE_GENERIC_WRAPPER)
set(USE_GENERIC_WRAPPER TRUE)
endif ()
else ()
find_package (Boost 1.65.0)
endif ()
if (Boost_FOUND)
include_directories (${Boost_INCLUDE_DIRS})
endif ()
#---------- GMP ---------#
set(GMP_USE_STATIC_LIBS ON)
if (CRAB_BUILD_LIBS_SHARED)
set(GMP_USE_STATIC_LIBS OFF)
endif ()
find_package(GMP REQUIRED)
if (GMP_FOUND)
include_directories (${GMP_INCLUDE_DIR})
else()
set(GMP_LIB "")
endif()
#---------- MPFR ---------#
if (CRAB_USE_APRON OR CRAB_USE_ELINA)
get_filename_component (GMP_SEARCH_PATH ${GMP_INCLUDE_DIR} PATH)
find_package(MPFR REQUIRED)
if (MPFR_FOUND)
get_filename_component (MPFR_SEARCH_PATH ${MPFR_INCLUDES} PATH)
endif ()
endif ()
#---------- FLINT ---------#
if (CRAB_USE_PPLITE)
get_filename_component (GMP_SEARCH_PATH ${GMP_INCLUDE_DIR} PATH)
find_package(FLINT REQUIRED)
if (FLINT_FOUND)
get_filename_component (FLINT_SEARCH_PATH ${FLINT_INCLUDES} PATH)
endif ()
endif ()
#------- Configuration for Coverage ----------#
if (CMAKE_BUILD_TYPE STREQUAL Coverage)
include(Coverage)
# We don't want coverage on external things
set(EXT_CMAKE_BUILD_TYPE Release)
else()
set(EXT_CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE})
endif ()
#------- Download external dependencies -------#
include(ExternalProject)
set_property(DIRECTORY PROPERTY EP_STEP_TARGETS configure build test)
find_package (Git)
include(download_apron)
include(download_elina)
include(download_boxes_ldd)
include(download_pplite)
if (CRAB_USE_LDD)
find_package(Ldd)
if (LDD_FOUND)
include_directories (${LDD_INCLUDE_DIR})
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LDD_CXXFLAGS}")
set (LDD_LIBS ${LDD_LIBRARY})
set (HAVE_LDD TRUE)
else()
ExternalProject_Get_Property (ldd INSTALL_DIR)
set (LDD_ROOT ${INSTALL_DIR} CACHE FILEPATH "Forced location of ldd" FORCE)
message (WARNING "Crab: no ldd found. Run \n\tcmake --build . --target ldd && cmake ${CMAKE_SOURCE_DIR}")
# restore old CMAKE_FIND_LIBRARY_SUFFIXES
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CRAB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
return()
endif()
endif ()
# PPLite (if enabled) should be built before Apron
if (CRAB_USE_PPLITE)
find_package(PPLite)
if (PPLITE_FOUND)
include_directories (${PPLITE_INCLUDE_DIR})
set (PPLITE_LIBS ${PPLITE_LIBRARY})
set (HAVE_PPLITE TRUE)
else()
ExternalProject_Get_Property (pplite INSTALL_DIR)
set (PPLITE_ROOT ${INSTALL_DIR} CACHE FILEPATH "Forced location of pplite" FORCE)
message (WARNING "Crab: no pplite found. Run \n\tcmake --build . --target pplite && cmake ${CMAKE_SOURCE_DIR}")
# restore old CMAKE_FIND_LIBRARY_SUFFIXES
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CRAB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
return()
endif()
endif ()
if (CRAB_USE_APRON)
find_package(Apron)
if (APRON_FOUND)
include_directories (${APRON_INCLUDE_DIR})
set (APRON_LIBS ${APRON_LIBRARY})
set (HAVE_APRON TRUE)
else()
ExternalProject_Get_Property (apron INSTALL_DIR)
set (APRON_ROOT ${INSTALL_DIR} CACHE FILEPATH "Forced location of apron" FORCE)
message (WARNING "Crab: no apron found. Run \n\tcmake --build . --target apron && cmake ${CMAKE_SOURCE_DIR}")
# restore old CMAKE_FIND_LIBRARY_SUFFIXES
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CRAB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
return()
endif()
endif ()
if (CRAB_USE_ELINA)
find_package(Elina)
if (ELINA_FOUND)
include_directories (${ELINA_INCLUDE_DIR})
set (ELINA_LIBS ${ELINA_LIBRARY})
set (HAVE_ELINA TRUE)
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags")
endif()
else()
ExternalProject_Get_Property (elina INSTALL_DIR)
set (ELINA_ROOT ${INSTALL_DIR} CACHE FILEPATH "Forced location of elina" FORCE)
message (WARNING "Crab: no elina found. Run \n\tcmake --build . --target elina && cmake ${CMAKE_SOURCE_DIR}")
# restore old CMAKE_FIND_LIBRARY_SUFFIXES
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CRAB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
return()
endif()
endif ()
if (CRAB_USE_LDD)
set_target_properties(ldd PROPERTIES EXCLUDE_FROM_ALL ON)
message (STATUS "Crab: Boxes domain will be available")
else ()
message (STATUS "Crab: Boxes domain will NOT be available")
endif ()
if (CRAB_USE_APRON)
set_target_properties(apron PROPERTIES EXCLUDE_FROM_ALL ON)
message (STATUS "Crab: Apron domains will be available")
else ()
message (STATUS "Crab: Apron domains will NOT be available")
endif ()
if (CRAB_USE_PPLITE)
set_target_properties(pplite PROPERTIES EXCLUDE_FROM_ALL ON)
message (STATUS "Crab: PPLite domains will be available")
else ()
message (STATUS "Crab: PPLite domains will NOT be available")
endif ()
if (CRAB_USE_ELINA)
set_target_properties(elina PROPERTIES EXCLUDE_FROM_ALL ON)
message (STATUS "Crab: Elina domains will be available")
else ()
message (STATUS "Crab: Elina domains will NOT be available")
endif ()
#------ Crab Options for logging and stats ----------#
# Enable always logging
set(NCRABLOG FALSE)
# Enable or disable stats gathering
if (CRAB_ENABLE_STATS)
set(CRAB_STATS TRUE)
else()
set(CRAB_STATS FALSE)
endif()
#------- Create CRAB_LIBS and CRAB_INCLUDE_DIRS for Crab clients -------#
set (CRAB_DEPS_LIBS
${LDD_LIBRARY}
${PPLITE_LIBRARY}
${APRON_LIBRARY}
${FLINT_LIBRARY}
${ELINA_LIBRARY}
${MPFR_LIBRARIES}
${GMP_LIB})
if (TopLevel)
set (CRAB_LIBS Crab ${CRAB_DEPS_LIBS})
else ()
## Propagate CRAB_LIBS and CRAB_INCLUDE_DIRS to parent
set (_CRAB_INCLUDE_DIRS
${crab_SOURCE_DIR}/include
## crab config.h
${CMAKE_BINARY_DIR}/include )
if (LDD_FOUND)
set (_CRAB_INCLUDE_DIRS ${_CRAB_INCLUDE_DIRS} ${LDD_INCLUDE_DIR})
endif ()
if (APRON_FOUND)
set (_CRAB_INCLUDE_DIRS ${_CRAB_INCLUDE_DIRS} ${APRON_INCLUDE_DIR})
endif ()
if (PPLITE_FOUND)
set (_CRAB_INCLUDE_DIRS ${_CRAB_INCLUDE_DIRS} ${PPLITE_INCLUDE_DIR})
endif ()
if (ELINA_FOUND)
set (_CRAB_INCLUDE_DIRS ${_CRAB_INCLUDE_DIRS} ${ELINA_INCLUDE_DIR})
endif ()
set(CRAB_LIBS Crab ${CRAB_DEPS_LIBS} PARENT_SCOPE)
set(CRAB_INCLUDE_DIRS ${_CRAB_INCLUDE_DIRS} PARENT_SCOPE)
endif()
#------- Compile Crab library and optionally tests -----#
include_directories(${crab_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
configure_file(include/crab/config.h.cmake
${CMAKE_BINARY_DIR}/include/crab/config.h )
add_subdirectory(lib)
if (CRAB_ENABLE_TESTS)
message (STATUS "Crab: tests will be compiled")
if (CRAB_USE_GENERIC_WRAPPER)
message(STATUS "Crab: compiling tests using generic wrapper for abstract domains")
endif()
add_subdirectory(tests)
endif ()
# restore old CMAKE_FIND_LIBRARY_SUFFIXES
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_CRAB_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
###----------------- INSTALL --------------------------####
install(DIRECTORY include/
DESTINATION crab/include
PATTERN "config.h.cmake" EXCLUDE)
install(FILES ${CMAKE_BINARY_DIR}/include/crab/config.h DESTINATION crab/include/crab)
if (CRAB_USE_LDD)
ExternalProject_Get_Property (ldd INSTALL_DIR)
install(DIRECTORY ${INSTALL_DIR} DESTINATION .)
endif()
if (CRAB_USE_APRON)
ExternalProject_Get_Property (apron INSTALL_DIR)
install(DIRECTORY ${INSTALL_DIR} DESTINATION .)
endif()
if (CRAB_USE_PPLITE)
ExternalProject_Get_Property (pplite INSTALL_DIR)
install(DIRECTORY ${INSTALL_DIR} DESTINATION .)
endif()
if (CRAB_USE_ELINA)
ExternalProject_Get_Property (elina INSTALL_DIR)
install(DIRECTORY ${INSTALL_DIR} DESTINATION .)
if (NOT TopLevel)
## This is ugly fix so that seahorn and crab-llvm can find elina's
## shared libraries. It has to do with how CMAKE_INSTALL_RPATH is
## handled by these tools.
foreach(library ${ELINA_LIBRARY})
get_filename_component(library_name ${library} NAME_WE)
file(COPY ${library} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endforeach(library)
endif()
endif ()
if (TopLevel)
install(FILES LICENSE DESTINATION .)
install(FILES README.md DESTINATION .)
install(FILES IKOS_LICENSE.pdf DESTINATION .)
endif ()
# Print cmake command
if (CRAB_ENABLE_TESTS)
message(STATUS "Crab: cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DCRAB_USE_APRON=${CRAB_USE_APRON} -DCRAB_USE_PPLITE=${CRAB_USE_PPLITE} -DCRAB_USE_ELINA=${CRAB_USE_ELINA} -DCRAB_USE_LDD=${CRAB_USE_LDD} -DCRAB_BUILD_LIBS_SHARED=${CRAB_BUILD_LIBS_SHARED} -DCRAB_ENABLE_TESTS=${CRAB_ENABLE_TESTS} -DTEST_DIR=${TEST_DIR}")
else()
message(STATUS "Crab: cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DCRAB_USE_APRON=${CRAB_USE_APRON} -DCRAB_USE_PPLITE=${CRAB_USE_PPLITE} -DCRAB_USE_ELINA=${CRAB_USE_ELINA} -DCRAB_USE_LDD=${CRAB_USE_LDD} -DCRAB_BUILD_LIBS_SHARED=${CRAB_BUILD_LIBS_SHARED}")
endif()