You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by pa...@apache.org on 2024/03/21 23:28:57 UTC

(arrow-nanoarrow) branch main updated: fix: Make build and install dirs proper CMake package, fix C++ header inclusion, and add proper tests (#406)

This is an automated email from the ASF dual-hosted git repository.

paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git


The following commit(s) were added to refs/heads/main by this push:
     new bd160606 fix: Make build and install dirs proper CMake package, fix C++ header inclusion, and add proper tests (#406)
bd160606 is described below

commit bd16060651912aa3bdccc528efc4942b28320135
Author: Vyas Ramasubramani <vy...@gmail.com>
AuthorDate: Thu Mar 21 16:28:52 2024 -0700

    fix: Make build and install dirs proper CMake package, fix C++ header inclusion, and add proper tests (#406)
    
    Resolves #350.
    Resolves #400.
    
    Happy to reorganize things.
---
 .github/workflows/examples.yaml         |  9 ++++
 .gitignore                              |  2 +
 CMakeLists.txt                          | 81 +++++++++++++++++++++------------
 .gitignore => cmake/config.cmake.in     | 22 +++++----
 examples/cmake-scenarios/CMakeLists.txt | 48 +++++++++++++++++++
 examples/cmake-scenarios/README.md      | 35 ++++++++++++++
 examples/cmake-scenarios/build.sh       | 44 ++++++++++++++++++
 examples/cmake-scenarios/src/app.cpp    | 26 +++++++++++
 8 files changed, 228 insertions(+), 39 deletions(-)

diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml
index dca7a3df..902619be 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 20545175..ab5821a7 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 8714c709..1feec135 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 "$<$<CONFIG:Debug>: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 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
@@ -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/.gitignore b/cmake/config.cmake.in
similarity index 61%
copy from .gitignore
copy to cmake/config.cmake.in
index 20545175..021dc313 100644
--- a/.gitignore
+++ b/cmake/config.cmake.in
@@ -6,7 +6,7 @@
 # "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
+# 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
@@ -15,12 +15,14 @@
 # specific language governing permissions and limitations
 # under the License.
 
-_coverage/
-build/
-out/
-arrow-hpp
-.DS_Store
-CMakeUserPresets.json
-.vscode
-.Rproj.user
-.cache
+
+@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 00000000..01828687
--- /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 00000000..988a74c7
--- /dev/null
+++ b/examples/cmake-scenarios/README.md
@@ -0,0 +1,35 @@
+<!---
+  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 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 00000000..6eb4a4f1
--- /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 00000000..137fc03d
--- /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;
+}