diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42d18337af3..9914fb62d28 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -673,7 +673,7 @@ jobs: run: | cmake -S lang/cpp -B build \ -DCMAKE_BUILD_TYPE=Debug \ - -DVORTEX_DEBUG_INFO=0 \ + -DBUILD_SHARED_LIBS=ON \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DVORTEX_SANITIZER=asan \ @@ -879,6 +879,7 @@ jobs: RUSTUP_TOOLCHAIN: ${{ env.NIGHTLY_TOOLCHAIN }} run: | cmake -S vortex-ffi -B vortex-ffi/build \ + -DBUILD_SHARED_LIBS=ON \ -DVORTEX_CARGO_PROFILE=ci \ -DVORTEX_BUILD_TESTS=ON cmake --build vortex-ffi/build --parallel "$(nproc)" diff --git a/.github/workflows/rust-instrumented.yml b/.github/workflows/rust-instrumented.yml index e64753fd3b6..80cdb9be282 100644 --- a/.github/workflows/rust-instrumented.yml +++ b/.github/workflows/rust-instrumented.yml @@ -262,6 +262,7 @@ jobs: run: | cmake -S . -B build \ -DCMAKE_BUILD_TYPE=Debug \ + -DBUILD_SHARED_LIBS=ON \ -DCMAKE_C_COMPILER=clang \ -DCMAKE_CXX_COMPILER=clang++ \ -DVORTEX_SANITIZER=${{ matrix.sanitizer }} \ diff --git a/CMakeLists.txt b/CMakeLists.txt index dd146ef57c8..883a29a2e3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,8 @@ # target_link_libraries(my_c_target PRIVATE Vortex::ffi_static) # target_link_libraries(my_cpp_target PRIVATE Vortex::cpp_static) # +# Use Vortex::ffi_shared and Vortex::cpp_shared for shared linkage. +# # See lang/cpp/README.md for build options and embedding requirements, # and vortex-ffi/README.md for C API development. diff --git a/lang/cpp/CMakeLists.txt b/lang/cpp/CMakeLists.txt index 4d969b375bd..a4acdfcdb05 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 "Use shared libraries for Vortex builds, tests, and examples" 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,44 @@ 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. -add_library(vortex_cxx STATIC ${_vortex_cpp_sources}) -set_target_properties(vortex_cxx PROPERTIES +add_library(vortex_cxx_static STATIC ${_vortex_cpp_sources}) +set_target_properties(vortex_cxx_static PROPERTIES + OUTPUT_NAME vortex_cxx + # Allow embedding the static archive in a shared library. 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") -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) + # Keep embedded wrapper symbols out of the parent library's exports. + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(vortex_cxx_static PUBLIC Vortex::ffi_static) +add_library(Vortex::cpp_static ALIAS vortex_cxx_static) + +# CMake enables PIC automatically for SHARED targets. +add_library(vortex_cxx_shared SHARED ${_vortex_cpp_sources}) +# Override an inherited hidden preset so the shared C++ API remains exported. +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) + +if(BUILD_SHARED_LIBS) + set_target_properties(vortex_cxx_static PROPERTIES EXCLUDE_FROM_ALL TRUE) + set(_vortex_cpp_target Vortex::cpp_shared) +else() + set_target_properties(vortex_cxx_shared PROPERTIES EXCLUDE_FROM_ALL TRUE) + set(_vortex_cpp_target Vortex::cpp_static) endif() -# The only supported consumer-facing name for the C++ API. -add_library(Vortex::cpp_static ALIAS vortex_cxx) +foreach(_target IN ITEMS vortex_cxx_static vortex_cxx_shared) + # Hide inline symbols in the shared library and when embedding the static archive. + set_target_properties(${_target} PROPERTIES 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) diff --git a/lang/cpp/README.md b/lang/cpp/README.md index 950f11fe001..14c93312ae9 100644 --- a/lang/cpp/README.md +++ b/lang/cpp/README.md @@ -17,7 +17,7 @@ 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 @@ -25,12 +25,14 @@ Vendor or fetch a pinned, complete checkout: ```cmake 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. +For static linkage, use `Vortex::ffi_static` and `Vortex::cpp_static`. + ## Build options Pass `-D