From 04acda8846e42ecd72974fa62c17a48bd2f16e0c Mon Sep 17 00:00:00 2001 From: Dewey Dunnington Date: Wed, 21 Oct 2026 22:17:06 -0500 Subject: [PATCH 1/2] fix(cmake): align minimum version and improve flatcc discovery --- .github/workflows/cmake-flatcc.yaml | 61 +++++++++ CMakeLists.txt | 10 +- ci/scripts/test_cmake_flatcc.py | 190 ++++++++++++++++++++++++++++ 3 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/cmake-flatcc.yaml create mode 100644 ci/scripts/test_cmake_flatcc.py diff --git a/.github/workflows/cmake-flatcc.yaml b/.github/workflows/cmake-flatcc.yaml new file mode 100644 index 000000000..5c20cfe91 --- /dev/null +++ b/.github/workflows/cmake-flatcc.yaml @@ -0,0 +1,61 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: cmake-flatcc + +on: + push: + branches: [main] + pull_request: + paths: + - 'CMakeLists.txt' + - 'ci/scripts/test_cmake_flatcc.py' + - '.github/workflows/cmake-flatcc.yaml' + - 'src/nanoarrow/**' + - 'thirdparty/flatcc/**' + +permissions: + contents: read + +jobs: + external-flatcc: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + cmake: ['latest'] + include: + - os: ubuntu-latest + cmake: '3.18.4.post1' + - os: ubuntu-latest + cmake: '3.23.3' + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 + with: + python-version: '3.11' + - name: Install CMake + shell: bash + run: | + if [ "${{ matrix.cmake }}" = "latest" ]; then + python -m pip install --upgrade cmake + else + python -m pip install "cmake==${{ matrix.cmake }}" + fi + - name: Test external flatcc discovery and linking + run: python ci/scripts/test_cmake_flatcc.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 919da6b46..eb3008c3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ # under the License. message(STATUS "Building using CMake version: ${CMAKE_VERSION}") -cmake_minimum_required(VERSION 3.14) +cmake_minimum_required(VERSION 3.18) set(NANOARROW_VERSION "0.10.0-SNAPSHOT") string(REGEX MATCH "^[0-9]+\\.[0-9]+\\.[0-9]+" NANOARROW_BASE_VERSION @@ -37,7 +37,7 @@ option(NANOARROW_IPC "Build IPC extension" OFF) option(NANOARROW_FLATCC_ROOT_DIR "Root directory for flatcc include and lib directories" OFF) option(NANOARROW_FLATCC_INCLUDE_DIR "Include directory for flatcc includes" OFF) -option(NANOARROW_FLATCC_LIB_DIR "Library directory that contains libflatccrt.a" OFF) +option(NANOARROW_FLATCC_LIB_DIR "Library directory that contains the flatcc runtime" OFF) option(NANOARROW_IPC_WITH_ZSTD "Build nanoarrow with ZSTD compression support built in" OFF) option(NANOARROW_IPC_WITH_LZ4 "Build nanoarrow with LZ4 compression support built in" OFF) @@ -95,8 +95,8 @@ if(NANOARROW_CODE_COVERAGE) endif() # Avoids a warning about timestamps on downloaded files (prefer new policy -# if available)) -if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.23") +# if available). +if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() @@ -241,6 +241,8 @@ if(NANOARROW_IPC) find_library(NANOARROW_FLATCC_LIBRARY_DEBUG NAMES "${CMAKE_STATIC_LIBRARY_PREFIX}flatccrt_d${CMAKE_STATIC_LIBRARY_SUFFIX}" flatccrt_d + "${CMAKE_STATIC_LIBRARY_PREFIX}flatccrt${CMAKE_STATIC_LIBRARY_SUFFIX}" + flatccrt PATHS "${NANOARROW_FLATCC_ROOT_DIR}/debug/lib" NO_DEFAULT_PATH) add_library(flatccrt UNKNOWN IMPORTED) diff --git a/ci/scripts/test_cmake_flatcc.py b/ci/scripts/test_cmake_flatcc.py new file mode 100644 index 000000000..e9aee4fce --- /dev/null +++ b/ci/scripts/test_cmake_flatcc.py @@ -0,0 +1,190 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +"""Build IPC against external flatcc runtimes without exercising package exports.""" + +import os +import subprocess +import tempfile +from pathlib import Path + + +def run(*args, **kwargs): + subprocess.run([str(arg) for arg in args], check=True, **kwargs) + + +def main(): + source = Path(__file__).resolve().parents[2] + with tempfile.TemporaryDirectory(prefix="nanoarrow-flatcc-") as tmp: + root = Path(tmp) + fixture = root / "fixture" + fixture.mkdir() + (fixture / "CMakeLists.txt").write_text( + """cmake_minimum_required(VERSION 3.18) +project(flatcc_fixture C) +add_library(flatccrt ${RUNTIME_TYPE} + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/builder.c" + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/emitter.c" + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/verifier.c" + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/refmap.c") +target_include_directories(flatccrt PRIVATE + "${NANOARROW_SOURCE}/thirdparty/flatcc/include") +set_target_properties(flatccrt PROPERTIES POSITION_INDEPENDENT_CODE ON + WINDOWS_EXPORT_ALL_SYMBOLS ON DEBUG_POSTFIX "${RUNTIME_DEBUG_POSTFIX}") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(subdir "debug/") +endif() +install(TARGETS flatccrt ARCHIVE DESTINATION "${subdir}lib" + LIBRARY DESTINATION "${subdir}lib" RUNTIME DESTINATION "${subdir}bin") +install(DIRECTORY "${NANOARROW_SOURCE}/thirdparty/flatcc/include/" + DESTINATION include) +""", + encoding="utf-8", + ) + consumer = root / "consumer" + consumer.mkdir() + (consumer / "CMakeLists.txt").write_text( + """cmake_minimum_required(VERSION 3.18) +project(flatcc_consumer C) +set(NANOARROW_IPC ON CACHE BOOL "") +add_subdirectory("${NANOARROW_SOURCE}" nanoarrow) +# Verify discovery as well as linking: a Release fallback can otherwise hide a +# missed unsuffixed Debug library. +if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND EXPECT_DEBUG) + if(NOT NANOARROW_FLATCC_LIBRARY_DEBUG MATCHES "/debug/lib/") + message(FATAL_ERROR "Did not select the external Debug runtime") + endif() +endif() +if(EXPECT_STATIC AND NOT WIN32) + if(NOT NANOARROW_FLATCC_LIBRARY MATCHES "[.]a$") + message(FATAL_ERROR "Did not prefer the static runtime") + endif() +endif() +add_executable(consumer main.c) +target_link_libraries(consumer PRIVATE nanoarrow::nanoarrow_ipc) +enable_testing() +add_test(NAME ipc-runtime COMMAND consumer) +""", + encoding="utf-8", + ) + (consumer / "main.c").write_text( + """#include +int main(void) { + struct ArrowIpcDecoder decoder; + if (ArrowIpcDecoderInit(&decoder)) return 1; + ArrowIpcDecoderReset(&decoder); + return 0; +} +""", + encoding="utf-8", + ) + # On Windows static and import libraries have the same filename. + layouts = [("static", ["STATIC"], "_d"), ("shared", ["SHARED"], "")] + if os.name != "nt": + layouts.append(("both", ["SHARED", "STATIC"], "_d")) + for name, types, postfix in layouts: + prefix = root / name + for kind in types: + for config in ("Release", "Debug"): + build = root / f"fixture-{name}-{kind}-{config}" + run( + "cmake", + "-S", + fixture, + "-B", + build, + f"-DNANOARROW_SOURCE={source.as_posix()}", + f"-DCMAKE_BUILD_TYPE={config}", + f"-DRUNTIME_TYPE={kind}", + f"-DRUNTIME_DEBUG_POSTFIX={postfix}", + f"-DCMAKE_INSTALL_PREFIX={prefix.as_posix()}", + ) + run( + "cmake", "--build", build, "--config", config, "--parallel", "2" + ) + run("cmake", "--install", build, "--config", config) + for mode in ("root", "dirs"): + for config in ("Release", "Debug"): + build = root / f"consumer-{name}-{mode}-{config}" + options = [f"-DNANOARROW_FLATCC_ROOT_DIR={prefix.as_posix()}"] + if mode == "dirs": + libdir = prefix / ("debug/lib" if config == "Debug" else "lib") + # Separate-directory discovery uses the unsuffixed name. + if config == "Debug" and postfix: + continue + include = (prefix / "include").as_posix() + options = [ + f"-DNANOARROW_FLATCC_INCLUDE_DIR={include}", + f"-DNANOARROW_FLATCC_LIB_DIR={libdir.as_posix()}", + ] + run( + "cmake", + "-S", + consumer, + "-B", + build, + f"-DNANOARROW_SOURCE={source.as_posix()}", + f"-DCMAKE_BUILD_TYPE={config}", + f"-DEXPECT_DEBUG={'ON' if mode == 'root' else 'OFF'}", + f"-DEXPECT_STATIC={'ON' if 'STATIC' in types else 'OFF'}", + *options, + ) + run( + "cmake", + "--build", + build, + "--config", + config, + "--target", + "consumer", + "nanoarrow_ipc_shared", + "--parallel", + "2", + ) + env = os.environ.copy() + bindir = prefix / ("debug/bin" if config == "Debug" else "bin") + env["PATH"] = os.pathsep.join([str(bindir), env["PATH"]]) + # --test-dir was added after the supported CMake minimum. + run( + "ctest", "-C", config, "--output-on-failure", cwd=build, env=env + ) + missing = root / "missing" + missing.mkdir() + result = subprocess.run( + [ + "cmake", + "-S", + str(source), + "-B", + str(root / "missing-build"), + "-DNANOARROW_IPC=ON", + f"-DNANOARROW_FLATCC_INCLUDE_DIR={source}/thirdparty/flatcc/include", + f"-DNANOARROW_FLATCC_LIB_DIR={missing}", + ], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + ) + if result.returncode == 0 or "NANOARROW_FLATCC_LIBRARY" not in result.stdout: + raise RuntimeError( + f"Expected missing-runtime configuration failure: {result.stdout}" + ) + print("External flatcc discovery checks passed.") + + +if __name__ == "__main__": + main() From dc5f1b927dedf29c7052b0de3a9e1dd4906b6a4e Mon Sep 17 00:00:00 2001 From: Dewey Dunnington Date: Sun, 25 Oct 2026 22:35:03 -0500 Subject: [PATCH 2/2] test(examples): translate flatcc CMake harness to Bash --- .github/workflows/cmake-flatcc.yaml | 5 +- ci/scripts/test_cmake_flatcc.py | 190 ------------------ examples/cmake-flatcc/README.md | 37 ++++ examples/cmake-flatcc/build.sh | 128 ++++++++++++ examples/cmake-flatcc/consumer/CMakeLists.txt | 39 ++++ examples/cmake-flatcc/consumer/main.c | 26 +++ examples/cmake-flatcc/fixture/CMakeLists.txt | 39 ++++ 7 files changed, 272 insertions(+), 192 deletions(-) delete mode 100644 ci/scripts/test_cmake_flatcc.py create mode 100644 examples/cmake-flatcc/README.md create mode 100755 examples/cmake-flatcc/build.sh create mode 100644 examples/cmake-flatcc/consumer/CMakeLists.txt create mode 100644 examples/cmake-flatcc/consumer/main.c create mode 100644 examples/cmake-flatcc/fixture/CMakeLists.txt diff --git a/.github/workflows/cmake-flatcc.yaml b/.github/workflows/cmake-flatcc.yaml index 5c20cfe91..251135bae 100644 --- a/.github/workflows/cmake-flatcc.yaml +++ b/.github/workflows/cmake-flatcc.yaml @@ -23,7 +23,7 @@ on: pull_request: paths: - 'CMakeLists.txt' - - 'ci/scripts/test_cmake_flatcc.py' + - 'examples/cmake-flatcc/**' - '.github/workflows/cmake-flatcc.yaml' - 'src/nanoarrow/**' - 'thirdparty/flatcc/**' @@ -58,4 +58,5 @@ jobs: python -m pip install "cmake==${{ matrix.cmake }}" fi - name: Test external flatcc discovery and linking - run: python ci/scripts/test_cmake_flatcc.py + shell: bash + run: examples/cmake-flatcc/build.sh diff --git a/ci/scripts/test_cmake_flatcc.py b/ci/scripts/test_cmake_flatcc.py deleted file mode 100644 index e9aee4fce..000000000 --- a/ci/scripts/test_cmake_flatcc.py +++ /dev/null @@ -1,190 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -"""Build IPC against external flatcc runtimes without exercising package exports.""" - -import os -import subprocess -import tempfile -from pathlib import Path - - -def run(*args, **kwargs): - subprocess.run([str(arg) for arg in args], check=True, **kwargs) - - -def main(): - source = Path(__file__).resolve().parents[2] - with tempfile.TemporaryDirectory(prefix="nanoarrow-flatcc-") as tmp: - root = Path(tmp) - fixture = root / "fixture" - fixture.mkdir() - (fixture / "CMakeLists.txt").write_text( - """cmake_minimum_required(VERSION 3.18) -project(flatcc_fixture C) -add_library(flatccrt ${RUNTIME_TYPE} - "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/builder.c" - "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/emitter.c" - "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/verifier.c" - "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/refmap.c") -target_include_directories(flatccrt PRIVATE - "${NANOARROW_SOURCE}/thirdparty/flatcc/include") -set_target_properties(flatccrt PROPERTIES POSITION_INDEPENDENT_CODE ON - WINDOWS_EXPORT_ALL_SYMBOLS ON DEBUG_POSTFIX "${RUNTIME_DEBUG_POSTFIX}") -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(subdir "debug/") -endif() -install(TARGETS flatccrt ARCHIVE DESTINATION "${subdir}lib" - LIBRARY DESTINATION "${subdir}lib" RUNTIME DESTINATION "${subdir}bin") -install(DIRECTORY "${NANOARROW_SOURCE}/thirdparty/flatcc/include/" - DESTINATION include) -""", - encoding="utf-8", - ) - consumer = root / "consumer" - consumer.mkdir() - (consumer / "CMakeLists.txt").write_text( - """cmake_minimum_required(VERSION 3.18) -project(flatcc_consumer C) -set(NANOARROW_IPC ON CACHE BOOL "") -add_subdirectory("${NANOARROW_SOURCE}" nanoarrow) -# Verify discovery as well as linking: a Release fallback can otherwise hide a -# missed unsuffixed Debug library. -if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND EXPECT_DEBUG) - if(NOT NANOARROW_FLATCC_LIBRARY_DEBUG MATCHES "/debug/lib/") - message(FATAL_ERROR "Did not select the external Debug runtime") - endif() -endif() -if(EXPECT_STATIC AND NOT WIN32) - if(NOT NANOARROW_FLATCC_LIBRARY MATCHES "[.]a$") - message(FATAL_ERROR "Did not prefer the static runtime") - endif() -endif() -add_executable(consumer main.c) -target_link_libraries(consumer PRIVATE nanoarrow::nanoarrow_ipc) -enable_testing() -add_test(NAME ipc-runtime COMMAND consumer) -""", - encoding="utf-8", - ) - (consumer / "main.c").write_text( - """#include -int main(void) { - struct ArrowIpcDecoder decoder; - if (ArrowIpcDecoderInit(&decoder)) return 1; - ArrowIpcDecoderReset(&decoder); - return 0; -} -""", - encoding="utf-8", - ) - # On Windows static and import libraries have the same filename. - layouts = [("static", ["STATIC"], "_d"), ("shared", ["SHARED"], "")] - if os.name != "nt": - layouts.append(("both", ["SHARED", "STATIC"], "_d")) - for name, types, postfix in layouts: - prefix = root / name - for kind in types: - for config in ("Release", "Debug"): - build = root / f"fixture-{name}-{kind}-{config}" - run( - "cmake", - "-S", - fixture, - "-B", - build, - f"-DNANOARROW_SOURCE={source.as_posix()}", - f"-DCMAKE_BUILD_TYPE={config}", - f"-DRUNTIME_TYPE={kind}", - f"-DRUNTIME_DEBUG_POSTFIX={postfix}", - f"-DCMAKE_INSTALL_PREFIX={prefix.as_posix()}", - ) - run( - "cmake", "--build", build, "--config", config, "--parallel", "2" - ) - run("cmake", "--install", build, "--config", config) - for mode in ("root", "dirs"): - for config in ("Release", "Debug"): - build = root / f"consumer-{name}-{mode}-{config}" - options = [f"-DNANOARROW_FLATCC_ROOT_DIR={prefix.as_posix()}"] - if mode == "dirs": - libdir = prefix / ("debug/lib" if config == "Debug" else "lib") - # Separate-directory discovery uses the unsuffixed name. - if config == "Debug" and postfix: - continue - include = (prefix / "include").as_posix() - options = [ - f"-DNANOARROW_FLATCC_INCLUDE_DIR={include}", - f"-DNANOARROW_FLATCC_LIB_DIR={libdir.as_posix()}", - ] - run( - "cmake", - "-S", - consumer, - "-B", - build, - f"-DNANOARROW_SOURCE={source.as_posix()}", - f"-DCMAKE_BUILD_TYPE={config}", - f"-DEXPECT_DEBUG={'ON' if mode == 'root' else 'OFF'}", - f"-DEXPECT_STATIC={'ON' if 'STATIC' in types else 'OFF'}", - *options, - ) - run( - "cmake", - "--build", - build, - "--config", - config, - "--target", - "consumer", - "nanoarrow_ipc_shared", - "--parallel", - "2", - ) - env = os.environ.copy() - bindir = prefix / ("debug/bin" if config == "Debug" else "bin") - env["PATH"] = os.pathsep.join([str(bindir), env["PATH"]]) - # --test-dir was added after the supported CMake minimum. - run( - "ctest", "-C", config, "--output-on-failure", cwd=build, env=env - ) - missing = root / "missing" - missing.mkdir() - result = subprocess.run( - [ - "cmake", - "-S", - str(source), - "-B", - str(root / "missing-build"), - "-DNANOARROW_IPC=ON", - f"-DNANOARROW_FLATCC_INCLUDE_DIR={source}/thirdparty/flatcc/include", - f"-DNANOARROW_FLATCC_LIB_DIR={missing}", - ], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - ) - if result.returncode == 0 or "NANOARROW_FLATCC_LIBRARY" not in result.stdout: - raise RuntimeError( - f"Expected missing-runtime configuration failure: {result.stdout}" - ) - print("External flatcc discovery checks passed.") - - -if __name__ == "__main__": - main() diff --git a/examples/cmake-flatcc/README.md b/examples/cmake-flatcc/README.md new file mode 100644 index 000000000..592fba16b --- /dev/null +++ b/examples/cmake-flatcc/README.md @@ -0,0 +1,37 @@ + + +# CMake External flatcc Examples + +This example builds nanoarrow IPC against external flatcc runtimes and runs a +small IPC consumer. It checks static and shared runtimes, static preference when +both are available, Debug and Release discovery, root and separate-directory +options, and configuration failure when the runtime is missing. It exercises +build-time linking; package exports are covered separately by `cmake-scenarios`. + +Run from this directory with Bash, CMake 3.18 or newer, and a C compiler: + +```bash +./build.sh +``` + +The script can also be invoked from any working directory. It builds in a +temporary directory and removes it on exit. On Windows, run it with Git Bash; +the combined static/shared layout is skipped because static and import libraries +use the same filename. diff --git a/examples/cmake-flatcc/build.sh b/examples/cmake-flatcc/build.sh new file mode 100755 index 000000000..145cc7933 --- /dev/null +++ b/examples/cmake-flatcc/build.sh @@ -0,0 +1,128 @@ +#!/usr/bin/env bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +set -exuo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source_dir="$(cd "${script_dir}/../.." && pwd)" +root="$(mktemp -d "${TMPDIR:-/tmp}/nanoarrow-flatcc-XXXXXX")" +trap 'rm -rf "${root}"' EXIT + +# CMake needs native paths in cache variables when running from Git Bash. +cmake_path() { + if [[ "${OSTYPE}" == msys* || "${OSTYPE}" == cygwin* ]]; then + cygpath -m "$1" + else + printf '%s\n' "$1" + fi +} + +source_dir="$(cmake_path "${source_dir}")" +layouts=(static shared) +# On Windows static and import libraries have the same filename. +if [[ "${OSTYPE}" != msys* && "${OSTYPE}" != cygwin* ]]; then + layouts+=(both) +fi + +for layout in "${layouts[@]}"; do + prefix="${root}/${layout}" + postfix="_d" + expect_static=ON + case "${layout}" in + static) types=(STATIC) ;; + shared) + types=(SHARED) + postfix="" + expect_static=OFF + ;; + both) types=(SHARED STATIC) ;; + esac + + for kind in "${types[@]}"; do + for config in Release Debug; do + build="${root}/fixture-${layout}-${kind}-${config}" + cmake -S "$(cmake_path "${script_dir}/fixture")" -B "$(cmake_path "${build}")" \ + "-DNANOARROW_SOURCE=${source_dir}" \ + "-DCMAKE_BUILD_TYPE=${config}" \ + "-DRUNTIME_TYPE=${kind}" \ + "-DRUNTIME_DEBUG_POSTFIX=${postfix}" \ + "-DCMAKE_INSTALL_PREFIX=$(cmake_path "${prefix}")" + cmake --build "$(cmake_path "${build}")" --config "${config}" --parallel 2 + cmake --install "$(cmake_path "${build}")" --config "${config}" + done + done + + for mode in root dirs; do + for config in Release Debug; do + build="${root}/consumer-${layout}-${mode}-${config}" + libdir="${prefix}/lib" + bindir="${prefix}/bin" + if [ "${config}" = Debug ]; then + libdir="${prefix}/debug/lib" + bindir="${prefix}/debug/bin" + fi + + options=("-DNANOARROW_FLATCC_ROOT_DIR=$(cmake_path "${prefix}")") + expect_debug=ON + if [ "${mode}" = dirs ]; then + # Separate-directory discovery uses the unsuffixed name. + if [ "${config}" = Debug ] && [ -n "${postfix}" ]; then + continue + fi + options=( + "-DNANOARROW_FLATCC_INCLUDE_DIR=$(cmake_path "${prefix}/include")" + "-DNANOARROW_FLATCC_LIB_DIR=$(cmake_path "${libdir}")" + ) + expect_debug=OFF + fi + + cmake -S "$(cmake_path "${script_dir}/consumer")" -B "$(cmake_path "${build}")" \ + "-DNANOARROW_SOURCE=${source_dir}" \ + "-DCMAKE_BUILD_TYPE=${config}" \ + "-DEXPECT_DEBUG=${expect_debug}" \ + "-DEXPECT_STATIC=${expect_static}" \ + "${options[@]}" + cmake --build "$(cmake_path "${build}")" --config "${config}" \ + --target consumer nanoarrow_ipc_shared --parallel 2 + # --test-dir was added after the supported CMake minimum. + ( + cd "${build}" + PATH="${bindir}:${PATH}" ctest -C "${config}" --output-on-failure + ) + done + done +done + +mkdir "${root}/missing" +if cmake -S "${source_dir}" -B "$(cmake_path "${root}/missing-build")" \ + -DNANOARROW_IPC=ON \ + "-DNANOARROW_FLATCC_INCLUDE_DIR=${source_dir}/thirdparty/flatcc/include" \ + "-DNANOARROW_FLATCC_LIB_DIR=$(cmake_path "${root}/missing")" \ + > "${root}/missing.log" 2>&1; then + cat "${root}/missing.log" + echo "Expected missing-runtime configuration failure" >&2 + exit 1 +fi +if ! grep -q NANOARROW_FLATCC_LIBRARY "${root}/missing.log"; then + cat "${root}/missing.log" + echo "Configuration failed for a reason other than a missing runtime" >&2 + exit 1 +fi + +echo "External flatcc discovery checks passed." diff --git a/examples/cmake-flatcc/consumer/CMakeLists.txt b/examples/cmake-flatcc/consumer/CMakeLists.txt new file mode 100644 index 000000000..32d7406f9 --- /dev/null +++ b/examples/cmake-flatcc/consumer/CMakeLists.txt @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +cmake_minimum_required(VERSION 3.18) +project(flatcc_consumer C) +set(NANOARROW_IPC + ON + CACHE BOOL "") +add_subdirectory("${NANOARROW_SOURCE}" nanoarrow) +# Verify discovery as well as linking: a Release fallback can otherwise hide a +# missed unsuffixed Debug library. +if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND EXPECT_DEBUG) + if(NOT NANOARROW_FLATCC_LIBRARY_DEBUG MATCHES "/debug/lib/") + message(FATAL_ERROR "Did not select the external Debug runtime") + endif() +endif() +if(EXPECT_STATIC AND NOT WIN32) + if(NOT NANOARROW_FLATCC_LIBRARY MATCHES "[.]a$") + message(FATAL_ERROR "Did not prefer the static runtime") + endif() +endif() +add_executable(consumer main.c) +target_link_libraries(consumer PRIVATE nanoarrow::nanoarrow_ipc) +enable_testing() +add_test(NAME ipc-runtime COMMAND consumer) diff --git a/examples/cmake-flatcc/consumer/main.c b/examples/cmake-flatcc/consumer/main.c new file mode 100644 index 000000000..a8915226e --- /dev/null +++ b/examples/cmake-flatcc/consumer/main.c @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +int main(void) { + struct ArrowIpcDecoder decoder; + if (ArrowIpcDecoderInit(&decoder)) return 1; + ArrowIpcDecoderReset(&decoder); + return 0; +} diff --git a/examples/cmake-flatcc/fixture/CMakeLists.txt b/examples/cmake-flatcc/fixture/CMakeLists.txt new file mode 100644 index 000000000..4cce145ec --- /dev/null +++ b/examples/cmake-flatcc/fixture/CMakeLists.txt @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +cmake_minimum_required(VERSION 3.18) +project(flatcc_fixture C) +add_library(flatccrt + ${RUNTIME_TYPE} + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/builder.c" + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/emitter.c" + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/verifier.c" + "${NANOARROW_SOURCE}/thirdparty/flatcc/src/runtime/refmap.c") +target_include_directories(flatccrt + PRIVATE "${NANOARROW_SOURCE}/thirdparty/flatcc/include") +set_target_properties(flatccrt + PROPERTIES POSITION_INDEPENDENT_CODE ON + WINDOWS_EXPORT_ALL_SYMBOLS ON + DEBUG_POSTFIX "${RUNTIME_DEBUG_POSTFIX}") +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(subdir "debug/") +endif() +install(TARGETS flatccrt + ARCHIVE DESTINATION "${subdir}lib" + LIBRARY DESTINATION "${subdir}lib" + RUNTIME DESTINATION "${subdir}bin") +install(DIRECTORY "${NANOARROW_SOURCE}/thirdparty/flatcc/include/" DESTINATION include)