Repository navigation
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
620 lines (564 loc) · 26.2 KB
/
Copy pathCMakeLists.txt
File metadata and controls
620 lines (564 loc) · 26.2 KB
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
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
#
# This MobilityDB code is provided under The PostgreSQL License.
# Copyright (c) 2016-2026, Université libre de Bruxelles and MobilityDB
# contributors
#
# MobilityDB includes portions of PostGIS version 3 source code released
# under the GNU General Public License (GPLv2 or later).
# Copyright (c) 2001-2026, PostGIS contributors
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose, without fee, and without a written
# agreement is hereby granted, provided that the above copyright notice and
# this paragraph and the following two paragraphs appear in all copies.
#
# IN NO EVENT SHALL UNIVERSITE LIBRE DE BRUXELLES BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
# LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
# EVEN IF UNIVERSITE LIBRE DE BRUXELLES HAS BEEN ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# UNIVERSITE LIBRE DE BRUXELLES SPECIFICALLY DISCLAIMS ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON
# AN "AS IS" BASIS, AND UNIVERSITE LIBRE DE BRUXELLES HAS NO OBLIGATIONS TO
# PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
#-------------------------------------
# MobilityDB/MEOS Main CMake file
#-------------------------------------
# Minimum Cmake version supporting fixtures
cmake_minimum_required(VERSION 3.12)
# Disallow in-source builds
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed.
Please make a new directory (called a build directory) and run CMake from there.
You may need to remove 'CMakeCache.txt' and 'CMakeFiles/'.")
endif()
# Set a default build type if none was specified
# https://www.kitware.com/cmake-and-the-default-build-type/
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# Specify search path for CMake modules to be loaded
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(CheckSymbolExists)
include(CheckCXXSymbolExists)
include(CheckCSourceRuns)
include(CMakeDependentOption)
#-------------------------------------
# RPATH settings
# https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling
#-------------------------------------
# use, i.e. don't skip the full RPATH for the build tree
# set(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
# set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
# set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
# set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# the RPATH to be used when installing, but only if it's not a system directory
# list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
# if("${isSystemDir}" STREQUAL "-1")
# set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# endif("${isSystemDir}" STREQUAL "-1")
# Windows build with MSVC
if(CMAKE_GENERATOR STREQUAL "Visual Studio 17 2022")
message(STATUS "Setting options for Visual Studio")
set(MSVC 1)
# Disable native language support
add_definitions(-DENABLE_NLS=0)
# Disable warning C4996: 'strcpy': This function or variable may be unsafe.
add_definitions(-D_CRT_SECURE_NO_WARNINGS=1)
endif()
#-------------------------------------
# Build MEOS or MobilityDB
#-------------------------------------
option(MEOS
"Set MEOS (default=OFF) to build the MEOS library instead of the MobilityDB
PostgreSQL extension
"
OFF
)
if(MEOS)
# Enable code specific to MEOS, typically user-oriented wrapper functions
# hiding internal implementation details from the API. Such functions are
# not used in the MobilityDB PostgreSQL extension.
message(STATUS "MEOS=1: Including user-facing MEOS API functions")
add_definitions(-DMEOS=1)
# On Windows the vendored PostgreSQL port headers select the win32 typedefs
# (uid_t/gid_t in port/win32_port.h, pulled in by port.h via "#if defined(WIN32)")
# from the bare WIN32 macro. The MEOS build omits pg_config_os.h (which would
# "#define WIN32"), and the C++ targets compile with strict -std=c++17, which
# (unlike -std=gnu++17 and the C targets' -std=gnu1x) does NOT predefine bare
# WIN32. Define it explicitly so the C and C++ MEOS translation units agree.
if(WIN32)
add_definitions(-DWIN32)
endif()
# Linkage of the standalone library. ON (the default) keeps the historical
# behaviour: a shared libmeos.so/.dylib that consumers resolve at load time.
# OFF builds a self-contained static libmeos.a instead, for consumers that
# embed MEOS in a single relocatable module and therefore cannot ship a
# sidecar shared library next to it — a DuckDB extension, a Python wheel, or
# any other plugin distributed as one file. BUILD_SHARED_LIBS is the standard
# CMake spelling, so package managers that already drive it (vcpkg maps the
# triplet's VCPKG_LIBRARY_LINKAGE onto it) select the right linkage with no
# project-specific option. Every add_library() in this tree names its type
# explicitly, so this variable only ever reaches the libmeos target below.
option(BUILD_SHARED_LIBS "Set ON|OFF (default=ON) to build libmeos as a shared library; OFF builds a self-contained static libmeos" ON)
if(NOT BUILD_SHARED_LIBS)
# The static libmeos exists to be linked into someone else's shared module,
# so every object it carries must be position-independent. The individual
# object libraries set this only case by case (liblwgeom, ryu, geo),
#, which is enough for a shared build that links them directly but not
# for an archive that is relocated into a downstream .so/.dylib.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
else()
message(STATUS "MEOS=0: Building MEOS core for MobilityDB (internal API only)")
add_definitions(-DMEOS=0)
endif()
# Options for including the various optional types.
# ALL is a single switch that enables every optional family at once, so present
# and future families are all built without enumerating each -D<FAMILY>=ON (the
# same convention as the documentation build's LANG_ALL). Families that need an
# external library (H3 requires libh3, POINTCLOUD requires pgpointcloud) still
# require that library on the build path when ALL=ON.
option(ALL "Set ON|OFF (default=OFF) to include all the optional families" OFF)
option(CBUFFER "Set ON|OFF (default=OFF) to include circular buffers" OFF)
option(H3 "Set ON|OFF (default=OFF) to include the temporal H3 index type (th3index). Requires libh3 on the build path." OFF)
option(JSON "Set ON|OFF (default=ON) to include json types" ON)
option(NPOINT "Set ON|OFF (default=ON) to include network points" ON)
option(POINTCLOUD "Set ON|OFF (default=OFF) to include pgpointcloud temporal types" OFF)
option(POSE "Set ON|OFF (default=OFF) to include geoposes" OFF)
CMAKE_DEPENDENT_OPTION(RGEO "Set ON|OFF (default=OFF) to include rigid geometries" ON "POSE" OFF)
# Option for including the temporal CARTO QUADBIN index type (`tquadbin`).
# quadbin has no external dependency: its cell algebra is implemented
# first-party in meos/src/quadbin/ (libm only), so no find_library /
# vendored subtree is needed.
option(QUADBIN "Set ON|OFF (default=OFF) to include the temporal QUADBIN index type (tquadbin)" OFF)
# Option for sampling PostGIS raster bands along trajectories.
# Requires the postgis_raster extension (ships with postgresql-N-postgis-3), and
# QUADBIN, since a Raquet tile is identified by a quadbin cell.
CMAKE_DEPENDENT_OPTION(RASTER "Set ON|OFF (default=OFF) to include PostGIS raster sampling operators" OFF "QUADBIN" OFF)
# Option for including the temporal Google S2 index type (`ts2cell`).
# S2 has no maintained C API, so its cell algebra is implemented first-party in
# meos/src/s2cell/ (libm only) from the published cell-id specification, the same
# model as quadbin, and no find_library / vendored subtree is needed.
# The family is spelled `s2cell`, after its static type, so that the option, the
# source directory and the public header carry one token as every other family
# does. The grid's own name cannot: a bare `S2` is a stab-line endpoint in the
# vendored PostGIS geodetic code (liblwgeom/lwgeodetic.c, lwgeodetic_tree.c),
# which a build-wide -DS2=0|1 rewrites into a numeric constant.
option(S2CELL "Set ON|OFF (default=OFF) to include the temporal Google S2 index type (ts2cell)" OFF)
# SIBLING-FROM doc/CMakeLists.txt (LANG_ALL): enable every optional family when
# ALL is set. A new family must be added to this list, the same maintenance model
# as adding a language to the documentation build's PROJECT_SUPPORTED_LANGUAGES.
# POSE precedes RGEO because it depends on it.
#
# The literal names stay on the `foreach` line: this block is what the ecosystem
# reads for the family set — MEOS-API's parser/families.py, from which every
# binding projects, and the strict build's own family flags — so a variable in
# their place answers them with its own name instead of the families.
if(ALL)
foreach(_family CBUFFER H3 JSON NPOINT POINTCLOUD POSE RGEO QUADBIN RASTER S2CELL)
set(${_family} ON CACHE BOOL "Enabled by ALL=ON" FORCE)
endforeach()
endif()
# The JSON types are derived from PostgreSQL 18 and require a PostgreSQL 18
# server. For the MobilityDB extension, detect the server version and disable
# JSON on older PostgreSQL. The standalone MEOS library vendors PostgreSQL 18,
# so JSON stays available there.
if(NOT MEOS AND JSON)
find_package(POSTGRESQL QUIET)
if(DEFINED POSTGRESQL_VERSION_MAJOR AND POSTGRESQL_VERSION_MAJOR LESS 18)
message(STATUS "JSON types require PostgreSQL 18; disabling JSON for PostgreSQL ${POSTGRESQL_VERSION_MAJOR}")
set(JSON OFF)
endif()
endif()
# Set the compilation flags when including the various optional types
if(CBUFFER)
message(STATUS "Including circular buffers")
add_definitions(-DCBUFFER=1)
else()
message(STATUS "Excluding circular buffers")
add_definitions(-DCBUFFER=0)
endif()
if(H3)
message(STATUS "Including temporal H3 index (th3index)")
add_definitions(-DH3=1)
else()
message(STATUS "Excluding temporal H3 index")
add_definitions(-DH3=0)
endif()
if(JSON)
message(STATUS "Including JSON types")
add_definitions(-DJSON=1)
else()
message(STATUS "Excluding JSON types")
add_definitions(-DJSON=0)
endif()
if(NPOINT)
message(STATUS "Including network points")
add_definitions(-DNPOINT=1)
else()
message(STATUS "Excluding network points")
add_definitions(-DNPOINT=0)
endif()
if(POINTCLOUD)
message(STATUS "Including pgpointcloud types")
add_definitions(-DPOINTCLOUD=1)
else()
message(STATUS "Excluding pgpointcloud types")
add_definitions(-DPOINTCLOUD=0)
endif()
if(POSE)
message(STATUS "Including geoposes")
add_definitions(-DPOSE=1)
else()
message(STATUS "Excluding geoposes")
add_definitions(-DPOSE=0)
endif()
if(QUADBIN)
message(STATUS "Including temporal QUADBIN index (tquadbin)")
add_definitions(-DQUADBIN=1)
else()
message(STATUS "Excluding temporal QUADBIN index")
add_definitions(-DQUADBIN=0)
endif()
if(RASTER)
message(STATUS "Including PostGIS raster sampling operators")
add_definitions(-DRASTER=1)
else()
message(STATUS "Excluding PostGIS raster sampling operators")
add_definitions(-DRASTER=0)
endif()
if(RGEO)
message(STATUS "Including rigid geometries")
add_definitions(-DRGEO=1)
else()
message(STATUS "Excluding rigid geometries")
add_definitions(-DRGEO=0)
endif()
if(S2CELL)
message(STATUS "Including temporal Google S2 index (ts2cell)")
add_definitions(-DS2CELL=1)
else()
message(STATUS "Excluding temporal Google S2 index")
add_definitions(-DS2CELL=0)
endif()
# Build the 'requires =' clause for the generated mobilitydb.control file
# from the same flags that gate C compilation and SQL inclusion. PostGIS
# is always required; pgPointCloud is required only when POINTCLOUD=ON,
# because that is the only flag that maps to an external extension.
# CBUFFER / NPOINT / POSE / RGEO add internal types that live inside
# libMobilityDB itself with no extra CREATE EXTENSION dependency.
set(MOBILITYDB_REQUIRES "postgis")
if(H3)
set(MOBILITYDB_REQUIRES "${MOBILITYDB_REQUIRES}, h3")
endif()
if(POINTCLOUD)
set(MOBILITYDB_REQUIRES "${MOBILITYDB_REQUIRES}, pointcloud")
endif()
if(RASTER)
set(MOBILITYDB_REQUIRES "${MOBILITYDB_REQUIRES}, postgis_raster")
endif()
# Get the MobilityDB major/minor/micro versions from the text file
file(READ mobdb_version.txt ver)
string(REGEX MATCH "MOBILITYDB_MAJOR_VERSION=([0-9]+)" _ ${ver})
set(MOBILITYDB_MAJOR_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "MOBILITYDB_MINOR_VERSION=([0-9]+)" _ ${ver})
set(MOBILITYDB_MINOR_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "MOBILITYDB_MICRO_VERSION=([0-9]+)" _ ${ver})
set(MOBILITYDB_MICRO_VERSION ${CMAKE_MATCH_1})
string(REGEX MATCH "MOBILITYDB_MICRO_VERSION=[0-9]+(beta?[0-9]+)" _ ${ver})
set(PROJECT_VERSION_DEV ${CMAKE_MATCH_1})
# Set the project name and project version
project(MobilityDB
VERSION ${MOBILITYDB_MAJOR_VERSION}.${MOBILITYDB_MINOR_VERSION}.${MOBILITYDB_MICRO_VERSION}
LANGUAGES C)
message(STATUS "Building MobilityDB version ${PROJECT_VERSION}")
# Enable testing, must follow project() call above
include(CTest)
# Make CTest run verbose for the output of the failed tests
set(CMAKE_CTEST_ARGUMENTS "--output-on-failure")
enable_testing()
# Locate libh3 for the temporal H3 index. This must follow project() so the
# C toolchain's default library search paths are populated.
if(H3)
find_library(H3_LIBRARY NAMES h3)
# PATH_SUFFIXES h3 — pgdg's libh3-dev installs to /usr/include/h3/h3api.h
# (subdirectory) rather than /usr/include/h3api.h. Add the suffix so
# find_path catches both layouts.
find_path(H3_INCLUDE_DIR NAMES h3api.h PATH_SUFFIXES h3)
if(NOT H3_LIBRARY OR NOT H3_INCLUDE_DIR)
message(FATAL_ERROR
"H3=ON was requested but libh3 was not found.\n"
"Install libh3 (https://github.com/uber/h3) or pass\n"
" -DH3_LIBRARY=/path/to/libh3.so -DH3_INCLUDE_DIR=/path/to/h3api.h\n"
"to cmake.")
endif()
# A static libh3.a built without -fPIC links fine into an executable but
# fails the final MobilityDB .so link with a cryptic
# relocation R_X86_64_PC32 ... can not be used when making a shared object;
# recompile with -fPIC
# error. Reproduce that link here (force every archive member in with
# --whole-archive, ignore unresolved externals so only relocation errors can
# fail it) and turn it into an actionable message. Only meaningful for an ELF
# static archive with a GNU-style linker; shared libs and other platforms are
# unaffected and skipped. Cached per resolved path so it runs only once.
if(H3_LIBRARY MATCHES "\\.a$" AND CMAKE_SYSTEM_NAME STREQUAL "Linux"
AND NOT "${H3_STATIC_PIC_OK}" STREQUAL "${H3_LIBRARY}")
set(_h3_probe "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/h3_pic_probe.so")
execute_process(
COMMAND ${CMAKE_C_COMPILER} -shared -fPIC
-Wl,--whole-archive "${H3_LIBRARY}" -Wl,--no-whole-archive
-Wl,--unresolved-symbols=ignore-all
-o "${_h3_probe}"
RESULT_VARIABLE _h3_link_rv
OUTPUT_VARIABLE _h3_link_out
ERROR_VARIABLE _h3_link_err)
file(REMOVE "${_h3_probe}")
if(_h3_link_err MATCHES "recompile with -fPIC" OR
_h3_link_err MATCHES "can not be used when making a shared object")
message(FATAL_ERROR
"The libh3 static archive found at\n"
" ${H3_LIBRARY}\n"
"was built without position-independent code (-fPIC) and cannot be "
"linked into the shared MobilityDB library. Fix it by either:\n"
" * installing a shared libh3 (build H3 with -DBUILD_SHARED_LIBS=ON), or\n"
" * rebuilding the static archive with -DCMAKE_POSITION_INDEPENDENT_CODE=ON\n"
" and pointing cmake at it via -DH3_LIBRARY=/path/to/pic/libh3.a\n")
endif()
# Passed (or the linker gave no PIC diagnostic): remember it so re-configures
# skip the probe unless H3_LIBRARY changes.
set(H3_STATIC_PIC_OK "${H3_LIBRARY}" CACHE INTERNAL
"libh3 static archive validated as position-independent")
endif()
include_directories(${H3_INCLUDE_DIR})
endif()
set(MOBILITYDB_VERSION "${PROJECT_VERSION}")
set(MOBILITYDB_VERSION_STRING "${CMAKE_PROJECT_NAME} ${PROJECT_VERSION}${PROJECT_VERSION_DEV}")
add_definitions(-DMOBILITYDB_VERSION_STRING="${MOBILITYDB_VERSION_STRING}")
message(STATUS "MOBILITYDB_VERSION_STRING = '${MOBILITYDB_VERSION_STRING}'")
# Comment out code used for debugging purposes so it is not concerned by the coverage
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
add_definitions(-DDEBUG_BUILD)
endif()
#-------------------------------------
# Set compiler flags
#-------------------------------------
# Generate position-independent code (PIC)
include(CheckCCompilerFlag)
if(NOT WIN32)
CHECK_C_COMPILER_FLAG("-fPIC" C_COMPILER_SUPPORTS_FPIC)
if(C_COMPILER_SUPPORTS_FPIC)
message(STATUS "Compiling into position-independent code (PIC)")
add_definitions(-fPIC)
endif()
endif()
# FFSL functions for finding the first (least significant) bit
check_symbol_exists(ffsl "string.h" HAS_FFSL)
if(NOT HAS_FFSL)
message(STATUS "No ffsl functions provided")
add_definitions(-DNO_FFSL)
endif()
# TODO
# Reentrant (_r) functions for POSIX hash table management (e.g. hsearch)
# check_symbol_exists("hsearch_r" "search.h" HAS_HSEARCH_R)
# if(NOT HAS_HSEARCH_R)
# add_definitions(-DNO_HSEARCH_R)
# endif()
# Added to build on Windows to avoid the error 'M_PI': undeclared identifier
add_compile_definitions(_USE_MATH_DEFINES)
# The Windows GDI header defines PC_NONE as a palette constant, which is also
# the first enumerator of the pgPointCloud compression enum, so a translation
# unit reading both parses "0 = 0," in place of the enumerator. NOGDI keeps the
# drawing interface out of windows.h, which no target here draws through.
if(WIN32)
add_compile_definitions(NOGDI)
endif()
# Set default compile flags and code coverage for GCC
if(CMAKE_COMPILER_IS_GNUCC)
# MobilityDB compiler flags valid for both C and C++
add_compile_options(-Wall -Wextra -Wunused-parameter -Wno-strict-aliasing)
# The following flags are C-only: the C++ compiler rejects -std=gnu1x and an
# implicit function declaration is a C-specific construct. Gating them to the
# C language keeps the C++ translation units (PostGIS/GEOS wrappers and the
# linked shared module) free of cc1plus command-line option warnings.
# Treating an implicit function declaration as an error matters because it
# silently assumes an int return, truncating any 64-bit pointer the callee
# actually returns and producing a hard-to-trace crash at runtime rather than
# at build time.
add_compile_options(
"$<$<COMPILE_LANGUAGE:C>:-std=gnu1x>"
"$<$<COMPILE_LANGUAGE:C>:-Werror=implicit-function-declaration>"
"$<$<COMPILE_LANGUAGE:C>:-Werror=implicit-int>")
# -Wno-strict-aliasing was removed to access directly PostGIS points
# See file tpoint_spatialfuncs.h
# add_definitions(-Wall -Wextra -std=gnu1x -Wno-unused-parameter)
# Code coverage
if(WITH_COVERAGE)
message(STATUS "Generating code coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage")
# The link does not pull libgcov from the compile flags, so --coverage goes
# to the linker as well.
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --coverage")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
endif()
endif()
# Set compiler optimizations for release
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2")
# Disable compiler optimizations for debugging
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
# Assertion checking, the counterpart of PostgreSQL's --enable-cassert.
#
# An assertion states a precondition that an internal function trusts, the
# public function above it having already tested the same constraint with the
# VALIDATE_* macros. A production build compiles the assertions out, since
# re-testing a precondition in the loops over the instants of a sequence or the
# elements of a set would pay for it a second time. The option is therefore OFF
# by default and a release keeps its current flags.
#
# cmake defines NDEBUG in every configuration except Debug, which ties whether
# the assertions are checked to the optimization level. CASSERT separates the
# two: a build can be optimized and still check its preconditions, and a
# session under a debugger can keep them without giving up -O2.
option(CASSERT
"Set ON|OFF (default=OFF) to check the assertions stating the preconditions \
of the internal functions. A production build compiles them out." OFF)
if(CASSERT)
message(STATUS "Assertion checking enabled")
foreach(config "" _DEBUG _RELEASE _RELWITHDEBINFO _MINSIZEREL)
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS${config}
"${CMAKE_C_FLAGS${config}}")
endforeach()
endif()
# Check machine architecture: big endian vs. little endian
# Needed for WKB support in MobilityDB and PostGIS (file postgis_config.h.in)
include(TestBigEndian)
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
message(STATUS "BIG_ENDIAN")
add_definitions(-DMEOS_IS_BIG_ENDIAN=1)
set(DEF_WORDS_BIGENDIAN ON)
else()
message(STATUS "LITTLE_ENDIAN")
add_definitions(-DMEOS_IS_BIG_ENDIAN=0)
unset(DEF_WORDS_BIGENDIAN)
endif()
# check for needed Header files and functions
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
check_symbol_exists(strchrnul "string.h" HAVE_STRCHRNUL)
unset(CMAKE_REQUIRED_DEFINITIONS)
check_symbol_exists(__get_cpuid "cpuid.h" HAVE__GET_CPUID)
check_c_source_runs("
#include <stdint.h>
int main() {
uint64_t x = 1, r;
__asm__ (\"popcntq %1, %0\" : \"=r\"(r) : \"r\"(x));
return 0;
}" HAVE_X86_64_POPCNTQ)
#--------------------------------
# Other dependencies
#--------------------------------
# The vendored PostGIS reads the GEOS version to decide which GEOS entry points
# it may call, and at 0 calls none of those a version gates
set(POSTGIS_GEOS_VERSION 0)
# The vendored PostGIS reads geos_c.h for the types of the entry points that
# convert between the two geometry models. This directory stands in for it,
# holding those types and nothing else, so no vendored source is edited and a
# build needs no GEOS headers installed
include_directories(BEFORE SYSTEM ${CMAKE_SOURCE_DIR}/meos/include/geos-none)
# Proj reprojection library
# The version is required as a plain check rather than as an argument to
# find_package: PROJ's own package configuration accepts a requested version
# only when its major number equals the installed one, so a minimum expressed
# there would reject every later major release.
find_package(PROJ REQUIRED)
include_directories(SYSTEM ${PROJ_INCLUDE_DIRS})
math(EXPR POSTGIS_PROJ_VERSION "${PROJ_VERSION_MAJOR} * 10 + ${PROJ_VERSION_MINOR}")
if(POSTGIS_PROJ_VERSION LESS 61)
message(FATAL_ERROR "PROJ 6.1 or later is required, ${PROJ_VERSION} found. The "
"transform path applies the axis order a visualisation expects through "
"proj_normalize_for_visualization(), which PROJ publishes from 6.1.0 on.")
endif()
message(STATUS "POSTGIS_PROJ_VERSION: ${POSTGIS_PROJ_VERSION}")
# JSON-C library (used for MF-JSON input/output)
find_package(JSON-C REQUIRED)
include_directories(SYSTEM ${JSON-C_INCLUDE_DIRS})
message(STATUS "JSON-C_INCLUDE_DIRS: ${JSON-C_INCLUDE_DIRS}")
message(STATUS "JSON-C_LIBRARIES: ${JSON-C_LIBRARIES}")
#----------------------------------------------
# Configure PostGIS with optional dependencies
#----------------------------------------------
if(RASTER)
find_package(GDAL REQUIRED)
message(STATUS "GDAL version '${GDAL_VERSION}' found (required by RASTER)")
endif()
find_package(LibXml2)
if(LibXml2_FOUND)
message(STATUS "LibXml2 version ${LIBXML2_VERSION_STRING} found")
else()
message(STATUS "LibXml2 not found")
endif()
# find_package(Protobuf REQUIRED)
find_package(Protobuf QUIET)
if(Protobuf_FOUND)
# Note that ${Protobuf_VERSION_STRING} is not set
if (Protobuf_INCLUDE_DIR AND EXISTS "${Protobuf_INCLUDE_DIR}/google/protobuf/stubs/common.h")
set(_Protobuf_VERSION_REGEX "^#define[ \t]+GOOGLE_PROTOBUF_VERSION[ \t]+([0-9]+).*$")
file(STRINGS "${Protobuf_INCLUDE_DIR}/google/protobuf/stubs/common.h" Protobuf_VERSION REGEX "${_Protobuf_VERSION_REGEX}")
if(Protobuf_VERSION MATCHES ${_Protobuf_VERSION_REGEX})
set(Protobuf_VERSION "${CMAKE_MATCH_1}")
math(EXPR Protobuf_VERSION_MAJOR "${Protobuf_VERSION} / 1000000")
math(EXPR Protobuf_VERSION_MINOR "${Protobuf_VERSION} / 1000 % 1000")
math(EXPR Protobuf_VERSION_PATCH "${Protobuf_VERSION} % 1000")
set(Protobuf_VERSION_STRING "${Protobuf_VERSION_MAJOR}.${Protobuf_VERSION_MINOR}.${Protobuf_VERSION_PATCH}")
endif()
message(STATUS "Protobuf version '${Protobuf_VERSION_STRING}' found")
unset(_Protobuf_VERSION_REGEX)
endif()
else()
message(STATUS "Protobuf not found")
endif()
find_package(Gettext QUIET)
if(GETTEXT_FOUND)
message(STATUS "GETTEXT version '${GETTEXT_VERSION_STRING}' found")
else()
message(STATUS "GETTEXT not found")
endif()
find_package(ICU QUIET)
if(ICU_FOUND)
message(STATUS "ICU Version '${ICU_VERSION}' found")
else()
message(STATUS "ICU NOT found")
endif()
#-------------------------------------
# Build either MobilityDB or MEOS
#-------------------------------------
add_subdirectory(pgtypes)
add_subdirectory(postgis)
add_subdirectory(meos)
if(NOT MEOS)
add_subdirectory(mobilitydb)
endif()
#-----------------------------------------------------------------------------
# Documentation
#-----------------------------------------------------------------------------
add_subdirectory(doc)
add_subdirectory(doxygen)
#-----------------------------------------------------------------------------
# The End
#-----------------------------------------------------------------------------