From a6f6d5c0a6e022687cf8439f667d91b60ac7b3ca Mon Sep 17 00:00:00 2001 From: Alexander Droste Date: Mon, 14 Sep 2026 20:37:36 +0200 Subject: [PATCH 01/14] Add shared CMake libraries and use them in C++ CI Signed-off-by: Alexander Droste --- .github/workflows/ci.yml | 5 +- lang/cpp/CMakeLists.txt | 52 ++++++++++++------- lang/cpp/README.md | 15 ++++-- lang/cpp/examples/CMakeLists.txt | 7 ++- lang/cpp/tests/CMakeLists.txt | 6 ++- vortex-ffi/CMakeLists.txt | 10 +++- vortex-ffi/README.md | 9 ++-- vortex-ffi/cmake/Configure.cmake | 31 ++++++++++- vortex-ffi/cmake/SystemDependencies.cmake | 4 +- vortex-ffi/cmake/exports.map | 7 +++ vortex-ffi/cmake/shared.c | 5 ++ .../tests/fixtures/native/header_consumer.c | 1 + .../tests/fixtures/native/vortex-ffi/build.rs | 5 +- .../tests/fixtures/native/vortex-ffi/lib.rs | 7 +++ .../cmake/tests/test_compiler_commands.py | 29 ++++++++++- vortex-ffi/cmake/tests/test_configure.py | 2 +- vortex-ffi/examples/CMakeLists.txt | 6 ++- vortex-ffi/test/CMakeLists.txt | 6 ++- 18 files changed, 168 insertions(+), 39 deletions(-) create mode 100644 vortex-ffi/cmake/exports.map create mode 100644 vortex-ffi/cmake/shared.c diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42d18337af3..7e7e5488812 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -673,9 +673,12 @@ jobs: run: | cmake -S lang/cpp -B build \ -DCMAKE_BUILD_TYPE=Debug \ - -DVORTEX_DEBUG_INFO=0 \ + -DBUILD_SHARED_LIBS=ON \ + -DVORTEX_DEBUG_INFO=2 \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=mold \ + -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=mold \ -DVORTEX_SANITIZER=asan \ -DVORTEX_SANITIZE_RUST_STD=ON \ -DVORTEX_BUILD_TESTS=ON \ diff --git a/lang/cpp/CMakeLists.txt b/lang/cpp/CMakeLists.txt index 4d969b375bd..62bbe1cfd70 100644 --- a/lang/cpp/CMakeLists.txt +++ b/lang/cpp/CMakeLists.txt @@ -1,8 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: Copyright the Vortex contributors -# Entry point for the static Vortex C++ wrapper. It consumes the Rust FFI -# archive from vortex-ffi and exports Vortex::cpp_static. It supports standalone +# Entry point for the Vortex C++ wrapper. It consumes the Rust FFI library +# from vortex-ffi and exports static and shared targets. It supports standalone # configuration and add_subdirectory() from the repository root or a parent. # CMake 3.25 is required for block() and FetchContent SYSTEM. @@ -33,6 +33,7 @@ if(_vortex_top_level AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) endif() +option(BUILD_SHARED_LIBS "Build and use shared libraries" OFF) option(VORTEX_BUILD_TESTS "Build Vortex tests" OFF) option(VORTEX_BUILD_EXAMPLES "Build Vortex examples" OFF) option(VORTEX_WARNINGS_AS_ERRORS @@ -50,27 +51,35 @@ endif() # The C++ wrapper over the C FFI. Public headers live under include/. file(GLOB _vortex_cpp_sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") -# Consumers inherit the FFI archive, its headers, and its system libraries -# through this target. Hidden visibility keeps wrapper symbols out of a parent -# shared library's exports. +# Preserve the static API and its hidden symbols for embedding in other DSOs. add_library(vortex_cxx STATIC ${_vortex_cpp_sources}) -set_target_properties(vortex_cxx PROPERTIES - POSITION_INDEPENDENT_CODE ON - CXX_VISIBILITY_PRESET hidden - VISIBILITY_INLINES_HIDDEN ON) -target_compile_features(vortex_cxx PUBLIC cxx_std_20) -target_include_directories(vortex_cxx PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") +set_target_properties(vortex_cxx PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(vortex_cxx PUBLIC Vortex::ffi_static) - -# Warning policy is private to Vortex-owned sources so embedding this target -# never injects warning flags into consumers. -target_compile_options(vortex_cxx PRIVATE -Wall -Wextra -Wpedantic) -if(VORTEX_WARNINGS_AS_ERRORS) - target_compile_options(vortex_cxx PRIVATE -Werror) +add_library(Vortex::cpp_static ALIAS vortex_cxx) +set(_vortex_cpp_targets vortex_cxx) +if(BUILD_SHARED_LIBS) + set_target_properties(vortex_cxx PROPERTIES EXCLUDE_FROM_ALL TRUE) + add_library(vortex_cxx_shared SHARED ${_vortex_cpp_sources}) + set_target_properties(vortex_cxx_shared PROPERTIES + OUTPUT_NAME vortex_cxx + CXX_VISIBILITY_PRESET default) + target_link_libraries(vortex_cxx_shared PUBLIC Vortex::ffi_shared) + add_library(Vortex::cpp_shared ALIAS vortex_cxx_shared) + list(APPEND _vortex_cpp_targets vortex_cxx_shared) endif() -# The only supported consumer-facing name for the C++ API. -add_library(Vortex::cpp_static ALIAS vortex_cxx) +foreach(_target IN LISTS _vortex_cpp_targets) + set_target_properties(${_target} PROPERTIES + POSITION_INDEPENDENT_CODE ON + VISIBILITY_INLINES_HIDDEN ON) + target_compile_features(${_target} PUBLIC cxx_std_20) + target_include_directories(${_target} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + # Warning policy must not propagate into consumers. + target_compile_options(${_target} PRIVATE -Wall -Wextra -Wpedantic) + if(VORTEX_WARNINGS_AS_ERRORS) + target_compile_options(${_target} PRIVATE -Werror) + endif() +endforeach() # Test and example dependencies are fetched at configure time and never installed. if(VORTEX_BUILD_TESTS OR VORTEX_BUILD_EXAMPLES) @@ -83,7 +92,12 @@ if(VORTEX_BUILD_TESTS OR VORTEX_BUILD_EXAMPLES) SYSTEM GIT_REPOSITORY https://github.com/apache/arrow-nanoarrow GIT_TAG apache-arrow-nanoarrow-0.8.0) + FetchContent_GetProperties(Nanoarrow POPULATED _vortex_nanoarrow_populated) FetchContent_MakeAvailable(Nanoarrow) + if(NOT _vortex_nanoarrow_populated) + # Build only the shared variant used below, without altering a parent's dependency. + set_property(DIRECTORY "${nanoarrow_SOURCE_DIR}" PROPERTY EXCLUDE_FROM_ALL TRUE) + endif() # Suppress Nanoarrow warnings. target_compile_options(nanoarrow_static PRIVATE -w) target_compile_options(nanoarrow_shared PRIVATE -w) diff --git a/lang/cpp/README.md b/lang/cpp/README.md index 950f11fe001..b251ab9eba3 100644 --- a/lang/cpp/README.md +++ b/lang/cpp/README.md @@ -17,20 +17,26 @@ cmake --build build/cpp --parallel CMake runs Cargo for you. Configuration and builds download uncached dependencies. **Native builds only:** GNU/Linux x86_64 and aarch64, plus macOS arm64 for standalone development. -Cross-compilation, universal binaries, Windows, musl, and shared Vortex targets are unsupported. +Cross-compilation, universal binaries, Windows, and musl are unsupported. ## Embed in a CMake project Vendor or fetch a pinned, complete checkout: ```cmake +set(BUILD_SHARED_LIBS ON) add_subdirectory(path/to/vortex vortex) -target_link_libraries(my_cpp_target PRIVATE Vortex::cpp_static) -target_link_libraries(my_c_target PRIVATE Vortex::ffi_static) +target_link_libraries(my_cpp_target PRIVATE Vortex::cpp_shared) +target_link_libraries(my_c_target PRIVATE Vortex::ffi_shared) ``` Vortex leaves parent build settings unchanged. Its archives are position-independent. +`BUILD_SHARED_LIBS=ON` also selects shared Catch2 libraries when building tests. +For static linkage, use `Vortex::ffi_static` and `Vortex::cpp_static`; these targets remain +available in either mode. CMake supplies build-tree runtime paths; deployment requires +configuring runtime search paths for the application and its shared libraries. + ## Build options Pass `-D