mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
configure died at src/CMakeLists.txt:127, "Cannot specify link libraries for
target clickhouse_compression which is not built by this project". Two lines
above, add_library creates datastore_compression. The rename reached the
definition and not the reference, and the miss survived because line 127 sits
behind `if (TARGET ch_contrib::sz3)` — it is only evaluated once SZ3 configures,
which nothing in this pipeline had ever got far enough to do.
Fixing that one line would only have surfaced the next, so this is the whole
class rather than the instance. Two sweeps, because one of them is not enough:
diffing every name referenced as the first argument of target_link_libraries /
target_include_directories / target_compile_* / add_dependencies /
set_target_properties against every name created by add_library / add_executable
/ add_custom_target finds 15 undefined, of which 13 are legitimate — corrosion
builds _cargo, _ch_rust_*, delta_kernel_ffi and chdig via corrosion_import_crate,
and google_cloud_cpp_* comes from functions in its own contrib cmake. That leaves
clickhouse_compression and clickhouse_common_io. But a first-argument diff cannot
see a stale name in a dependency LIST or a call to a command that no longer
exists, so the occurrence-level pass matters too and finds both.
Ten occurrences, all of them the same missed rename:
- undefined target, first arg, fatal at configure: src/CMakeLists.txt 127, 570, 578
- undefined names inside unit_tests_dbms's link list: 939, 940, 941. These fail
at LINK, not configure, and only when ENABLE_TESTS=1, so this pipeline would
never have reported them.
- calls to clickhouse_add_executable, which does not exist — the macro is
datastore_add_executable (CMakeLists.txt:668): benchmarks:26, fuzzers:22.
- inert: src/CMakeLists.txt:498 passes a name to add_object_library, whose body
ignores it entirely and only calls add_headers_and_sources(dbms ...); and a
comment at CMakeLists.txt:379 naming the old macro. Neither can break a build;
both are renamed so the next reader cannot mistake them for the live kind.
Renamed on evidence, not on the prefix: ch_contrib::* aliases and upstream contrib
targets keep their names, and every name changed here was confirmed undefined in
the tree with a defined datastore_* counterpart.
835 lines
39 KiB
CMake
835 lines
39 KiB
CMake
cmake_minimum_required(VERSION 3.25)
|
|
|
|
# Some CMakeLists.txt in contrib/ are not being good citizens and change cmake cache variables
|
|
# globally. This policy prevents such *cache* variable assignments from altering *normal* variables
|
|
# that we've set.
|
|
#
|
|
# Example: suppose our root CMakeLists.txt assigns a normal variable:
|
|
# set(CMAKE_CXX_STANDARD 23)
|
|
# then llvm-project assigns cache variable with the same name:
|
|
# set(CMAKE_CXX_STANDARD 17 CACHE STRING "...")
|
|
# The latter assignment doesn't affect the normal variable, so llvm-project effectively uses C++23.
|
|
#
|
|
# Without this policy, the behavior is nonlocal and brittle: if the cache variable doesn't exists,
|
|
# the normal variable is unset; otherwise it's left alone. So the effective value would depend e.g.
|
|
# on the order in which contrib/ libraries are traversed.
|
|
set (CMAKE_POLICY_DEFAULT_CMP0126 NEW)
|
|
|
|
project(Datastore LANGUAGES C CXX ASM)
|
|
|
|
# If turned off: e.g. when ENABLE_FOO is ON, but FOO tool was not found, the CMake will continue.
|
|
option(FAIL_ON_UNSUPPORTED_OPTIONS_COMBINATION
|
|
"Stop/Fail CMake configuration if some ENABLE_XXX option is defined (either ON or OFF)
|
|
but is not possible to satisfy" ON)
|
|
|
|
# This allows to compile some code conditionally in the private build while having byte-identical source files.
|
|
set (DATASTORE_CLOUD 0)
|
|
|
|
if(FAIL_ON_UNSUPPORTED_OPTIONS_COMBINATION)
|
|
set(RECONFIGURE_MESSAGE_LEVEL FATAL_ERROR)
|
|
else()
|
|
set(RECONFIGURE_MESSAGE_LEVEL WARNING)
|
|
endif()
|
|
|
|
include (cmake/arch.cmake)
|
|
include (cmake/target.cmake)
|
|
include (cmake/tools.cmake)
|
|
include (cmake/ccache.cmake)
|
|
include (cmake/clang_tidy.cmake)
|
|
include (cmake/git.cmake)
|
|
include (cmake/utils.cmake)
|
|
|
|
# This is needed to set up the CMAKE_INSTALL_BINDIR variable.
|
|
include (GNUInstallDirs)
|
|
|
|
# Ignore export() since we don't use it,
|
|
# but it gets broken with global targets via link_libraries()
|
|
macro (export)
|
|
endmacro ()
|
|
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS 1) # Write compile_commands.json
|
|
set(CMAKE_LINK_DEPENDS_NO_SHARED 1) # Do not relink all depended targets on .so
|
|
|
|
# Enable the ability to organize targets into hierarchies of "folders" for capable GUI-based IDEs.
|
|
# For more info see https://cmake.org/cmake/help/latest/prop_gbl/USE_FOLDERS.html
|
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
|
|
|
# Check that submodules are present
|
|
if (NOT EXISTS "${Datastore_SOURCE_DIR}/contrib/sysroot/README.md")
|
|
message (FATAL_ERROR "Submodules are not initialized. Run\n\tgit submodule update --init")
|
|
endif ()
|
|
|
|
option(ENABLE_CHECK_HEAVY_BUILDS "Don't allow C++ translation units to compile too long or to take too much memory while compiling." OFF)
|
|
if (ENABLE_CHECK_HEAVY_BUILDS)
|
|
enable_heavy_build_check_if_needed()
|
|
endif ()
|
|
|
|
if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None")
|
|
set (CMAKE_BUILD_TYPE "RelWithDebInfo")
|
|
message (STATUS "CMAKE_BUILD_TYPE is not set, set to default = ${CMAKE_BUILD_TYPE}")
|
|
endif ()
|
|
message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
|
|
|
string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
|
|
|
|
list(REVERSE CMAKE_FIND_LIBRARY_SUFFIXES)
|
|
|
|
option (ENABLE_FUZZING "Fuzzy testing using libfuzzer" OFF)
|
|
option (ENABLE_BUZZHOUSE "Enable BuzzHouse fuzzer on the client" OFF)
|
|
option (ENABLE_FUZZER_TEST "Build testing fuzzers in order to test libFuzzer functionality" OFF)
|
|
|
|
if (ENABLE_FUZZING)
|
|
message (STATUS "Fuzzing instrumentation enabled")
|
|
set (FUZZER "libfuzzer")
|
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib++")
|
|
set (ENABLE_SSL 1)
|
|
set (ENABLE_EXAMPLES 0)
|
|
set (ENABLE_UTILS 0)
|
|
set (ENABLE_THINLTO 0)
|
|
set (ENABLE_TCMALLOC 0)
|
|
set (ENABLE_JEMALLOC 0)
|
|
set (ENABLE_CHECK_HEAVY_BUILDS 1)
|
|
set (GLIBC_COMPATIBILITY OFF)
|
|
set (ENABLE_BENCHMARKS 0)
|
|
set (ENABLE_DATASTORE_KEEPER 0)
|
|
|
|
# For codegen_select_fuzzer
|
|
set (ENABLE_PROTOBUF 1)
|
|
endif()
|
|
|
|
if (ENABLE_BUZZHOUSE)
|
|
set (ENABLE_SSL 1)
|
|
set (ENABLE_PROTOBUF 1)
|
|
endif()
|
|
|
|
option (ENABLE_XRAY "Enable LLVM XRay" OFF)
|
|
|
|
if (NOT ENABLE_XRAY)
|
|
message (STATUS "Not using LLVM XRay because it's disabled")
|
|
set (ENABLE_XRAY 0)
|
|
endif()
|
|
|
|
if (NOT ((ARCH_AMD64 OR ARCH_AARCH64) AND OS_LINUX) OR SANITIZE OR USE_MUSL)
|
|
message (STATUS "Not using LLVM XRay, only Linux on amd64 and aarch64 is supported without sanitizers")
|
|
set (ENABLE_XRAY 0)
|
|
endif()
|
|
|
|
# Global libraries
|
|
# See:
|
|
# - default_libs.cmake
|
|
# - sanitize.cmake
|
|
add_library(global-libs INTERFACE)
|
|
|
|
include (cmake/sanitize.cmake)
|
|
include (cmake/profile_optimization.cmake)
|
|
|
|
option(ENABLE_COLORED_BUILD "Enable colors in compiler output" ON)
|
|
|
|
set (CMAKE_COLOR_MAKEFILE ${ENABLE_COLORED_BUILD}) # works only for the makefile generator
|
|
|
|
if (ENABLE_COLORED_BUILD AND CMAKE_GENERATOR STREQUAL "Ninja")
|
|
# Turn on colored output. https://github.com/ninja-build/ninja/wiki/FAQ
|
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
|
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
|
|
# ... such manually setting of flags can be removed once CMake supports a variable to
|
|
# activate colors in *all* build systems: https://gitlab.kitware.com/cmake/cmake/-/issues/15502
|
|
# --> available since CMake 3.24: https://stackoverflow.com/a/73349744
|
|
endif ()
|
|
|
|
include (cmake/add_warning.cmake)
|
|
|
|
# A compiler without zlib accepts -gz but only warns, so -Werror on that warning makes the check fail.
|
|
include (CheckCompilerFlag)
|
|
set (CMAKE_REQUIRED_FLAGS "-Werror=debug-compression-unavailable")
|
|
check_compiler_flag (C "-gz=zlib" C_COMPILER_SUPPORTS_GZ_ZLIB)
|
|
check_compiler_flag (CXX "-gz=zlib" CXX_COMPILER_SUPPORTS_GZ_ZLIB)
|
|
unset (CMAKE_REQUIRED_FLAGS)
|
|
set (COMPILER_SUPPORTS_GZ_ZLIB OFF)
|
|
if (C_COMPILER_SUPPORTS_GZ_ZLIB AND CXX_COMPILER_SUPPORTS_GZ_ZLIB)
|
|
set (COMPILER_SUPPORTS_GZ_ZLIB ON)
|
|
endif ()
|
|
|
|
# Block build-time CMake probes (check_*, try_compile, try_run) project-wide. Compiler and
|
|
# toolchain are fixed (see cmake/tools.cmake), so feature detection is unnecessary - any
|
|
# version-dependent behaviour must be gated on CMAKE_CXX_COMPILER_VERSION explicitly.
|
|
include (cmake/block_build_time_checks.cmake)
|
|
|
|
option(ENABLE_TESTS "Provide unit_tests_dbms target with Google.Test unit tests" ON)
|
|
option(ENABLE_EXAMPLES "Build all example programs in 'examples' subdirectories" OFF)
|
|
option(ENABLE_BENCHMARKS "Build all benchmark programs in 'benchmarks' subdirectories" OFF)
|
|
|
|
if (OS_LINUX AND (ARCH_AMD64 OR ARCH_AARCH64) AND NOT USE_MUSL)
|
|
# Only for Linux, x86_64 or aarch64.
|
|
option(GLIBC_COMPATIBILITY "Enable compatibility with older glibc libraries." ON)
|
|
elseif(GLIBC_COMPATIBILITY)
|
|
message (${RECONFIGURE_MESSAGE_LEVEL} "Glibc compatibility cannot be enabled in current configuration")
|
|
endif ()
|
|
|
|
if (OS_LINUX)
|
|
# We should not export dynamic symbols, because:
|
|
# - The main datastore binary does not use dlopen,
|
|
# and whatever is poisoning it by LD_PRELOAD should not link to our symbols.
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-export-dynamic -Wl,--gc-sections")
|
|
|
|
if (LINKER_NAME MATCHES "lld" AND NOT SANITIZE AND NOT SANITIZE_COVERAGE AND NOT WITH_COVERAGE)
|
|
# Fold identical code and data sections to reduce binary size.
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--icf=all")
|
|
endif ()
|
|
|
|
# In Release builds, strip residual debug sections that may come from contrib
|
|
# libraries or Rust crates compiled with debug info by their own build systems.
|
|
if (CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE" AND NOT SPLIT_DEBUG_SYMBOLS)
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--strip-debug")
|
|
endif ()
|
|
endif ()
|
|
|
|
if (OS_DARWIN)
|
|
# Same reasoning as `--no-export-dynamic` on Linux: the main datastore binary does not
|
|
# use dlopen, so it does not need to export any dynamic symbols. By default the Mach-O
|
|
# linker puts every global symbol into the export trie (hundreds of thousands of them for
|
|
# datastore), which dyld walks for weak-symbol coalescing on every launch, adding ~0.15s
|
|
# of startup latency. An empty `-exported_symbols_list` suppresses the export trie while
|
|
# keeping the LC_SYMTAB used for backtraces intact. We use it instead of the simpler
|
|
# `-no_exported_symbols` because the latter is not understood by the cctools `ld` used for
|
|
# cross-compilation in CI, while `-exported_symbols_list` is supported by both it and lld.
|
|
#
|
|
# Skip this for sanitizer builds: on Darwin we rely on Apple's bundled sanitizer runtime,
|
|
# which resolves hooks such as `__asan_default_options` / `__lsan_default_suppressions`
|
|
# (see base/base/sanitizer_options.h) by symbol name via dyld weak-symbol coalescing.
|
|
# Hiding the executable's exports would silently drop those options. Sanitizer builds are
|
|
# for testing and do not need the startup optimization anyway.
|
|
if (NOT SANITIZE)
|
|
set (EMPTY_EXPORTED_SYMBOLS_LIST "${CMAKE_BINARY_DIR}/empty_exported_symbols.txt")
|
|
file (WRITE "${EMPTY_EXPORTED_SYMBOLS_LIST}" "")
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-exported_symbols_list,${EMPTY_EXPORTED_SYMBOLS_LIST}")
|
|
endif ()
|
|
|
|
# Remove unreachable functions/data (Darwin equivalent of --gc-sections).
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
|
|
|
|
# The `-all_load` flag forces loading of all symbols from all libraries,
|
|
# and leads to multiply-defined symbols. This flag allows force loading
|
|
# from a _specific_ library, which is what we need.
|
|
set(WHOLE_ARCHIVE -force_load)
|
|
# The `-noall_load` flag is the default and now obsolete.
|
|
set(NO_WHOLE_ARCHIVE "-undefined,error") # Effectively, a no-op. Here to avoid empty "-Wl, " sequence to be generated in the command line.
|
|
else ()
|
|
set(WHOLE_ARCHIVE --whole-archive)
|
|
set(NO_WHOLE_ARCHIVE --no-whole-archive)
|
|
endif ()
|
|
|
|
if (NOT (SANITIZE_COVERAGE OR WITH_COVERAGE)
|
|
AND (CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE"
|
|
OR CMAKE_BUILD_TYPE_UC STREQUAL "RELWITHDEBINFO"
|
|
OR CMAKE_BUILD_TYPE_UC STREQUAL "MINSIZEREL"))
|
|
set (OMIT_HEAVY_DEBUG_SYMBOLS_DEFAULT ON)
|
|
else()
|
|
set (OMIT_HEAVY_DEBUG_SYMBOLS_DEFAULT OFF)
|
|
endif()
|
|
# Provides faster linking and lower binary size.
|
|
# Tradeoff is the inability to debug some source files with e.g. gdb
|
|
# (empty stack frames and no local variables).
|
|
# In Release builds (which have no debug info by default), this option has
|
|
# no effect -- it only reduces debug info for RelWithDebInfo and MinSizeRel.
|
|
option(OMIT_HEAVY_DEBUG_SYMBOLS
|
|
"Do not generate debugger info for heavy modules (Datastore functions and dictionaries, some contrib)"
|
|
${OMIT_HEAVY_DEBUG_SYMBOLS_DEFAULT})
|
|
|
|
option(BUILD_STANDALONE_KEEPER "Build keeper as small standalone binary" OFF)
|
|
|
|
# Create BuildID when using lld. For other linkers it is created by default.
|
|
# (NOTE: LINKER_NAME can be either path or name, and in different variants)
|
|
if (LINKER_NAME MATCHES "lld" AND NOT LINKER_NAME MATCHES "ld64")
|
|
# SHA1 is not cryptographically secure but it is the best what lld is offering.
|
|
# ld64.lld (MachO linker) does not support --build-id.
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=sha1")
|
|
endif ()
|
|
|
|
# Add a section with the hash of the compiled machine code for integrity checks.
|
|
# Only for official builds, because adding a section can be time consuming (rewrite of several GB).
|
|
# And cross compiled binaries are not supported (since you cannot execute datastore hash-binary)
|
|
if (DATASTORE_OFFICIAL_BUILD AND OS_LINUX AND (ARCH_AMD64 OR ARCH_AARCH64) AND NOT ENABLE_CLANG_TIDY)
|
|
message(STATUS "Official build: A checksum hash will be added to the datastore executable")
|
|
set (USE_BINARY_HASH 1 CACHE STRING "Calculate binary hash and store it in the separate section")
|
|
else ()
|
|
message(STATUS "No official build: A checksum hash will not be added to the datastore executable")
|
|
endif ()
|
|
|
|
# Optionally split binaries and debug symbols.
|
|
option(DISABLE_ALL_DEBUG_SYMBOLS "Disable debug symbols, independently of which build type is used" OFF)
|
|
option(SPLIT_DEBUG_SYMBOLS "Split binaries and debug symbols" OFF)
|
|
if (SPLIT_DEBUG_SYMBOLS)
|
|
message(STATUS "Will split binaries and debug symbols")
|
|
set(SPLIT_DEBUG_SYMBOLS_DIR "stripped" CACHE STRING "A separate directory for stripped information")
|
|
endif()
|
|
|
|
option(BUILD_STRIPPED_BINARY "Build stripped binary (datastore-stripped)" OFF)
|
|
|
|
cmake_host_system_information(RESULT AVAILABLE_PHYSICAL_MEMORY QUERY AVAILABLE_PHYSICAL_MEMORY) # Not available under freebsd
|
|
|
|
|
|
if(NOT AVAILABLE_PHYSICAL_MEMORY OR AVAILABLE_PHYSICAL_MEMORY GREATER 8000)
|
|
# Less `/tmp` usage, more RAM usage.
|
|
option(COMPILER_PIPE "-pipe compiler option" ON)
|
|
endif()
|
|
|
|
if(COMPILER_PIPE)
|
|
set(COMPILER_FLAGS "${COMPILER_FLAGS} -pipe")
|
|
else()
|
|
message(STATUS "Disabling compiler -pipe option (have only ${AVAILABLE_PHYSICAL_MEMORY} mb of memory)")
|
|
endif()
|
|
|
|
include(cmake/cpu_features.cmake)
|
|
|
|
|
|
# Query Profiler doesn't work on MacOS for several reasons
|
|
# - PHDR cache is not available
|
|
# - We use native functionality to get stacktraces which is not async signal safe
|
|
# and thus we don't need to generate asynchronous unwind tables
|
|
if (NOT OS_DARWIN)
|
|
# Asynchronous unwind tables are needed for Query Profiler.
|
|
# They are already by default on some platforms but possibly not on all platforms.
|
|
# Enable it explicitly.
|
|
set (COMPILER_FLAGS "${COMPILER_FLAGS} -fasynchronous-unwind-tables")
|
|
endif()
|
|
|
|
# Reproducible builds.
|
|
if (CMAKE_BUILD_TYPE_UC STREQUAL "DEBUG")
|
|
set (ENABLE_BUILD_PATH_MAPPING_DEFAULT OFF)
|
|
else ()
|
|
set (ENABLE_BUILD_PATH_MAPPING_DEFAULT ON)
|
|
endif ()
|
|
|
|
if (COMPILER_CACHE STREQUAL "chcache")
|
|
set (ENABLE_BUILD_PATH_MAPPING_DEFAULT ON)
|
|
endif()
|
|
|
|
option (ENABLE_BUILD_PATH_MAPPING "Enable remapping of file source paths in debug info, predefined preprocessor macros, and __builtin_FILE(). It's used to generate reproducible builds. See https://reproducible-builds.org/docs/build-path" ${ENABLE_BUILD_PATH_MAPPING_DEFAULT})
|
|
|
|
if (ENABLE_BUILD_PATH_MAPPING)
|
|
# Fix DW_AT_comp_dir to "." regardless of the build directory location, then strip the source
|
|
# directory prefix from all file paths (trailing slash ensures the separator is stripped too,
|
|
# leaving bare relative paths like "src/Foo.cpp" that the symbolizer resolves to "./src/Foo.cpp").
|
|
set (COMPILER_FLAGS "${COMPILER_FLAGS} -fdebug-compilation-dir=. -ffile-prefix-map=${PROJECT_SOURCE_DIR}/=")
|
|
set (CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -fdebug-compilation-dir=. -ffile-prefix-map=${PROJECT_SOURCE_DIR}/=")
|
|
endif ()
|
|
|
|
option (ENABLE_BUILD_PROFILING "Enable profiling of build time" OFF)
|
|
if (ENABLE_BUILD_PROFILING)
|
|
set (COMPILER_FLAGS "${COMPILER_FLAGS} -ftime-trace")
|
|
|
|
if (LINKER_NAME MATCHES "lld")
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--time-trace")
|
|
set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--time-trace")
|
|
endif ()
|
|
endif ()
|
|
|
|
set (CMAKE_CXX_STANDARD 23)
|
|
set (CMAKE_CXX_EXTENSIONS OFF)
|
|
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
set (CMAKE_C_STANDARD 11)
|
|
set (CMAKE_C_EXTENSIONS ON) # required by most contribs written in C
|
|
set (CMAKE_C_STANDARD_REQUIRED ON)
|
|
|
|
# Align functions and loops to reduce performance sensitivity to code layout changes,
|
|
# providing more stable benchmarks.
|
|
set(COMPILER_FLAGS "${COMPILER_FLAGS} -falign-functions=64 -falign-loops=32")
|
|
|
|
# Put each function and data item into its own section so that the linker can
|
|
# remove unused ones (--gc-sections / -dead_strip) and fold identical ones (--icf).
|
|
# Sanitizer and coverage builds do not benefit from these size optimizations
|
|
# and the extra sections hurt instruction-cache locality in hot loops,
|
|
# causing timing-sensitive tests to fail.
|
|
if (NOT SANITIZE AND NOT SANITIZE_COVERAGE AND NOT WITH_COVERAGE)
|
|
set(COMPILER_FLAGS "${COMPILER_FLAGS} -ffunction-sections -fdata-sections")
|
|
# -faddrsig emits an address-significance table that lets lld's ICF
|
|
# distinguish address-taken symbols from non-address-taken ones.
|
|
# Only useful on Linux where we use lld with --icf=all; Darwin's ld64
|
|
# does not consume these sections.
|
|
if (OS_LINUX)
|
|
set(COMPILER_FLAGS "${COMPILER_FLAGS} -faddrsig")
|
|
endif ()
|
|
endif()
|
|
|
|
if (ARCH_AMD64)
|
|
# align branches within a 32-Byte boundary to avoid the potential performance loss when code layout change,
|
|
# which makes benchmark results more stable.
|
|
set(BRANCHES_WITHIN_32B_BOUNDARIES "-mbranches-within-32B-boundaries")
|
|
set(COMPILER_FLAGS "${COMPILER_FLAGS} ${BRANCHES_WITHIN_32B_BOUNDARIES}")
|
|
endif()
|
|
|
|
# Disable floating-point expression contraction in order to get consistent floating point calculation results across platforms
|
|
set (COMPILER_FLAGS "${COMPILER_FLAGS} -ffp-contract=off")
|
|
|
|
# Do not maintain `errno` for math functions (`sqrt`, `log`, `pow`, ...). This changes no
|
|
# computed result - `errno` is the only observable difference and ClickHouse never reads it
|
|
# after a libm call - but it lets the compiler emit math instructions directly instead of
|
|
# guarding each call with a branch to a libm wrapper, which also unblocks vectorization.
|
|
# Clang's default on Linux is `-fmath-errno` (errno-setting), so this is not already implied.
|
|
set (COMPILER_FLAGS "${COMPILER_FLAGS} -fno-math-errno")
|
|
|
|
# `-fno-math-errno` lets the compiler fold, hoist, and eliminate libm calls. That can remove the
|
|
# last `src/`-side references to a libm function, leaving its only references in contrib objects
|
|
# (e.g. usearch, arrow) that are linked after our in-tree `glibc-compatibility` math archive. Since
|
|
# an archive member is pulled only to satisfy an already-undefined symbol, the in-tree object is
|
|
# never extracted and the reference binds to shared glibc's newer symbol version, which the
|
|
# compatibility check rejects (max allowed GLIBC version is 2.4 on amd64, 2.18 on aarch64). Force
|
|
# our in-tree `musl` implementations to be pulled from the static archive so they preempt glibc,
|
|
# in the same spirit as the explicit `memcpy` interposition in `datastore_add_executable` below.
|
|
#
|
|
# Both the single-precision functions (new glibc version `@GLIBC_2.27`) and the double-precision
|
|
# ones (`@GLIBC_2.29`) are pinned. The doubles matter when `ENABLE_LLVM_LIBC_MATH=OFF`: in that
|
|
# configuration llvm-libc does not provide them, so `exp`/`log`/`pow`/`exp2`/`log2` are available
|
|
# only from the earlier `glibc-compatibility` archive and a later contrib reference can otherwise
|
|
# bind to glibc's `@GLIBC_2.29` symbols above the floor. With llvm-libc on they are already pulled
|
|
# from it, so the extra `-u` requests are harmless no-ops.
|
|
if (GLIBC_COMPATIBILITY)
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-u,logf -Wl,-u,powf -Wl,-u,expf -Wl,-u,exp2f -Wl,-u,log2f -Wl,-u,log -Wl,-u,pow -Wl,-u,exp -Wl,-u,exp2 -Wl,-u,log2")
|
|
endif ()
|
|
|
|
set (DEBUG_INFO_FLAGS "-g")
|
|
if (DISABLE_ALL_DEBUG_SYMBOLS)
|
|
set (DEBUG_INFO_FLAGS "-g0")
|
|
endif()
|
|
|
|
if (OS_DARWIN)
|
|
# On Darwin the optimizatiosns to reduce the debug size are off by default. `-fno-standalone-debug` enables them
|
|
set (DEBUG_INFO_FLAGS "${DEBUG_INFO_FLAGS} -fno-standalone-debug")
|
|
endif()
|
|
|
|
# generate ranges for fast "addr2line" search
|
|
if (NOT CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE")
|
|
# NOTE: that clang has a bug because of it does not emit .debug_aranges
|
|
# with ThinLTO, so custom ld.lld wrapper is shipped in docker images.
|
|
set(DEBUG_INFO_FLAGS "${DEBUG_INFO_FLAGS} -gdwarf-aranges")
|
|
endif ()
|
|
|
|
# Compress DWARF debug sections (`.debug_*`) in object files with -gz=zlib to shrink the build dir
|
|
# (debug info dominates it). Compile-only via add_compile_options, so binaries stay uncompressed and
|
|
# the symbolizer is unaffected. Defaults on where the compiler supports it (probed above).
|
|
option (COMPRESS_DEBUG_SECTIONS "Compress DWARF debug sections in object files with zlib (-gz)" ${COMPILER_SUPPORTS_GZ_ZLIB})
|
|
|
|
if (COMPRESS_DEBUG_SECTIONS)
|
|
# Only C/C++ (and GNU-style ASM handled by clang) understand -gz; scope it away from other
|
|
# languages such as ASM_NASM (ISA-L on amd64), whose nasm assembler rejects the flag.
|
|
add_compile_options ($<$<COMPILE_LANGUAGE:C,CXX,ASM>:-gz=zlib>)
|
|
endif ()
|
|
|
|
# Disable omit frame pointer compiler optimization using -fno-omit-frame-pointer
|
|
option(DISABLE_OMIT_FRAME_POINTER "Disable omit frame pointer compiler optimization" OFF)
|
|
|
|
if (DISABLE_OMIT_FRAME_POINTER)
|
|
set (CMAKE_CXX_FLAGS_ADD "${CMAKE_CXX_FLAGS_ADD} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer")
|
|
set (CMAKE_C_FLAGS_ADD "${CMAKE_C_FLAGS_ADD} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer")
|
|
set (CMAKE_ASM_FLAGS_ADD "${CMAKE_ASM_FLAGS_ADD} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer")
|
|
endif()
|
|
|
|
# Before you start hating your debugger because it refuses to show variables ('<optimized out>'), try building with -DDEBUG_O_LEVEL="0"
|
|
# https://stackoverflow.com/questions/63386189/whats-the-difference-between-a-compilers-o0-option-and-og-option/63386263#63386263
|
|
set(DEBUG_O_LEVEL "g" CACHE STRING "The -Ox level used for debug builds")
|
|
|
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS} ${CMAKE_CXX_FLAGS_ADD}")
|
|
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 ${DEBUG_INFO_FLAGS} ${CMAKE_CXX_FLAGS_ADD}")
|
|
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O${DEBUG_O_LEVEL} ${DEBUG_INFO_FLAGS} ${CMAKE_CXX_FLAGS_ADD}")
|
|
|
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILER_FLAGS} ${CMAKE_C_FLAGS_ADD}")
|
|
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 ${DEBUG_INFO_FLAGS} ${CMAKE_C_FLAGS_ADD}")
|
|
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O${DEBUG_O_LEVEL} ${DEBUG_INFO_FLAGS} ${CMAKE_C_FLAGS_ADD}")
|
|
|
|
set (CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${COMPILER_FLAGS} ${CMAKE_ASM_FLAGS_ADD}")
|
|
set (CMAKE_ASM_FLAGS_RELWITHDEBINFO "${CMAKE_ASM_FLAGS_RELWITHDEBINFO} -O3 ${DEBUG_INFO_FLAGS} ${CMAKE_ASM_FLAGS_ADD}")
|
|
set (CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -O${DEBUG_O_LEVEL} ${DEBUG_INFO_FLAGS} ${CMAKE_ASM_FLAGS_ADD}")
|
|
|
|
if (OS_DARWIN)
|
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-U,_inside_main")
|
|
endif()
|
|
|
|
# Display absolute paths in error messages. Otherwise KDevelop fails to navigate to correct file and opens a new file instead.
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-absolute-paths")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-absolute-paths")
|
|
|
|
# https://clang.llvm.org/docs/ThinLTO.html
|
|
# Applies to clang and linux only.
|
|
# Disabled by default; explicitly enabled in CI for release and performance builds.
|
|
option(ENABLE_THINLTO "Clang-specific link time optimization" OFF)
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-vtable-pointers")
|
|
|
|
# CFI requires ThinLTO. Validate here, after ENABLE_THINLTO has been resolved by
|
|
# the option() call above. sanitize.cmake is included earlier (before the option()
|
|
# declaration) so the check must live here where ENABLE_THINLTO is fully defined.
|
|
if (ENABLE_CFI AND NOT ENABLE_THINLTO)
|
|
message (FATAL_ERROR "ENABLE_CFI requires ENABLE_THINLTO. "
|
|
"CFI needs -flto=thin and -fwhole-program-vtables which are only applied "
|
|
"when ThinLTO is enabled. Current configuration has ENABLE_THINLTO=${ENABLE_THINLTO}.")
|
|
endif ()
|
|
|
|
if (ENABLE_CFI AND ENABLE_TESTS)
|
|
message (FATAL_ERROR "ENABLE_CFI is incompatible with ENABLE_TESTS. "
|
|
"ThinLTO (required by CFI) is disabled when building tests. "
|
|
"Build without tests (ENABLE_TESTS=0) to use CFI.")
|
|
endif ()
|
|
|
|
# CFI flags are wired into the RelWithDebInfo profile only (CMAKE_*_FLAGS_RELWITHDEBINFO).
|
|
# Other build types would configure successfully and print the CFI status message while
|
|
# silently producing a non-CFI binary, so reject them explicitly.
|
|
if (ENABLE_CFI AND NOT CMAKE_BUILD_TYPE_UC STREQUAL "RELWITHDEBINFO")
|
|
message (FATAL_ERROR "ENABLE_CFI is only supported with CMAKE_BUILD_TYPE=RelWithDebInfo. "
|
|
"Current configuration has CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}.")
|
|
endif ()
|
|
|
|
# We cannot afford to use LTO when compiling unit tests, and it's not enough
|
|
# to only supply -fno-lto at the final linking stage. So we disable it
|
|
# completely.
|
|
if (ENABLE_THINLTO AND NOT ENABLE_TESTS AND NOT SANITIZE)
|
|
# Link time optimization
|
|
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -flto=thin -fwhole-program-vtables")
|
|
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -flto=thin -fwhole-program-vtables")
|
|
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -flto=thin -fwhole-program-vtables")
|
|
|
|
if(LINKER_NAME MATCHES "lld")
|
|
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -Wl,--lto-whole-program-visibility")
|
|
endif()
|
|
|
|
if (ENABLE_CFI)
|
|
# CFI checks: virtual dispatch type safety and bad downcasts via static_cast.
|
|
# cfi-icall is omitted because C function pointers in contrib libraries (compiled without
|
|
# CFI) would cause false positives. Start conservative; broaden after baseline is clean.
|
|
# cfi-vcall and cfi-derived-cast are C++-only checks; do not apply to C compilation.
|
|
#
|
|
# Use `-fvisibility=default` rather than the CFI-documented `hidden`: with hidden
|
|
# visibility the build succeeds (with `-Wunique-object-duplication` suppressed) but the
|
|
# resulting binary crashes with SIGSEGV before main runs, because inline-static singletons
|
|
# like `Context::global_context_instance` and `BaseSettings::unknown_settings` get
|
|
# duplicated per translation unit and singleton identity is broken. Validated empirically
|
|
# by WeeklyCFI run 25790910376 — `clickhouse-server --version` exited with signal 11.
|
|
# CFI vtable visibility is still satisfied for in-binary types because
|
|
# `-fwhole-program-vtables` and `-Wl,--lto-whole-program-visibility` (set above) cause
|
|
# the linker to treat all vtables as internal to the binary.
|
|
#
|
|
# CFI is left in the default trap mode: a violation executes an illegal instruction
|
|
# (SIGILL) and CI's core-dump handler yields a stack trace pinpointing the bad vcall/cast.
|
|
# Diagnostic mode (`-fno-sanitize-trap=cfi`, which prints a UBSan-style type/location
|
|
# report) is deliberately NOT used: it makes Clang link `libclang_rt.ubsan_standalone`,
|
|
# which this toolchain does not ship (only select compiler-rt libs are built from contrib),
|
|
# so even host tools like `protoc` fail to link — validated by WeeklyCFI run 28943752776.
|
|
# `-fno-sanitize-recover=cfi` is redundant in trap mode but kept as an explicit marker that
|
|
# a violation must never be continued past.
|
|
set (CFI_FLAGS "-fsanitize=cfi-vcall,cfi-derived-cast -fno-sanitize-recover=cfi -fvisibility=default")
|
|
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CFI_FLAGS}")
|
|
set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} ${CFI_FLAGS}")
|
|
endif ()
|
|
elseif (ENABLE_THINLTO)
|
|
message (${RECONFIGURE_MESSAGE_LEVEL} "Cannot enable ThinLTO")
|
|
endif ()
|
|
|
|
if(COMPILER_PIPE)
|
|
set(MAX_COMPILER_MEMORY 2500)
|
|
else()
|
|
set(MAX_COMPILER_MEMORY 1500)
|
|
endif()
|
|
set(MAX_LINKER_MEMORY 5000)
|
|
if (ENABLE_FUZZING)
|
|
# Fuzzer builds produce many large ASan-instrumented binaries.
|
|
# Each linker instance needs significantly more memory than the default.
|
|
set(MAX_LINKER_MEMORY 16000)
|
|
endif()
|
|
include(cmake/limit_jobs.cmake)
|
|
|
|
|
|
# Turns on all external libs like s3, kafka, ODBC, ...
|
|
option(ENABLE_LIBRARIES "Enable all external libraries by default" ON)
|
|
|
|
# Increase stack size on Musl. We need big stack for our recursive-descend parser
|
|
# and for analyzer passes that recurse on deeply-nested join trees (e.g.
|
|
# 1000-join queries). Match glibc's 8 MiB default; musl reads this from
|
|
# PT_GNU_STACK and clamps it to DEFAULT_STACK_MAX (also 8 MiB).
|
|
if (USE_MUSL)
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,stack-size=8388608")
|
|
endif ()
|
|
|
|
include(cmake/dbms_glob_sources.cmake)
|
|
|
|
add_library(global-group INTERFACE)
|
|
if (OS_LINUX OR OS_ANDROID)
|
|
include(cmake/linux/default_libs.cmake)
|
|
elseif (OS_DARWIN)
|
|
include(cmake/darwin/default_libs.cmake)
|
|
elseif (OS_FREEBSD)
|
|
include(cmake/freebsd/default_libs.cmake)
|
|
elseif (OS_SUNOS)
|
|
include(cmake/sunos/default_libs.cmake)
|
|
endif ()
|
|
link_libraries(global-group)
|
|
target_link_libraries(global-group INTERFACE $<TARGET_PROPERTY:global-libs,INTERFACE_LINK_LIBRARIES>)
|
|
|
|
option (ENABLE_LIBFIU "Enable libfiu" ON)
|
|
|
|
option(WERROR "Enable -Werror compiler option" ON)
|
|
|
|
if (WERROR)
|
|
# Don't pollute CMAKE_CXX_FLAGS with -Werror as it will break some CMake checks.
|
|
# Instead, adopt modern cmake usage requirement.
|
|
# TODO: Set CMAKE_COMPILE_WARNING_AS_ERROR (cmake 3.24)
|
|
target_compile_options(global-group INTERFACE "-Werror")
|
|
endif ()
|
|
|
|
# Make this extra-checks for correct library dependencies.
|
|
if (OS_LINUX AND NOT SANITIZE)
|
|
target_link_options(global-group INTERFACE "LINKER:--no-undefined")
|
|
endif ()
|
|
|
|
######################################
|
|
### Add targets below this comment ###
|
|
######################################
|
|
|
|
set (CMAKE_POSTFIX_VARIABLE "CMAKE_${CMAKE_BUILD_TYPE_UC}_POSTFIX")
|
|
|
|
# We enable position independent encoding for all build types except build with -flto=thin:
|
|
# 1. Position independent binaries and libraries have no limit for maximum size of relocation. It allows to avoid
|
|
# multiple sophisticated problems like linking with sanitizers or linking of rust.
|
|
# 2. Position independent binaries and libraries are a little bit slower, than position dependent. We consider
|
|
# build with -flto=thin as trully "production" build where each % of performance is important.
|
|
# 3. For some unknow reason -flto=thin lead to some other way of linkage. For example for rust libraries build
|
|
# we don't see any relocation-related errors without -fPIC, but with enabled -flto=thin. While without
|
|
# -flto=thin we have relocation errors like:
|
|
# rust-lld: error: relocation R_X86_64_32S cannot be used against symbol 'SEED_encrypt'; recompile with -fPIC
|
|
#
|
|
# NOTE: -fno-pie disables -fPIC, so that is why we check ENABLE_THINLTO in the branch bellow
|
|
#
|
|
# For some sophisticated platforms we have different issues with fPIC:
|
|
# For example riscv toolchain itself compiled without fPIC
|
|
if (NOT ENABLE_THINLTO AND (ARCH_AMD64 OR ARCH_AARCH64))
|
|
set(ENABLE_POSITION_INDEPENDENT_BINARY 1)
|
|
endif()
|
|
|
|
if (ENABLE_POSITION_INDEPENDENT_BINARY)
|
|
set (CMAKE_POSITION_INDEPENDENT_CODE OFF)
|
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
|
endif()
|
|
|
|
if (NOT OS_ANDROID AND OS_LINUX AND NOT ARCH_S390X AND NOT SANITIZE AND NOT ENABLE_POSITION_INDEPENDENT_BINARY)
|
|
# Using '-no-pie' builds executables with fixed addresses, resulting in slightly more efficient code
|
|
# and keeping binary addresses constant even with ASLR enabled.
|
|
# Disabled on Android as it requires PIE: https://source.android.com/docs/security/enhancements#android-5
|
|
# Disabled on IBM S390X due to build issues with 'no-pie'
|
|
# Disabled with sanitizers to avoid issues with maximum relocation size: https://github.com/hanzoai/datastore/pull/49145
|
|
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-pie")
|
|
set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fno-pie")
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie -Wl,-no-pie")
|
|
endif ()
|
|
|
|
if (ENABLE_TESTS)
|
|
message (STATUS "Unit tests are enabled")
|
|
else()
|
|
message(STATUS "Unit tests are disabled")
|
|
endif ()
|
|
|
|
enable_testing() # Enable for tests without binary
|
|
|
|
set(ENABLE_OPENSSL_DYNAMIC_DEFAULT OFF)
|
|
option(ENABLE_OPENSSL_DYNAMIC "This option removes SSL from Datastore and will link to the OpenSSL version supplied by OS." ${ENABLE_OPENSSL_DYNAMIC_DEFAULT})
|
|
|
|
# when installing to /usr - place configs to /etc but for /usr/local place to /usr/local/etc
|
|
if (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
|
|
set (DATASTORE_ETC_DIR "/etc")
|
|
else ()
|
|
set (DATASTORE_ETC_DIR "${CMAKE_INSTALL_PREFIX}/etc")
|
|
endif ()
|
|
|
|
message (STATUS "Building for: ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_LIBRARY_ARCHITECTURE}")
|
|
|
|
# With cross-compiling, all targets are built for the target platform which usually different from the host
|
|
# platform. This is problematic if a build artifact X (e.g. a file or an executable) is generated by running
|
|
# another executable Y previously produced in the build. This is solved by compiling and running Y for/on
|
|
# the host platform. Add target to the list:
|
|
# add_native_target(<target> ...)
|
|
set_property (GLOBAL PROPERTY NATIVE_BUILD_TARGETS)
|
|
function (add_native_target TARGET)
|
|
set_property (GLOBAL APPEND PROPERTY NATIVE_BUILD_TARGETS "--target" ${TARGET})
|
|
endfunction (add_native_target)
|
|
|
|
add_subdirectory (contrib EXCLUDE_FROM_ALL)
|
|
|
|
# We can only include XRay flags and defines once we know that we're building LLVM
|
|
if (ENABLE_XRAY)
|
|
include (cmake/xray_instrumentation.cmake)
|
|
endif()
|
|
|
|
# Sets dummy launchers to suppress linking. Used for clang-tidy builds.
|
|
enable_dummy_launchers_if_needed()
|
|
|
|
if (NOT ENABLE_JEMALLOC)
|
|
message (WARNING "Non default allocator is disabled. This is not recommended for production builds.")
|
|
endif ()
|
|
|
|
macro (datastore_add_executable target)
|
|
# invoke built-in add_executable
|
|
# explicitly acquire and interpose malloc symbols by datastore_malloc
|
|
# Note: for musl builds (-nostartfiles), the CRT startup files are added to every
|
|
# executable through the link flags, see cmake/linux/default_libs.cmake.
|
|
add_executable (${ARGV} $<TARGET_OBJECTS:datastore_malloc>)
|
|
|
|
get_target_property (type ${target} TYPE)
|
|
if (${type} STREQUAL EXECUTABLE)
|
|
target_link_libraries (${target} PUBLIC datastore_new_delete)
|
|
|
|
# In case of static jemalloc, because zone_register() is located in zone.c and
|
|
# is never used outside (it is declared as constructor) it is omitted
|
|
# by the linker, and so jemalloc will not be registered as system
|
|
# allocator under osx [1], and datastore will SIGSEGV.
|
|
#
|
|
# [1]: https://github.com/jemalloc/jemalloc/issues/708
|
|
#
|
|
# About symbol name:
|
|
# - _zone_register not zone_register due to Mach-O binary format,
|
|
# - _je_zone_register due to JEMALLOC_PRIVATE_NAMESPACE=je_ under OS X.
|
|
# - but jemalloc-cmake does not run private_namespace.sh
|
|
# so symbol name should be _zone_register
|
|
if (ENABLE_JEMALLOC AND OS_DARWIN)
|
|
set_property(TARGET ${target} APPEND PROPERTY LINK_OPTIONS -u_zone_register)
|
|
endif()
|
|
endif()
|
|
endmacro()
|
|
|
|
set(CONFIG_INCLUDE_PATH ${CMAKE_CURRENT_BINARY_DIR}/includes/configs CACHE INTERNAL "Path to generated configuration files.")
|
|
include_directories(${CONFIG_INCLUDE_PATH})
|
|
|
|
# Add as many warnings as possible for our own code.
|
|
include (cmake/warnings.cmake)
|
|
include (cmake/print_flags.cmake)
|
|
|
|
if (ENABLE_RUST)
|
|
add_subdirectory (rust)
|
|
|
|
# With LTO Rust adds few symbols with global visibility, the most common is
|
|
# rust_eh_personality. And this leads to linking errors because multiple
|
|
# Rust libraries contains the same symbol.
|
|
#
|
|
# If it was shared library, that we could use version script for linker to
|
|
# hide this symbols, but libraries are static.
|
|
#
|
|
# we could in theory compile everything to one library but this will be a
|
|
# mess
|
|
#
|
|
# But this should be OK since CI has lots of other builds that are done
|
|
# without LTO and it will find multiple definitions if there will be any.
|
|
#
|
|
# More information about this behaviour in Rust can be found here
|
|
# - https://github.com/rust-lang/rust/issues/44322
|
|
# - https://alanwu.space/post/symbol-hygiene/
|
|
if (ENABLE_THINLTO)
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-multiple-definition")
|
|
endif()
|
|
endif()
|
|
|
|
if (CMAKE_BUILD_TYPE_UC STREQUAL "RELWITHDEBINFO"
|
|
AND NOT SANITIZE AND NOT ENABLE_FUZZING
|
|
AND OMIT_HEAVY_DEBUG_SYMBOLS AND OS_LINUX AND (ARCH_AMD64 OR ARCH_AARCH64))
|
|
set(CHECK_LARGE_OBJECT_SIZES_DEFAULT ON)
|
|
else ()
|
|
set(CHECK_LARGE_OBJECT_SIZES_DEFAULT OFF)
|
|
endif ()
|
|
option(CHECK_LARGE_OBJECT_SIZES "Check that there are no large object files after build." ${CHECK_LARGE_OBJECT_SIZES_DEFAULT})
|
|
|
|
add_subdirectory (base)
|
|
add_subdirectory (src)
|
|
if (LEXER_STANDALONE_BUILD)
|
|
add_subdirectory(tests/lexer)
|
|
endif ()
|
|
add_subdirectory (programs)
|
|
add_subdirectory (utils)
|
|
|
|
if (FUZZER)
|
|
# Bundle fuzzers target
|
|
add_custom_target(fuzzers)
|
|
# Instrument all targets fuzzer and link with libfuzzer
|
|
get_all_targets(all_targets)
|
|
foreach(target ${all_targets})
|
|
# isa-l contrib uses the nasm compiler, which has no fsanitize options
|
|
if (NOT(target STREQUAL "_fuzzer" OR target STREQUAL "_fuzzer_no_main" OR target MATCHES ".*isal.*"))
|
|
get_target_property(target_type ${target} TYPE)
|
|
if (NOT(target_type STREQUAL "INTERFACE_LIBRARY" OR target_type STREQUAL "UTILITY"))
|
|
target_compile_options(${target} PRIVATE "-fsanitize=fuzzer-no-link")
|
|
endif()
|
|
if (target_type STREQUAL "EXECUTABLE" AND target MATCHES ".+_fuzzer")
|
|
message(STATUS "${target} instrumented with fuzzer")
|
|
target_link_libraries(${target} PUBLIC ch_contrib::fuzzer)
|
|
# Add to fuzzers bundle
|
|
add_dependencies(fuzzers ${target})
|
|
get_target_filename(${target} target_bin_name)
|
|
get_target_property(target_bin_dir ${target} BINARY_DIR)
|
|
add_custom_command(TARGET fuzzers POST_BUILD COMMAND mv "${target_bin_dir}/${target_bin_name}" "${CMAKE_CURRENT_BINARY_DIR}/programs/" VERBATIM)
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
add_custom_command(TARGET fuzzers POST_BUILD COMMAND SRC=${CMAKE_SOURCE_DIR} BIN=${CMAKE_BINARY_DIR} OUT=${CMAKE_BINARY_DIR}/programs ${CMAKE_SOURCE_DIR}/tests/fuzz/build.sh VERBATIM)
|
|
endif()
|
|
|
|
include (cmake/sanitize_targets.cmake)
|
|
|
|
if (COMPILER_CACHE STREQUAL "chcache" AND CHCACHE_EXECUTABLE_PATH STREQUAL "")
|
|
message(STATUS "Adding chcache as dependency to all other targets")
|
|
get_all_targets(all_targets)
|
|
set(chcache_targets _cargo-build_chcache cargo-build_chcache cargo-prebuild_chcache)
|
|
|
|
foreach(target ${all_targets})
|
|
if (target IN_LIST chcache_targets)
|
|
continue()
|
|
endif()
|
|
|
|
add_dependencies(${target} cargo-build_chcache)
|
|
endforeach()
|
|
endif()
|
|
|
|
# Build native targets if necessary
|
|
get_property(NATIVE_BUILD_TARGETS GLOBAL PROPERTY NATIVE_BUILD_TARGETS)
|
|
if (NATIVE_BUILD_TARGETS
|
|
AND NOT(
|
|
CMAKE_HOST_SYSTEM_NAME STREQUAL CMAKE_SYSTEM_NAME
|
|
AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR
|
|
AND NOT USE_MUSL
|
|
)
|
|
)
|
|
message (STATUS "Building native targets: ${NATIVE_BUILD_TARGETS}")
|
|
|
|
set (NATIVE_BUILD_DIR "${PROJECT_BINARY_DIR}/native")
|
|
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${NATIVE_BUILD_DIR}"
|
|
COMMAND_ECHO STDOUT
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
)
|
|
|
|
disable_dummy_launchers_if_needed()
|
|
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND}
|
|
"-G${CMAKE_GENERATOR}"
|
|
"-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
|
|
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
|
|
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
|
|
"-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}"
|
|
"-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}"
|
|
"-DCMAKE_BUILD_TYPE=Release"
|
|
# Avoid overriding .cargo/config.toml with native toolchain.
|
|
"-DENABLE_RUST=OFF"
|
|
"-DENABLE_DATASTORE_SELF_EXTRACTING=${ENABLE_DATASTORE_SELF_EXTRACTING}"
|
|
"-DUSE_BINARY_HASH=${USE_BINARY_HASH}"
|
|
${PROJECT_SOURCE_DIR}
|
|
WORKING_DIRECTORY "${NATIVE_BUILD_DIR}"
|
|
COMMAND_ECHO STDOUT
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
)
|
|
|
|
enable_dummy_launchers_if_needed()
|
|
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} --build "${NATIVE_BUILD_DIR}" ${NATIVE_BUILD_TARGETS}
|
|
COMMAND_ECHO STDOUT
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
)
|
|
endif ()
|