-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCMakeLists.txt
531 lines (393 loc) · 17.2 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
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(CDFF VERSION 0.1 LANGUAGES C CXX)
# Maintainer: Romain Michalec <[email protected]>
## User interface --------------------------------------------------------------
##
## You can set these cache entries on the cmake command line: -D <var>=<value>.
## The setting will take priority over the project's default values (defined
## below) and update the entries present in the CMake cache (CMakeCache.txt).
# Choose between building the CDFF as static libraries or shared libraries
option(BUILD_SHARED_LIBS
"Build shared libraries instead of static libraries" OFF)
# To use the libraries provided in the source tree, set USE_BUNDLED_DEPENDENCIES
# to ON: CMake will look for headers, compiled libraries, and executable files
# under BUNDLED_DEPENDENCIES_PREFIX before looking anywhere else, in particular
# in your system directories.
#
# When building inside a container spanned from a CDFF Docker image, leave at
# OFF: the appropriate libraries are in /usr/local.
#
# Switching from ON to OFF without deleting the CMake cache will not result in
# the desired effect if bundled libraries were previously found, because
# information about them will persist in the CMake cache. Delete the cache.
option(USE_BUNDLED_DEPENDENCIES
"Preferably link the CDFF against the libraries provided in the source tree" OFF)
set(BUNDLED_DEPENDENCIES_PREFIX External/install CACHE PATH
"Location of the libraries in the source tree")
# Define preprocessor definition TESTING
# Use it in #ifdef and #ifndef preprocessor conditionnals in your source code
#
# TODO: this preprocessor definition should probably be defined at a more inner
# scope than the top-level CMakeLists file, perhaps with target_compile_
# definitions() or set_source_files_properties()?
option(TEST_ENABLED "Compile test code in DFNs and DFPCs" ON)
if(TEST_ENABLED)
add_definitions(-DTESTING)
endif()
# Generate tests for CTest. Each test defined with the CMake command add_test()
# will be registered as a CTest test. Run these tests with ctest(1). The enable_
# testing() command must be in the top-level source directory.
enable_testing()
# Flags passed to the compiler
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
## Print basic information -----------------------------------------------------
message(STATUS "Generating makefiles for project: ${PROJECT_NAME}")
message(STATUS "Top-level source directory: ${CMAKE_SOURCE_DIR}")
message(STATUS "Top-level build directory: ${CMAKE_BINARY_DIR}")
## Work in progress ------------------------------------------------------------
# TODO: remove this temporary internal variable when all find_package() commands
# load everything they are supposed to load (probably just requires fixing inner
# CMakeLists files). For now this variable selects between looking for VTK, PCL,
# OpenCV in /usr/local (default installation path selected in the Docker image)
# or in the source tree, and it also helps with finding FindBoost.cmake.
set(_DEPENDENCIES_PREFIX /usr/local)
if(USE_BUNDLED_DEPENDENCIES)
set(_DEPENDENCIES_PREFIX "${BUNDLED_DEPENDENCIES_PREFIX}")
endif()
## Customize search paths ------------------------------------------------------
# When used in "module" mode, find_package() looks for a find module called
# Find<package>.cmake in the directories specified in CMAKE_MODULE_PATH
# (default: empty) before checking the default modules that come with CMake.
#
# include() looks for modules called <module>.cmake in the exact same way.
#
# Find modules loaded by find_package() in "module" mode will typically look
# for the package's components, whether compiled libraries, header files, and/or
# binaries, by using the other find_*() commands, so look further down for the
# CMAKE_PREFIX_PATH variable. Additionally, they will typically give higher
# priority to package-specific variables (e.g. BOOST_ROOT), if set.
if(USE_BUNDLED_DEPENDENCIES)
set(CMAKE_MODULE_PATH
"${CMAKE_SOURCE_DIR}/${BUNDLED_DEPENDENCIES_PREFIX}/share/cmake-3.11.4/Modules")
else()
# TODO: check if CMake 3.5.1 doesn't automatically look for find modules in
# /usr/local/share/cmake*/Modules (it does in /usr/share/cmake-3.5/Modules)
set(CMAKE_MODULE_PATH
"${_DEPENDENCIES_PREFIX}/share/cmake-3.11.4/Modules")
endif()
if(USE_BUNDLED_DEPENDENCIES)
# When used in "config" mode, find_package() looks for a package configuration
# file called <package>Config.cmake or <lower-case-package>-config.cmake in
# the directories specified by certain cache/environment variables, including
# directories deduced from PATH, as well as in a variety of standard locations
# under these directories.
#
# find_library(), find_file(), find_path(), and find_program() look for a
# compiled library, a file, a directory containing the given file, and an
# executable file in the directories specified by similar cache/environment
# variables, including directories deduced from PATH, as well as in their
# lib/, include/, and [s]bin/ subdirectories, respectively.
#
# The complete search procedure is described in the documentation of those
# functions.
#
# In all cases, the first search paths tried are those under the directories
# specified by the following variable (default: empty):
set(CMAKE_PREFIX_PATH "${BUNDLED_DEPENDENCIES_PREFIX}")
endif()
## Info/debug function ---------------------------------------------------------
# Print whether a previously executed find_package() command ran in "module"
# mode or in "config" mode
macro(find_package_mode pkg)
if(NOT ${pkg}_CONFIG)
message(STATUS "Found CMake find module for ${pkg}")
else()
message(STATUS "Found package configuration file for ${pkg}: ${${pkg}_CONFIG}")
endif()
endmacro()
## Look for Boost --------------------------------------------------------------
# Most Boost libraries are header-only. Please write the compiled libraries that
# you want to link against after the COMPONENTS keyword, so that CMake looks for
# them: for instance date_time for Boost.Date_Time aka libboost_date_time.so.
#
# CMake will look for the headers and the requested compiled libraries, as well
# as the compiled libraries they depend on.
find_package(Boost 1.66.0 REQUIRED)
if(Boost_FOUND)
find_package_mode(Boost)
# To use header-only libraries:
#
# * In your source:
# #include <boost/...>
#
# * In your CMakeLists file:
# include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
# add_library(mylib src1.cpp src2.cpp ...)
#
# To use compiled libraries:
#
# * In your source:
# #include <boost/...>
#
# * In your CMakeLists file:
# include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
# add_executable(mybin src1.cpp src2.cpp ...)
# target_link_libraries(mybin Boost::date_time Boost::serialization ...)
# # to link against the specified libraries and their dependencies
#
# TODO: target_include_directories() should be preferred to include_
# directories() but I don't understand how it works
message(STATUS "Found Boost headers in: ${Boost_INCLUDE_DIRS}")
message(STATUS "Found Boost compiled libraries in: ${Boost_LIBRARY_DIRS}")
# TODO: better reporting of imported targets
if(TARGET Boost::boost)
message(STATUS "Succesfully imported targets: Boost::boost")
endif()
message(STATUS "All requested Boost compiled libraries, "
"and their dependencies: ${Boost_LIBRARIES}")
# TODO: kept for compatibility with the existing CDFF code base: to be removed
# when all CMakeLists that define targets that use Boost libraries feature the
# appropriate [target_]include_directories()
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
else()
# Abort if the headers or a requested compiled library is not found
return()
endif()
## Look for Eigen --------------------------------------------------------------
# TODO: doc
find_package(Eigen3 3.3.4 REQUIRED)
if(Eigen3_FOUND)
find_package_mode(Eigen3)
# TODO: better reporting of imported targets
if(TARGET Eigen3::Eigen)
message(STATUS "Succesfully imported target: Eigen3::Eigen")
message(STATUS "Pass it to your target_link_libraries() commands")
endif()
else()
# Abort if the headers are not found
return()
endif()
# TODO: remove, use imported target Eigen3::Eigen instead
include_directories(
SYSTEM "${_DEPENDENCIES_PREFIX}/include/eigen3"
)
## Look for Ceres --------------------------------------------------------------
# TODO: doc
find_package(Ceres 1.14.0 REQUIRED COMPONENTS SparseLinearAlgebraLibrary)
if(Ceres_FOUND)
find_package_mode(Ceres)
# To use Ceres:
#
# * In your source:
# #include <ceres/...>
#
# * In your CMakeLists file:
# include_directories(SYSTEM ${CERES_INCLUDE_DIRS})
# add_executable(mybin src1.cpp src2.cpp ...)
# target_link_libraries(mybin ${CERES_LIBRARIES})
# # to link against Ceres and its dependencies
#
# TODO: target_include_directories() should be preferred to include_
# directories() but I don't understand how it works
message(STATUS "Found Ceres headers, and the headers of its dependencies, in: ${CERES_INCLUDE_DIRS}")
# TODO: CERES_LIBRARIES appears to actually be an imported target instead of a list of
# libraries, cf. http://ceres-solver.org/installation.html#understanding-the-cmake-package-system
message(STATUS "Requested Ceres library, "
"and its dependencies: ${CERES_LIBRARIES}")
# TODO: kept for compatibility with the existing CDFF code base: to be removed
# when all CMakeLists that define targets feature the appropriate [target_]
# include_directories()
# TODO: also, ${CERES_INCLUDE_DIRS} features /usr/include if some dependencies
# of Ceres have been installed as osdeps, so /usr/include will be before all
# other include dirs subsequently appended to the list, which can cause trouble
# when looking for a library which is in two different version in /usr/include
# and ${_DEPENDENCIES_PREFIX}/include -> really necessary to restrict the
# include dirs to specific targets
include_directories(SYSTEM ${CERES_INCLUDE_DIRS})
add_definitions(-DHAVE_CERES)
else()
# Abort if Ceres is not found
return()
endif()
## Don't look for FLANN, yaml-cpp, CloudCompare-core ---------------------------
set(CLOUDCOMPARE_FOUND true)
set(CLOUDCOMPARE_INCLUDE_DIRS "")
set(CLOUDCOMPARE_LIBRARIES "cloudcompare_core")
if(CLOUDCOMPARE_FOUND)
add_definitions(-DHAVE_CLOUDCOMPARE)
endif()
# There aren't any CMake find modules nor any package configuration files for
# those libraries, so just add the main include directory and use the libraries
# as e.g. #include <flann/stuff.hpp>
#
# TODO: there are .pc files though, that might be of use in conjunction with
# CMake's pkg-config module
include_directories(
SYSTEM "${_DEPENDENCIES_PREFIX}/include"
)
link_directories(
"${_DEPENDENCIES_PREFIX}/lib"
)
## Look for VTK, PCL, OpenCV ---------------------------------------------------
# TODO: rework this section
find_package(VTK 8.1.0 REQUIRED NAMES VTK VTK-8.1 CONFIGS VTKConfig.cmake)
find_package_mode(VTK)
find_package(PCL 1.8.1 REQUIRED NAMES PCL PCL-1.8 CONFIGS PCLConfig.cmake)
find_package_mode(PCL)
add_definitions(${PCL_DEFINITIONS})
include_directories(SYSTEM ${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
if(PCL_FOUND)
add_definitions(-DHAVE_PCL)
endif()
message(STATUS "Preprocessor definitions and compiler flags added by the PCL: ${PCL_DEFINITIONS}")
message(STATUS "Found PCL headers, and the headers of its dependencies, in: ${PCL_INCLUDE_DIRS}")
message(STATUS "Found PCL libraries in: ${PCL_LIBRARY_DIRS}")
message(STATUS "All requested PCL libraries, and their dependencies: ${PCL_LIBRARIES}")
find_package(OpenCV 3.4.0 REQUIRED)
find_package_mode(OpenCV)
if(OpenCV_FOUND)
add_definitions(-DHAVE_OPENCV)
# checking extra contrib modules
include(CheckIncludeFileCXX)
check_include_file_cxx(opencv2/ximgproc.hpp HAVE_OPENCV_XIMGPROC)
check_include_file_cxx(opencv2/rgbd.hpp HAVE_OPENCV_RGBD)
if(HAVE_OPENCV_RGBD AND HAVE_OPENCV_XIMGPROC)
add_definitions(-DHAVE_OPENCV_CONTRIB)
else()
message(WARNING one of the modules from OPENCV_CONTRIB is missing : ximgproc, rgbd )
endif()
endif()
## Look for libpointmatcher ---------------------------------------------------
# TODO: rework this section
find_package(libpointmatcher 1.3.0 REQUIRED)
set(POINTMATCHER_FOUND true)
if(POINTMATCHER_FOUND)
add_definitions(-DHAVE_POINTMATCHER)
endif()
# Usage:
# target_include_directories(<target> SYSTEM PRIVATE|PUBLIC ${POINTMATCHER_INCLUDE_DIRS})
# target_link_libraries(<target> PRIVATE|PUBLIC ${POINTMATCHER_LIBRARIES})
## Look for Edres-Wrapper (optional dependency) --------------------------------
find_package(Edres-Wrapper QUIET)
if(Edres-Wrapper_FOUND)
find_package_mode(Edres-Wrapper)
message(STATUS "Found Edres-Wrapper headers in: ${Edres-Wrapper_INCLUDE_DIRS}")
message(STATUS "Found Edres-Wrapper libraries, and their dependencies: ${Edres-Wrapper_LIBRARIES}")
add_definitions(-DHAVE_EDRES)
include_directories(SYSTEM ${Edres-Wrapper_INCLUDE_DIRS})
else()
message(STATUS "Edres-Wrapper not found: Edres-dependent parts will not be built")
endif()
## Look for DLRTracker-core (optional dependency) ------------------------------
find_package(DLRtracker_core QUIET)
if(DLRTRACKER-CORE_FOUND)
find_package_mode(DLRtracker_core)
message(STATUS "Found DLRTracker-core headers in: ${DLRTRACKER-CORE_INCLUDE_DIRS}")
message(STATUS "Found DLRTracker-core libraries, and their dependencies: ${DLRTRACKER-CORE_LIBRARIES}")
include_directories(SYSTEM ${DLRTRACKER-CORE_INCLUDE_DIRS})
else()
message(STATUS "DLRTracker-core not found: DLRTracker-dependent parts will not be built")
endif()
## Try to compile Core/liborbslam ------------------------------
find_package(Pangolin QUIET)
if(Pangolin_FOUND)
find_package_mode(Pangolin)
if(EXISTS ${CMAKE_SOURCE_DIR}/Common/Core/liborbslam)
message(STATUS "Building Common/Core/liborbslam")
set(WITH_LIBORBSLAM ON)
add_definitions(-DHAVE_LIBORBSLAM)
add_subdirectory(${CMAKE_SOURCE_DIR}/Common/Core/liborbslam)
endif()
else()
set(WITH_LIBORBSLAM OFF)
message(STATUS "Pangolin not found: Common/Core/liborbslam will not be built")
endif()
option(BUILD_CENTRALDPM "Build the central data product manager" OFF)
if(BUILD_CENTRALDPM)
message(STATUS "Central Data Product Manager will be built if Envire is found")
find_package(PkgConfig REQUIRED)
pkg_check_modules(ENVIRE_CORE envire_core)
if (ENVIRE_CORE_FOUND)
message(STATUS "Envire found, Data Product Manager will be built")
else()
set(BUILD_CENTRALDPM OFF)
message(STATUS "Envire not found the Data Product Manager will not be built")
endif()
else()
message(STATUS "The Data Product Manager will not be built, becase the correspondent flag is OFF")
endif()
## Setup CDFF installation -----------------------------------------------------
# Standard installation directories, as defined by the GNU Coding Standards:
#
# * CMAKE_INSTALL_INCLUDEDIR is include
# * CMAKE_INSTALL_LIBDIR is lib
# * CMAKE_INSTALL_BINDIR is bin
# * Full list at https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html
#
# Use them in your install() commands, see example below. CMAKE_INSTALL_PREFIX,
# default /usr/local, will be prepended to those directories.
include(GNUInstallDirs)
# Install all the header files
file(GLOB_RECURSE headers
RELATIVE "${CMAKE_SOURCE_DIR}"
"Common/*.h" "Common/*.hpp" "DFNs/*.hpp" "DFPCs/*.hpp" "Tests/*.hpp")
list(SORT headers)
foreach(header ${headers})
get_filename_component(dir "${header}" DIRECTORY)
install(FILES "${header}"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${dir}")
endforeach()
## Setup CDFF uninstallation ---------------------------------------------------
# Add an uninstall target, see documentation in cmake_uninstall.cmake[.in]
configure_file(
"${CMAKE_SOURCE_DIR}/Tools/CMake/cmake_uninstall.cmake.in"
"${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
@ONLY)
add_custom_target(uninstall
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/cmake_uninstall.cmake"
VERBATIM)
# Add a purge target, see documentation in cmake_purge.cmake[.in]
configure_file(
"${CMAKE_SOURCE_DIR}/Tools/CMake/cmake_purge.cmake.in"
"${CMAKE_BINARY_DIR}/cmake_purge.cmake"
@ONLY)
add_custom_target(purge
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_BINARY_DIR}/cmake_purge.cmake"
VERBATIM)
## Compile the CDFF ------------------------------------------------------------
# Take into account the headers provided in the following directories
#
# To use these headers:
#
# * In your source:
# #include "[subdir/.../]header.hpp"
#
# TODO: as with the previous libraries, [target_]include_directories() commands
# written in inner CMakeLists file should be preferred to include_directories()
# written in the top-level CMakeLists file
include_directories(
Common
DFNs
DFPCs
)
if(BUILD_CENTRALDPM)
include_directories(Support)
endif()
# Process all subdirectories containing a CMakeLists file
add_subdirectory(Common)
add_subdirectory(DFNs)
add_subdirectory(DFPCs)
if(BUILD_CENTRALDPM)
add_subdirectory(Support)
endif()
# Optionally compile the tests (unit tests, interactive tests, performance
# tests, etc)
option(BUILD_TESTS "Build the CDFF's tests" ON)
if(BUILD_TESTS)
include_directories(Tests)
add_subdirectory(Tests)
endif()