forked from valhalla/valhalla
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
413 lines (365 loc) · 16.9 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
# Minimal CMake configuration for Valhalla
#
# Builds libvalhalla and minimal collection of programs.
#
# This is NOT equivalent to the official Valhalla build configuration based on GNU Autotools.
# This is NOT suitable for building complete Valhalla suite.
# This is secondary build configuration provided for convenient development
# on Windows and using CMake-enabled IDEs.
#
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(valhalla LANGUAGES CXX C)
include(FindPkgConfig)
include(GNUInstallDirs)
set(VALHALLA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(VALHALLA_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR})
list(INSERT CMAKE_MODULE_PATH 0 ${VALHALLA_SOURCE_DIR}/cmake)
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ language version to use (default is 17)")
option(ENABLE_TOOLS "Enable Valhalla tools" ON)
option(ENABLE_DATA_TOOLS "Enable Valhalla data tools" ON)
option(ENABLE_SERVICES "Enable Valhalla services" ON)
option(ENABLE_HTTP "Enable the use of CURL" ON)
option(ENABLE_PYTHON_BINDINGS "Enable Python bindings" ON)
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF)
option(ENABLE_COMPILER_WARNINGS "Build with compiler warnings" OFF)
option(ENABLE_SANITIZERS "Use all the integrated sanitizers for Debug build" OFF)
option(ENABLE_ADDRESS_SANITIZER "Use memory sanitizer for Debug build" OFF)
option(ENABLE_UNDEFINED_SANITIZER "Use UB sanitizer for Debug build" OFF)
option(ENABLE_TESTS "Enable Valhalla tests" ON)
option(ENABLE_WERROR "Convert compiler warnings to errors. Requires ENABLE_COMPILER_WARNINGS=ON to take effect" OFF)
option(ENABLE_THREAD_SAFE_TILE_REF_COUNT "If ON uses shared_ptr as tile reference(i.e. it is thread safe)" OFF)
option(ENABLE_SINGLE_FILES_WERROR "Convert compiler warnings to errors for single files" ON)
option(PREFER_EXTERNAL_DEPS "Whether to use internally vendored headers or find the equivalent external package" OFF)
# useful to workaround issues likes this https://stackoverflow.com/questions/24078873/cmake-generated-xcode-project-wont-compile
option(ENABLE_STATIC_LIBRARY_MODULES "If ON builds Valhalla modules as STATIC library targets" OFF)
set(LOGGING_LEVEL "" CACHE STRING "Logging level, default is INFO")
set_property(CACHE LOGGING_LEVEL PROPERTY STRINGS "NONE;ALL;ERROR;WARN;INFO;DEBUG;TRACE")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
# colorize output
include(CheckCXXCompilerFlag)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
if(HAS_COLOR_FLAG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COLOR_FLAG}")
endif()
endif()
# Explicitly set the build type to Release if no other type is specified
# on the command line. Without this, cmake defaults to an unoptimized,
# non-debug build, which almost nobody wants.
if(NOT MSVC_IDE) # TODO: May need to be extended for Xcode, CLion, etc.
if(NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type specified, defaulting to Release")
set(CMAKE_BUILD_TYPE Release)
endif()
endif()
if(CMAKE_BUILD_TYPE STREQUAL Debug)
message(STATUS "Configuring in debug mode")
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
message(STATUS "Configuring in release mode")
elseif(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
message(STATUS "Configuring in release mode with debug symbols")
elseif(CMAKE_BUILD_TYPE STREQUAL MinRelSize)
message(STATUS "Configuring in release mode with minimized size")
elseif(CMAKE_BUILD_TYPE STREQUAL None)
message(STATUS "Configuring without a mode, no optimization flags will be set")
else()
message(FATAL_ERROR "Unrecognized build type. Use one of Debug, Release, RelWithDebInfo, MinRelSize, None")
endif()
if(ENABLE_CCACHE AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
message(STATUS "Using ccache to speed up incremental builds")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
set(ENV{CCACHE_CPP2} "true")
endif()
endif()
include(ValhallaSanitizerOptions)
include(ValhallaSourceGroups)
# We use pkg-config for (almost) all dependencies:
# - CMake Find* modules are versioned with CMake, not the packages, see protobuf > 21.12
# - it's more trivial to use custom installations via PKG_CONFIG_PATH env var
find_package(PkgConfig REQUIRED)
find_package(Threads REQUIRED)
pkg_check_modules(ZLIB REQUIRED IMPORTED_TARGET zlib)
pkg_check_modules(LZ4 REQUIRED IMPORTED_TARGET liblz4)
# cURL
set(curl_targets "")
if (ENABLE_HTTP OR ENABLE_DATA_TOOLS)
pkg_check_modules(CURL REQUIRED IMPORTED_TARGET libcurl)
if (CURL_FOUND)
set(curl_targets PkgConfig::CURL)
target_compile_definitions(PkgConfig::CURL INTERFACE ENABLE_HTTP)
else()
message(FATAL_ERROR "ENABLE_HTTP=ON, but cURL not found...")
endif()
endif()
# Boost has no .pc file..
find_package(Boost 1.71 REQUIRED)
add_definitions(-DBOOST_NO_CXX11_SCOPED_ENUMS)
add_definitions(-DBOOST_ALLOW_DEPRECATED_HEADERS)
add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS)
# resolve vendored libraries
set(date_include_dir ${VALHALLA_SOURCE_DIR}/third_party/date/include)
set(rapidjson_include_dir ${CMAKE_SOURCE_DIR}/third_party/rapidjson/include)
set(robinhoodhashing_include_dir ${CMAKE_SOURCE_DIR}/third_party/robin-hood-hashing/src/include)
set(cxxopts_include_dir ${VALHALLA_SOURCE_DIR}/third_party/cxxopts/include)
set(dirent_include_dir ${CMAKE_SOURCE_DIR}/third_party/dirent/include)
if (PREFER_EXTERNAL_DEPS)
# date
find_package(date QUIET)
if (date_FOUND)
get_target_property(date_include_dir date::date INTERFACE_INCLUDE_DIRECTORIES)
else()
message(WARNING "No date found in system libraries, using vendored date...")
endif()
# rapidjson
find_package(RapidJSON QUIET)
if (RapidJSON_FOUND)
get_target_property(rapidjson_include_dir rapidjson INTERFACE_INCLUDE_DIRECTORIES)
else()
message(WARNING "No RapidJSON found in system libraries, using vendored RapidJSON...")
endif()
# robin-hood-hashing
find_package(robin_hood QUIET)
if (robin_hood_FOUND)
get_target_property(robinhoodhashing_include_dir robin_hood::robin_hood INTERFACE_INCLUDE_DIRECTORIES)
else()
message(WARNING "No robin_hood found in system libraries, using vendored robin_hood...")
endif()
# cxxopts
if (ENABLE_DATA_TOOLS OR ENABLE_TOOLS)
find_package(cxxopts QUIET)
if (cxxopts_FOUND)
get_target_property(cxxopts_include_dir cxxopts::cxxopts INTERFACE_INCLUDE_DIRECTORIES)
else()
message(WARNING "No cxxopts found in system libraries, using vendored cxxopts...")
endif()
endif()
# dirent
if (WIN32)
find_path(dirent_include_dir dirent.h REQUIRED)
if (dirent_include_dir-NOTFOUND)
message(WARNING "No dirent.h found in system headers, using vendored dirent.h...")
endif()
endif()
endif()
# Protobuf is non-trivial to include via pkg-config, pkg_check_modules has no way to check
# for protoc location in a platform agnostic manner
# prefer CONFIG mode over MODULE mode, which versions configuration on the package, not CMake
# NOTE: this is only supported for cmake >= 3.15, but shouldn't be a problem in real life
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# newer protobuf versions require a compat bool
set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")
find_package(Protobuf REQUIRED)
# and turn it off again
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
message(STATUS "Using protoc from ${Protobuf_PROTOC_EXECUTABLE}")
message(STATUS "Using pbf headers from ${Protobuf_INCLUDE_DIRS}")
message(STATUS "Using pbf libs from ${PROTOBUF_LIBRARIES}")
if(TARGET protobuf::libprotobuf-lite)
message(STATUS "Using pbf-lite")
endif()
if(TARGET protobuf::libprotobuf-lite)
set(valhalla_protobuf_targets protobuf::libprotobuf-lite)
elseif(TARGET protobuf::libprotobuf)
set(valhalla_protobuf_targets protobuf::libprotobuf)
else()
message(FATAL_ERROR "Required target protobuf::libprotobuf-lite or protobuf::libprotobuf is not defined")
endif()
# libprime_server
# see https://gitlab.kitware.com/cmake/cmake/-/issues/19467
set(libprime_server_targets "")
if(ENABLE_SERVICES)
pkg_check_modules(libprime_server IMPORTED_TARGET libprime_server>=0.6.3)
if (libprime_server_FOUND)
target_compile_definitions(PkgConfig::libprime_server INTERFACE ENABLE_SERVICES)
set(libprime_server_targets PkgConfig::libprime_server)
else()
set(ENABLE_SERVICES OFF)
message(FATAL_ERROR "ENABLE_SERVICES=ON but prime_server not found...")
endif()
endif()
## Mjolnir and associated executables
if(ENABLE_DATA_TOOLS)
add_compile_definitions(DATA_TOOLS)
# keep sqlite3 with cmake find_package(), as OSX needs our own FindSqlite3.cmake
# otherwise the system sqlite3 is found which doesn't allow for spatialite
find_package(SQLite3 REQUIRED)
pkg_check_modules(SpatiaLite REQUIRED IMPORTED_TARGET spatialite)
pkg_check_modules(LuaJIT REQUIRED IMPORTED_TARGET luajit)
endif()
if (ENABLE_THREAD_SAFE_TILE_REF_COUNT)
add_definitions(-DENABLE_THREAD_SAFE_TILE_REF_COUNT)
endif ()
## libvalhalla
add_subdirectory(src)
## Python bindings
if(ENABLE_PYTHON_BINDINGS)
# python is fine for cmake as well
find_package(Python COMPONENTS Development Interpreter)
if (Python_FOUND)
add_subdirectory(src/bindings/python)
install(FILES COPYING CHANGELOG.md
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/python-valhalla"
COMPONENT python)
else()
set(ENABLE_PYTHON_BINDINGS OFF)
message(WARNING "Python development version not found, skipping Python bindings...")
endif()
endif()
## Executable targets
## Valhalla programs
set(valhalla_programs valhalla_run_map_match valhalla_benchmark_loki valhalla_benchmark_skadi
valhalla_run_isochrone valhalla_run_route valhalla_benchmark_adjacency_list valhalla_run_matrix
valhalla_path_comparison valhalla_export_edges valhalla_expand_bounding_box valhalla_service)
## Valhalla data tools
set(valhalla_data_tools valhalla_build_statistics valhalla_ways_to_edges valhalla_validate_transit
valhalla_benchmark_admins valhalla_build_connectivity valhalla_build_tiles valhalla_build_admins
valhalla_convert_transit valhalla_ingest_transit valhalla_query_transit valhalla_add_predicted_traffic
valhalla_assign_speeds valhalla_add_elevation valhalla_build_landmarks valhalla_add_landmarks)
## Valhalla services
set(valhalla_services valhalla_loki_worker valhalla_odin_worker valhalla_thor_worker)
if(ENABLE_TOOLS)
foreach(program ${valhalla_programs})
get_source_path(path ${program})
add_executable(${program} ${path})
set_target_properties(${program} PROPERTIES FOLDER "Tools")
create_source_groups("Source Files" ${path})
target_link_libraries(${program} valhalla)
target_include_directories(${program} PRIVATE ${cxxopts_include_dir})
install(TARGETS ${program} DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime)
endforeach()
endif()
if(ENABLE_DATA_TOOLS)
foreach(program ${valhalla_data_tools})
get_source_path(path ${program})
add_executable(${program} ${path})
create_source_groups("Source Files" ${path})
set_target_properties(${program} PROPERTIES FOLDER "Data Tools")
target_include_directories(${program} PRIVATE ${cxxopts_include_dir})
target_link_libraries(${program} valhalla)
if (LuaJIT_FOUND AND APPLE AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
# Using LuaJIT on macOS on Intel processors requires a couple of extra linker flags
target_link_options(${program} PUBLIC -pagezero_size 10000 -image_base 100000000)
endif()
install(TARGETS ${program} DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime)
endforeach()
# Target-specific dependencies
pkg_check_modules(GEOS REQUIRED IMPORTED_TARGET geos)
target_link_libraries(valhalla_build_admins PkgConfig::GEOS)
target_sources(valhalla_build_statistics
PUBLIC
${VALHALLA_SOURCE_DIR}/src/mjolnir/statistics.cc
${VALHALLA_SOURCE_DIR}/src/mjolnir/statistics_database.cc)
endif()
if(ENABLE_SERVICES)
foreach(program ${valhalla_services})
add_executable(${program} src/${program}.cc)
create_source_groups("Source Files" src/${program}.cc)
set_target_properties(${program} PROPERTIES FOLDER "Services")
target_link_libraries(${program} valhalla)
install(TARGETS ${program} DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime)
endforeach()
endif()
# add the scripts to the build folder as well
foreach(script valhalla_build_config valhalla_build_elevation
valhalla_build_extract valhalla_build_timezones)
configure_file(${VALHALLA_SOURCE_DIR}/scripts/${script} ${CMAKE_BINARY_DIR}/${script} COPYONLY)
install(
FILES
scripts/${script}
DESTINATION "${CMAKE_INSTALL_BINDIR}"
PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
COMPONENT runtime
)
endforeach()
install(FILES COPYING CHANGELOG.md
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
COMPONENT runtime)
# install third_party
install(DIRECTORY ${rapidjson_include_dir}/
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/valhalla/third_party")
install(DIRECTORY ${date_include_dir}/
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/valhalla/third_party")
if (WIN32)
install(DIRECTORY ${dirent_include_dir}/
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/valhalla/third_party")
endif()
if(ENABLE_TESTS)
add_subdirectory(test)
endif()
## Coverage report targets
if(ENABLE_COVERAGE)
find_program(GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat)
if(NOT GENHTML_PATH)
message(FATAL_ERROR "no genhtml installed")
endif()
set(FASTCOV_PATH ${VALHALLA_SOURCE_DIR}/third_party/fastcov/fastcov.py)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/coverage.info
COMMAND ${FASTCOV_PATH} -d . --exclude /usr/ third_party/ ${CMAKE_CURRENT_BINARY_DIR}/ --lcov -o coverage.info
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS check)
add_custom_target(coverage
COMMAND ${GENHTML_PATH} --prefix ${CMAKE_CURRENT_BINARY_DIR} --output-directory coverage --title "Test Coverage" --legend --show-details coverage.info
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/coverage.info)
set_target_properties(coverage PROPERTIES FOLDER "Tests")
endif()
## Packaging via CPack
include(CPackComponent)
string(TOLOWER "${CMAKE_PROJECT_NAME}" CPACK_PACKAGE_NAME)
set(CPACK_PACKAGE_VERSION_MAJOR ${VALHALLA_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${VALHALLA_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${VALHALLA_VERSION_PATCH})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}${CPACK_PACKAGE_VERSION_SUFFIX}")
set(CPACK_PACKAGE_CONTACT "Team Valhalla <valhalla@mapzen.com>")
set(CPACK_RESOURCE_FILE_LICENSE "${VALHALLA_SOURCE_DIR}/LICENSE.md")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "OpenStreetMap Routing API
A set of routing APIs designed around OSM map data using
dynamic costing and a tiled data structure")
set(CPACK_COMPONENT_PYTHON_DESCRIPTION "OpenStreetMap Routing Python Bindings
A set routing APIs designed around OSM map data using
dynamic costing and a tiled data structure and
accompanying tools and services used to analyse and
compute routes using those APIs")
set(CPACK_STRIP_FILES TRUE)
set(CPACK_SOURCE_PACKAGE_FILE_NAME "libvalhalla")
if(${CPACK_GENERATOR} MATCHES "^DEB$")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/valhalla/")
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set(CPACK_DEBIAN_SHARED_PACKAGE_NAME "libvalhalla0")
set(CPACK_DEBIAN_SHARED_PACKAGE_SECTION "contrib/libs")
set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_NAME "libvalhalla-dev")
set(CPACK_DEBIAN_DEVELOPMENT_PACKAGE_DEPENDS "libvalhalla0 (= ${CPACK_PACKAGE_VERSION})")
set(CPACK_DEBIAN_RUNTIME_PACKAGE_NAME "valhalla-bin")
set(CPACK_DEBIAN_RUNTIME_PACKAGE_SECTION "contrib/misc")
set(CPACK_DEBIAN_RUNTIME_PACKAGE_DEPENDS "libvalhalla0 (= ${CPACK_PACKAGE_VERSION})")
set(CPACK_DEBIAN_PYTHON_PACKAGE_NAME "python-valhalla")
set(CPACK_DEBIAN_PYTHON_PACKAGE_SECTION "python")
set(CPACK_DEBIAN_PYTHON_PACKAGE_DEPENDS "libvalhalla0 (= ${CPACK_PACKAGE_VERSION})")
if("${CMAKE_CXX_LIBRARY_ARCHITECTURE}" MATCHES "arm-linux-gnueabihf")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE armhf)
endif()
message(STATUS "Configured deb packages of ${CMAKE_CXX_LIBRARY_ARCHITECTURE} build for ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
endif()
if(BUILD_SHARED_LIBS)
set(CPACK_COMPONENTS_ALL "shared;runtime;python")
else()
set(CPACK_COMPONENTS_ALL "development")
endif()
set(CPACK_PROJECT_CONFIG_FILE ${VALHALLA_SOURCE_DIR}/cmake/CPackConfig.cmake)
set(CPACK_DEBIAN_PACKAGE_DEBUG OFF)
include(CPack)
configure_file(cmake/uninstall.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/valhalla_uninstall.cmake @ONLY)
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/valhalla_uninstall.cmake)