diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index dca7a3dfc..902619beb 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -109,3 +109,12 @@ jobs: cmake .. cmake --build . ctest . + + - name: Comprehensive CMake example + run: | + cd examples/cmake-scenarios + ./build.sh + for dir in scratch/build*; do + ./${dir}/minimal_cpp_app; + echo ; + done diff --git a/.gitignore b/.gitignore index 205451754..ab5821a73 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ _coverage/ build/ +scratch/ out/ arrow-hpp .DS_Store @@ -24,3 +25,4 @@ CMakeUserPresets.json .vscode .Rproj.user .cache +*.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8714c7092..1feec1357 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,6 @@ else() endif() option(NANOARROW_CODE_COVERAGE "Enable coverage reporting" OFF) -add_library(coverage_config INTERFACE) # Avoids a warning about timestamps on downloaded files (prefer new policy # if available)) @@ -111,6 +110,8 @@ if(NANOARROW_BUNDLE) if(NANOARROW_BUILD_TESTS) include_directories(${CMAKE_BINARY_DIR}/amalgamation) add_library(nanoarrow ${NANOARROW_C_TEMP}) + add_library(nanoarrow::nanoarrow ALIAS nanoarrow) + target_compile_definitions(nanoarrow PUBLIC "$<$:NANOARROW_DEBUG>") endif() @@ -120,6 +121,7 @@ if(NANOARROW_BUNDLE) else() add_library(nanoarrow src/nanoarrow/array.c src/nanoarrow/schema.c src/nanoarrow/array_stream.c src/nanoarrow/utils.c) + add_library(nanoarrow::nanoarrow ALIAS nanoarrow) target_include_directories(nanoarrow PUBLIC $ @@ -154,13 +156,50 @@ else() endif() endif() - install(TARGETS nanoarrow DESTINATION lib) + install(TARGETS nanoarrow + DESTINATION lib + EXPORT nanoarrow-exports) install(DIRECTORY src/ DESTINATION include FILES_MATCHING - PATTERN "*.h") + PATTERN "*.h*") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/nanoarrow_config.h DESTINATION include/nanoarrow) + + # Generate package files for the build and install trees. + include(CMakePackageConfigHelpers) + include(GNUInstallDirs) + + foreach(tree_type BUILD INSTALL) + if(tree_type STREQUAL "BUILD") + set(install_location ".") + else() + set(install_location "${CMAKE_INSTALL_LIBDIR}/cmake/nanoarrow") + endif() + + set(build_location "${PROJECT_BINARY_DIR}/${install_location}") + write_basic_package_version_file( + "${build_location}/nanoarrow-config-version.cmake" + VERSION ${nanoarrow_VERSION} + # After 1.0.0, we can use `SameMajorVersion` here. + COMPATIBILITY ExactVersion) + configure_package_config_file("${CMAKE_CURRENT_LIST_DIR}/cmake/config.cmake.in" + "${build_location}/nanoarrow-config.cmake" + INSTALL_DESTINATION "${install_location}") + + if(tree_type STREQUAL "BUILD") + export(EXPORT nanoarrow-exports + FILE "${build_location}/nanoarrow-targets.cmake" + NAMESPACE nanoarrow::) + + else() + install(DIRECTORY "${build_location}/" DESTINATION "${install_location}") + install(EXPORT nanoarrow-exports + DESTINATION "${install_location}" + FILE "nanoarrow-targets.cmake" + NAMESPACE nanoarrow::) + endif() + endforeach() endif() # Always build integration test if building tests @@ -215,34 +254,18 @@ if(NANOARROW_BUILD_TESTS) src/nanoarrow/integration/c_data_integration_test.cc) if(NANOARROW_CODE_COVERAGE) - target_compile_options(coverage_config INTERFACE -O0 -g --coverage) - target_link_options(coverage_config INTERFACE --coverage) - target_link_libraries(nanoarrow coverage_config) + target_compile_options(nanoarrow PUBLIC -O0 -g --coverage) + target_link_options(nanoarrow PUBLIC --coverage) endif() - target_link_libraries(utils_test - nanoarrow - gtest_main - ${NANOARROW_ARROW_TARGET} - coverage_config) - target_link_libraries(buffer_test nanoarrow gtest_main coverage_config) - target_link_libraries(array_test - nanoarrow - gtest_main - ${NANOARROW_ARROW_TARGET} - coverage_config) - target_link_libraries(schema_test - nanoarrow - gtest_main - ${NANOARROW_ARROW_TARGET} - coverage_config) - target_link_libraries(array_stream_test nanoarrow gtest_main coverage_config) - target_link_libraries(nanoarrow_hpp_test nanoarrow gtest_main coverage_config) - target_link_libraries(nanoarrow_testing_test - nanoarrow - gtest_main - nlohmann_json::nlohmann_json - coverage_config) + target_link_libraries(utils_test nanoarrow gtest_main ${NANOARROW_ARROW_TARGET}) + target_link_libraries(buffer_test nanoarrow gtest_main) + target_link_libraries(array_test nanoarrow gtest_main ${NANOARROW_ARROW_TARGET}) + target_link_libraries(schema_test nanoarrow gtest_main ${NANOARROW_ARROW_TARGET}) + target_link_libraries(array_stream_test nanoarrow gtest_main) + target_link_libraries(nanoarrow_hpp_test nanoarrow gtest_main) + target_link_libraries(nanoarrow_testing_test nanoarrow gtest_main + nlohmann_json::nlohmann_json) target_link_libraries(c_data_integration_test nanoarrow nanoarrow_c_data_integration gtest_main) diff --git a/cmake/config.cmake.in b/cmake/config.cmake.in new file mode 100644 index 000000000..021dc3137 --- /dev/null +++ b/cmake/config.cmake.in @@ -0,0 +1,28 @@ +# 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. + + +@PACKAGE_INIT@ + +cmake_minimum_required(VERSION @CMAKE_MINIMUM_REQUIRED_VERSION@) + +include("${CMAKE_CURRENT_LIST_DIR}/nanoarrow-targets.cmake" REQUIRED) +include("${CMAKE_CURRENT_LIST_DIR}/nanoarrow-config-version.cmake" REQUIRED) + +set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG "${CMAKE_CURRENT_LIST_FILE}") +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(${CMAKE_FIND_PACKAGE_NAME} CONFIG_MODE) diff --git a/examples/cmake-scenarios/CMakeLists.txt b/examples/cmake-scenarios/CMakeLists.txt new file mode 100644 index 000000000..018286877 --- /dev/null +++ b/examples/cmake-scenarios/CMakeLists.txt @@ -0,0 +1,48 @@ +# 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. + +message(STATUS "Building using CMake version: ${CMAKE_VERSION}") +cmake_minimum_required(VERSION 3.12) + +project(NanoArrowExampleCMakeMinimal LANGUAGES C CXX) + +option(FIND_NANOARROW "Find an existing nanoarrow" ON) + +# When adding nanoarrow's CMake directory to a CMake project that contains a library +# intended for use by others, set NANOARROW_NAMESPACE to rename symbols in the +# nanoarrow library such that they do not collide with other libraries that may also +# link to their own copy of nanoarrow. You may wish to include the namespace only +# on release builds, since the namespace implementation obscures inline help +# available in many text editors. +set(NANOARROW_NAMESPACE "ExampleCmakeMinimal") + +if(FIND_NANOARROW) + # Users should pin to a specific version of nanoarrow if they choose + # to find nanoarrow rather than pinning to a specific version via + # FetchContent. + find_package(nanoarrow REQUIRED) +else() + include(FetchContent) + fetchcontent_declare(nanoarrow_example_cmake_minimal + GIT_REPOSITORY https://github.com/apache/arrow-nanoarrow.git + GIT_TAG main + GIT_SHALLOW TRUE) + fetchcontent_makeavailable(nanoarrow_example_cmake_minimal) +endif() + +add_executable(minimal_cpp_app src/app.cpp) +target_link_libraries(minimal_cpp_app nanoarrow::nanoarrow) diff --git a/examples/cmake-scenarios/README.md b/examples/cmake-scenarios/README.md new file mode 100644 index 000000000..988a74c72 --- /dev/null +++ b/examples/cmake-scenarios/README.md @@ -0,0 +1,35 @@ + + +# CMake Comprehensive Examples + +This folder contains a CMake project that showcases the many different +ways in which nanoarrow may be used by other projects. The project +exposes a few options for configuring how nanoarrow is found and +built. It shows how nanoarrow may be fetched from source during the +build via FetchContent as well as how it may be preinstalled on the +system and then found by the consumer. + +To demonstrate the various scenarios, this project comes with a build +script that iterates through the different possibilities. To test this +out, simply run + +```bash +./build.sh +``` diff --git a/examples/cmake-scenarios/build.sh b/examples/cmake-scenarios/build.sh new file mode 100755 index 000000000..6eb4a4f1a --- /dev/null +++ b/examples/cmake-scenarios/build.sh @@ -0,0 +1,44 @@ +#!/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 + +# Build nanoarrow statically. +cmake -S ../.. -B scratch/nanoarrow_build_static/ -DCMAKE_INSTALL_PREFIX=scratch/nanoarrow_install_static/ +cmake --build scratch/nanoarrow_build_static/ +cmake --install scratch/nanoarrow_build_static/ + +# Build nanoarrow dynamically. +cmake -S ../.. -B scratch/nanoarrow_build_shared/ -DCMAKE_INSTALL_PREFIX=scratch/nanoarrow_install_shared/ -DBUILD_SHARED_LIBS=ON +cmake --build scratch/nanoarrow_build_shared/ +cmake --install scratch/nanoarrow_build_shared/ + +for nanoarrow_build_type in static shared; do + # Build the project against the built nanoarrow. + cmake -S . -B scratch/build_${nanoarrow_build_type}/ -Dnanoarrow_ROOT=scratch/nanoarrow_build_${nanoarrow_build_type}/ + cmake --build scratch/build_${nanoarrow_build_type}/ + + # Build the project against the installed nanoarrow. + cmake -S . -B scratch/build_against_install_${nanoarrow_build_type}/ -Dnanoarrow_ROOT=scratch/nanoarrow_install_${nanoarrow_build_type}/ + cmake --build scratch/build_against_install_${nanoarrow_build_type}/ + + # Now try using FetchContent to get nanoarrow from remote. + cmake -S . -B scratch/build_against_fetched_${nanoarrow_build_type}/ -DFIND_NANOARROW=OFF + cmake --build scratch/build_against_fetched_${nanoarrow_build_type}/ +done diff --git a/examples/cmake-scenarios/src/app.cpp b/examples/cmake-scenarios/src/app.cpp new file mode 100644 index 000000000..137fc03d8 --- /dev/null +++ b/examples/cmake-scenarios/src/app.cpp @@ -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 "nanoarrow/nanoarrow.h" +#include "nanoarrow/nanoarrow.hpp" + +int main(int argc, char* argv[]) { + nanoarrow::UniqueSchema schema; + NANOARROW_RETURN_NOT_OK(ArrowSchemaInitFromType(schema.get(), NANOARROW_TYPE_INT32)); + printf("Schema format for int32 is '%s'", schema->format); + return EXIT_SUCCESS; +}