From 2b935cf753b16d5e96ccc04ba3c9adcb7e0b40bf Mon Sep 17 00:00:00 2001 From: Dewey Dunnington Date: Tue, 18 Jun 2024 19:52:48 +0000 Subject: [PATCH] chore: Move bundling from CMake to Python (#508) Some of the work with the Meson build system has highlighted that the bundling is currently very inflexible because it's implemented in CMake. This was initially done because it made it easy to use `configure_file()` in CMake to keep the version information consistent, and because it allowed a straightforward path to testing the bundled files in the same way as the normal build. This had the unfortunate side effect of requiring CMake to "build" the R or Python packages as is generally confusing, and used the CMake "install" in a confusing way (it installed sources). Instead, we can do this with a Python script (and call that from CMake, R, and Python). The testing of the namespaced builds is still done in CMake, which is essential to ensure that both build types are tested in the same way. This also closes #485 by prefixing all nanoarrow includes with "nanoarrow/" in the source files. Many of them had to not use this prefix because when the files were bundled they weren't always bundled into a "nanoarrow/" directory. This feature has been moved to the bundling script which can now namespace or un-namespace the nanoarrow includes. --- .github/workflows/bundle.yaml | 29 +- .github/workflows/examples.yaml | 29 +- CMakeLists.txt | 531 +++++++----------- ci/scripts/bundle.py | 367 ++++++++++++ ci/scripts/test_bundle.py | 59 ++ examples/cmake-scenarios/CMakeLists.txt | 1 + examples/vendored-ipc/README.md | 44 +- examples/vendored-minimal/README.md | 26 +- examples/vendored-minimal/src/library.c | 2 +- .../src/{ => nanoarrow}/nanoarrow.h | 0 python/bootstrap.py | 56 +- r/bootstrap.R | 95 +--- src/nanoarrow/array.c | 2 +- src/nanoarrow/array_stream.c | 2 +- src/nanoarrow/nanoarrow.hpp | 2 +- src/nanoarrow/nanoarrow_device.c | 5 +- src/nanoarrow/nanoarrow_device.h | 2 +- src/nanoarrow/nanoarrow_device.hpp | 2 +- src/nanoarrow/nanoarrow_device_cuda.c | 2 +- src/nanoarrow/nanoarrow_device_cuda.h | 2 +- src/nanoarrow/nanoarrow_device_cuda_test.cc | 4 +- src/nanoarrow/nanoarrow_device_hpp_test.cc | 2 +- src/nanoarrow/nanoarrow_device_metal.cc | 5 +- src/nanoarrow/nanoarrow_device_metal.h | 2 +- src/nanoarrow/nanoarrow_device_metal_test.cc | 5 +- src/nanoarrow/nanoarrow_device_test.cc | 2 +- src/nanoarrow/nanoarrow_gtest_util.hpp | 2 +- src/nanoarrow/nanoarrow_ipc.h | 2 +- src/nanoarrow/nanoarrow_ipc.hpp | 4 +- src/nanoarrow/nanoarrow_ipc_decoder.c | 6 +- src/nanoarrow/nanoarrow_ipc_reader.c | 4 +- src/nanoarrow/nanoarrow_testing.hpp | 2 +- src/nanoarrow/schema.c | 2 +- src/nanoarrow/utils.c | 2 +- 34 files changed, 748 insertions(+), 554 deletions(-) create mode 100644 ci/scripts/bundle.py create mode 100644 ci/scripts/test_bundle.py rename examples/vendored-minimal/src/{ => nanoarrow}/nanoarrow.h (100%) diff --git a/.github/workflows/bundle.yaml b/.github/workflows/bundle.yaml index c3db6820c..8472bd62b 100644 --- a/.github/workflows/bundle.yaml +++ b/.github/workflows/bundle.yaml @@ -35,28 +35,15 @@ jobs: - name: Bundle nanoarrow run: | - mkdir build && cd build - cmake .. -DNANOARROW_BUNDLE=ON - cmake --build . - cmake --install . --prefix=../nanoarrow-latest - cd .. - cp LICENSE.txt nanoarrow-latest/LICENSE.txt - - - name: Bundle nanoarrow_ipc - run: | - rm -rf build - mkdir build && cd build - cmake .. -DNANOARROW_BUNDLE=ON -DNANOARROW_IPC=ON - cmake --build . - cmake --install . --prefix=../nanoarrow-latest + python3 ci/scripts/bundle.py \ + --source-output-dir=nanoarrow-latest \ + --include-output-dir=nanoarrow-latest \ + --header-namespace= \ + --with-device \ + --with-ipc \ + --with-flatcc - - name: Bundle nanoarrow_device - run: | - rm -rf build - mkdir build && cd build - cmake .. -DNANOARROW_BUNDLE=ON -DNANOARROW_DEVICE=ON - cmake --build . - cmake --install . --prefix=../nanoarrow-latest + cp LICENSE.txt nanoarrow-latest/LICENSE.txt - name: Compress bundle run: | diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index e0a1c20b6..b2c97dacb 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -60,13 +60,9 @@ jobs: - name: Minimal Vendored Example run: | cd examples/vendored-minimal - mkdir build && cd build - cmake ../../.. -DNANOARROW_BUNDLE=ON -DNANOARROW_NAMESPACE=ExampleVendored - cmake --build . - cmake --install . --prefix=../src - - cd ../src + python3 ../../ci/scripts/bundle.py --source-output-dir=src --include-output-dir=src + cd src gcc -c library.c nanoarrow.c ar rcs libexample_vendored_minimal_library.a library.o nanoarrow.o gcc -o example_vendored_minimal_app app.c libexample_vendored_minimal_library.a @@ -85,18 +81,15 @@ jobs: - name: Ipc Vendored Example run: | cd examples/vendored-ipc - mkdir build && cd build - cmake ../../.. -DNANOARROW_BUNDLE=ON -DNANOARROW_NAMESPACE=ExampleVendored - cmake --build . - cmake --install . --prefix=../src/nanoarrow - mkdir ../build_ipc && cd ../build_ipc - cmake ../../.. -DNANOARROW_BUNDLE=ON -DNANOARROW_IPC=ON - cmake --build . - cmake --install . --prefix=../src/nanoarrow - - cd ../src - - gcc -c library.c nanoarrow/nanoarrow.c nanoarrow/flatcc.c nanoarrow/nanoarrow_ipc.c -I./nanoarrow -I./nanoarrow/flatcc + python3 ../../ci/scripts/bundle.py \ + --source-output-dir=src \ + --include-output-dir=src \ + --symbol-namespace=MyProject \ + --with-ipc \ + --with-flatcc + + cd src + gcc -c library.c nanoarrow.c flatcc.c nanoarrow_ipc.c -I. ar rcs libexample_vendored_ipc_library.a library.o nanoarrow.o nanoarrow_ipc.o flatcc.o gcc -o example_vendored_ipc_app app.c libexample_vendored_ipc_library.a diff --git a/CMakeLists.txt b/CMakeLists.txt index 6788c8d89..fa24b7ccd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,13 +56,6 @@ option(NANOARROW_ARROW_STATIC option(NANOARROW_DEVICE_WITH_METAL "Build Apple metal libraries" OFF) option(NANOARROW_DEVICE_WITH_CUDA "Build CUDA libraries" OFF) -set(NANOARROW_DEVICE - NANOARROW_DEVICE - OR - NANOARROW_DEVICE_WITH_MDETAL - OR - NANOARROW_DEVICE_WITH_CUDA) - if(NANOARROW_IPC) add_library(ipc_coverage_config INTERFACE) endif() @@ -85,9 +78,96 @@ if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.23") cmake_policy(SET CMP0135 NEW) endif() -configure_file(src/nanoarrow/nanoarrow_config.h.in generated/nanoarrow_config.h) +if(NANOARROW_BUNDLE) + message(STATUS "Generating bundled nanoarrow sources using ci/scripts/bundle.py") + + find_package(Python3 + COMPONENTS Interpreter + REQUIRED) + + # Set up arguments to the bundler + set(NANOARROW_BUNDLE_ARGS "--with-ipc" "--with-device" "--with-flatcc") + + if(NANOARROW_BUNDLE_AS_CPP) + list(APPEND NANOARROW_BUNDLE_ARGS "--cpp") + set(NANOARROW_BUILD_SOURCES "${CMAKE_BINARY_DIR}/bundled/src/nanoarrow.cc") + else() + set(NANOARROW_BUILD_SOURCES "${CMAKE_BINARY_DIR}/bundled/src/nanoarrow.c") + endif() + + if(NANOARROW_NAMESPACE) + list(APPEND NANOARROW_BUNDLE_ARGS "--symbol-namespace=${NANOARROW_NAMESPACE}") + endif() + + # Run the bundler + execute_process(COMMAND ${Python3_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/ci/scripts/bundle.py" + "--output-dir" "${CMAKE_BINARY_DIR}/bundled" + ${NANOARROW_BUNDLE_ARGS} COMMAND_ECHO STDERR) + + set(NANOARROW_BUILD_INCLUDE_DIR "${CMAKE_BINARY_DIR}/bundled/include") + set(NANOARROW_IPC_BUILD_SOURCES "${CMAKE_BINARY_DIR}/bundled/src/nanoarrow_ipc.c") + set(NANOARROW_DEVICE_BUILD_SOURCES "${CMAKE_BINARY_DIR}/bundled/src/nanoarrow_device.c") + set(NANOARROW_FLATCC_BUILD_SOURCES "${CMAKE_BINARY_DIR}/bundled/src/flatcc.c") +else() + # Generate the version information + configure_file(src/nanoarrow/nanoarrow_config.h.in generated/nanoarrow_config.h) + set(NANOARROW_BUILD_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") +endif() + +# Start the list of targets and headers to install +set(NANOARROW_INSTALL_TARGETS nanoarrow) +set(NANOARROW_INSTALL_HEADERS ${NANOARROW_BUILD_INCLUDE_DIR}/nanoarrow/nanoarrow.h + ${NANOARROW_BUILD_INCLUDE_DIR}/nanoarrow/nanoarrow.hpp) + +# If the bundler didn't already assign the source files for the library, do so here +if(NOT NANOARROW_BUNDLE) + set(NANOARROW_BUILD_SOURCES src/nanoarrow/array.c src/nanoarrow/schema.c + src/nanoarrow/array_stream.c src/nanoarrow/utils.c) + list(APPEND + NANOARROW_INSTALL_HEADERS + src/nanoarrow/array_inline.h + src/nanoarrow/buffer_inline.h + src/nanoarrow/nanoarrow_types.h + "${CMAKE_CURRENT_BINARY_DIR}/generated/nanoarrow_config.h") +endif() + +# Add the nanoarrow library target +add_library(nanoarrow ${NANOARROW_BUILD_SOURCES}) +add_library(nanoarrow::nanoarrow ALIAS nanoarrow) + +target_include_directories(nanoarrow + PUBLIC $ + $ + $) +target_compile_definitions(nanoarrow PUBLIC "$<$:NANOARROW_DEBUG>") + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(nanoarrow + PRIVATE -Wall + -Werror + -Wextra + -Wpedantic + -Wno-type-limits + -Wmaybe-uninitialized + -Wunused-result + -Wconversion + -Wno-sign-conversion) + elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_C_COMPILER_ID STREQUAL + "Clang") + target_compile_options(nanoarrow + PRIVATE -Wall + -Werror + -Wextra + -Wpedantic + -Wdocumentation + -Wconversion + -Wno-sign-conversion) + endif() +endif() -if(NANOARROW_IPC AND (NANOARROW_BUILD_TESTS OR NOT NANOARROW_BUNDLE)) +if(NANOARROW_IPC) # Add the flatcc (runtime) dependency set(FLATCC_RTONLY ON @@ -98,16 +178,23 @@ if(NANOARROW_IPC AND (NANOARROW_BUILD_TESTS OR NOT NANOARROW_BUNDLE)) # A flatcc installation is unlikely, so default to building the vendored one if(NOT NANOARROW_FLATCC_INCLUDE_DIR AND NOT NANOARROW_FLATCC_ROOT_DIR) - add_library(flatccrt STATIC - thirdparty/flatcc/src/runtime/builder.c - thirdparty/flatcc/src/runtime/emitter.c - thirdparty/flatcc/src/runtime/verifier.c - thirdparty/flatcc/src/runtime/refmap.c) - set(NANOARROW_FLATCC_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/thirdparty/flatcc/include) + # If the bundler didn't already assign the source files for the library, do so here + if(NOT NANOARROW_BUNDLE) + set(NANOARROW_FLATCC_BUILD_SOURCES + thirdparty/flatcc/src/runtime/builder.c thirdparty/flatcc/src/runtime/emitter.c + thirdparty/flatcc/src/runtime/verifier.c thirdparty/flatcc/src/runtime/refmap.c) + set(NANOARROW_FLATCC_INCLUDE_DIR + "${CMAKE_CURRENT_LIST_DIR}/thirdparty/flatcc/include") + else() + set(NANOARROW_FLATCC_INCLUDE_DIR "${NANOARROW_BUILD_INCLUDE_DIR}") + endif() + + add_library(flatccrt STATIC ${NANOARROW_FLATCC_BUILD_SOURCES}) target_include_directories(flatccrt PUBLIC $ $) + elseif(NOT NANOARROW_FLATCC_ROOT_DIR) add_library(flatccrt STATIC IMPORTED) set_target_properties(flatccrt @@ -117,7 +204,7 @@ if(NANOARROW_IPC AND (NANOARROW_BUILD_TESTS OR NOT NANOARROW_BUNDLE)) "${NANOARROW_FLATCC_INCLUDE_DIR}") elseif(NOT NANOARROW_FLATCC_INCLUDE_DIR) - set(NANOARROW_FLATCC_INCLUDE_DIR ${NANOARROW_FLATCC_ROOT_DIR}/include) + set(NANOARROW_FLATCC_INCLUDE_DIR "${NANOARROW_FLATCC_ROOT_DIR}/include") add_library(flatccrt STATIC IMPORTED) set_target_properties(flatccrt PROPERTIES IMPORTED_LOCATION @@ -125,329 +212,91 @@ if(NANOARROW_IPC AND (NANOARROW_BUILD_TESTS OR NOT NANOARROW_BUNDLE)) INTERFACE_INCLUDE_DIRECTORIES "${NANOARROW_FLATCC_INCLUDE_DIR}") endif() -endif() - -if(NANOARROW_BUNDLE) - # Combine all headers into amalgamation/nanoarrow.h in the build directory - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/amalgamation) - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow) - set(NANOARROW_H_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow.h) - file(READ ${CMAKE_BINARY_DIR}/generated/nanoarrow_config.h SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_H_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/nanoarrow_types.h SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_H_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/nanoarrow.h SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_H_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/buffer_inline.h SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_H_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/array_inline.h SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_H_TEMP} "${SRC_FILE_CONTENTS}") - - # Remove includes that aren't needed when the headers are concatenated - file(READ ${NANOARROW_H_TEMP} SRC_FILE_CONTENTS) - string(REGEX REPLACE "#include \"[a-z_.]+\"" "" SRC_FILE_CONTENTS - "${SRC_FILE_CONTENTS}") - file(WRITE ${NANOARROW_H_TEMP} "${SRC_FILE_CONTENTS}") - - # Copy nanoarrow.hpp - set(NANOARROW_HPP_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow.hpp) - file(READ src/nanoarrow/nanoarrow.hpp SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_HPP_TEMP} "${SRC_FILE_CONTENTS}") - - # Copy nanoarrow_testing.hpp - set(NANOARROW_TESTING_HPP_TEMP - ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_testing.hpp) - file(READ src/nanoarrow/nanoarrow_testing.hpp SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_TESTING_HPP_TEMP} "${SRC_FILE_CONTENTS}") - - # Copy nanoarrow_gtest_util.hpp - set(NANOARROW_GTEST_UTIL_HPP_TEMP - ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_gtest_util.hpp) - file(READ src/nanoarrow/nanoarrow_gtest_util.hpp SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_GTEST_UTIL_HPP_TEMP} "${SRC_FILE_CONTENTS}") - - # Combine all source files into amalgamation/nanoarrow.c in the build directory - if(NANOARROW_BUNDLE_AS_CPP) - set(NANOARROW_C_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow.cc) - else() - set(NANOARROW_C_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow.c) - endif() - file(READ src/nanoarrow/utils.c SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/schema.c SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/array.c SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/array_stream.c SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_C_TEMP} "${SRC_FILE_CONTENTS}") - - # Add a library that the tests can link against (but don't install it) - 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() - - # Install the amalgamated header and source - install(FILES ${NANOARROW_H_TEMP} - ${NANOARROW_C_TEMP} - ${NANOARROW_HPP_TEMP} - ${NANOARROW_GTEST_UTIL_HPP_TEMP} - ${NANOARROW_TESTING_HPP_TEMP} - DESTINATION ".") - - if(NANOARROW_IPC) - # nanoarrow_ipc.h is already standalone - set(NANOARROW_IPC_H_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_ipc.h) - file(READ src/nanoarrow/nanoarrow_ipc.h SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_IPC_H_TEMP} "${SRC_FILE_CONTENTS}") - - set(NANOARROW_IPC_C_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_ipc.c) - file(READ src/nanoarrow/nanoarrow_ipc_flatcc_generated.h SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_IPC_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/nanoarrow_ipc_decoder.c SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_IPC_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ src/nanoarrow/nanoarrow_ipc_reader.c SRC_FILE_CONTENTS) - file(APPEND ${NANOARROW_IPC_C_TEMP} "${SRC_FILE_CONTENTS}") - - # remove the include for the generated files in the bundled version - file(READ ${NANOARROW_IPC_C_TEMP} SRC_FILE_CONTENTS) - string(REGEX REPLACE "#include \"nanoarrow_ipc_flatcc_generated.h\"" "" - SRC_FILE_CONTENTS "${SRC_FILE_CONTENTS}") - file(WRITE ${NANOARROW_IPC_C_TEMP} "${SRC_FILE_CONTENTS}") - - # combine the flatcc sources - set(FLATCC_C_TEMP ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/flatcc.c) - file(READ thirdparty/flatcc/src/runtime/builder.c SRC_FILE_CONTENTS) - file(WRITE ${FLATCC_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ thirdparty/flatcc/src/runtime/emitter.c SRC_FILE_CONTENTS) - file(APPEND ${FLATCC_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ thirdparty/flatcc/src/runtime/verifier.c SRC_FILE_CONTENTS) - file(APPEND ${FLATCC_C_TEMP} "${SRC_FILE_CONTENTS}") - file(READ thirdparty/flatcc/src/runtime/refmap.c SRC_FILE_CONTENTS) - file(APPEND ${FLATCC_C_TEMP} "${SRC_FILE_CONTENTS}") - - # Add a library that the tests can link against (but don't install it) - if(NANOARROW_BUILD_TESTS) - # Bundle flatcc into the nanoarrow_ipc library instead of - # link to the flatccrt static lib we declared above. - add_library(nanoarrow_ipc ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_ipc.c - ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/flatcc.c) - - target_include_directories(nanoarrow_ipc - PUBLIC $ - $ - $ - $ - ) - endif() - - # Install the amalgamated header and sources - install(FILES ${NANOARROW_IPC_H_TEMP} ${NANOARROW_IPC_C_TEMP} ${FLATCC_C_TEMP} - DESTINATION ".") - - # Also install the flatcc headers - install(DIRECTORY thirdparty/flatcc/include/flatcc DESTINATION ".") - endif() - - if(NANOARROW_DEVICE) - # The CMake build step is creating nanoarrow_device.c and nanoarrow_device.h; - # the CMake install step is copying them to a specific location - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/amalgamation) - file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow) - - # nanoarrow_device.h is currently standalone - set(NANOARROW_DEVICE_H_TEMP - ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_device.h) - file(READ src/nanoarrow/nanoarrow_device.h SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_DEVICE_H_TEMP} "${SRC_FILE_CONTENTS}") - - # nanoarrow_device.c is currently standalone - set(NANOARROW_DEVICE_C_TEMP - ${CMAKE_BINARY_DIR}/amalgamation/nanoarrow/nanoarrow_device.c) - file(READ src/nanoarrow/nanoarrow_device.c SRC_FILE_CONTENTS) - file(WRITE ${NANOARROW_DEVICE_C_TEMP} "${SRC_FILE_CONTENTS}") - - # Add a library that the tests can link against (but don't install it) - if(NANOARROW_BUILD_TESTS) - add_library(nanoarrow_device ${NANOARROW_DEVICE_C_TEMP}) - - target_include_directories(nanoarrow_device - PUBLIC $ - $ - $ - ) - endif() - # Install the amalgamated header and sources - install(FILES ${NANOARROW_DEVICE_H_TEMP} ${NANOARROW_DEVICE_C_TEMP} DESTINATION ".") + if(NOT NANOARROW_BUNDLE) + set(NANOARROW_IPC_BUILD_SOURCES src/nanoarrow/nanoarrow_ipc_decoder.c + src/nanoarrow/nanoarrow_ipc_reader.c) endif() -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 $ + add_library(nanoarrow_ipc ${NANOARROW_IPC_BUILD_SOURCES}) + target_link_libraries(nanoarrow_ipc PRIVATE flatccrt) + target_include_directories(nanoarrow_ipc + PUBLIC $ + $ + $) - target_include_directories(nanoarrow - PUBLIC $ - ) - target_compile_definitions(nanoarrow PUBLIC "$<$:NANOARROW_DEBUG>") - - if(CMAKE_BUILD_TYPE STREQUAL "Debug") - if(CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_compile_options(nanoarrow - PRIVATE -Wall - -Werror - -Wextra - -Wpedantic - -Wno-type-limits - -Wmaybe-uninitialized - -Wunused-result - -Wconversion - -Wno-sign-conversion) - elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_C_COMPILER_ID STREQUAL - "Clang") - target_compile_options(nanoarrow - PRIVATE -Wall - -Werror - -Wextra - -Wpedantic - -Wdocumentation - -Wconversion - -Wno-sign-conversion) - endif() - endif() - install(TARGETS nanoarrow - DESTINATION lib - EXPORT nanoarrow-exports) - install(DIRECTORY src/ - DESTINATION include - FILES_MATCHING - PATTERN "*.h*") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/nanoarrow_config.h + install(TARGETS nanoarrow_ipc DESTINATION lib) + install(FILES src/nanoarrow/nanoarrow_ipc.h + src/nanoarrow/nanoarrow_ipc_flatcc_generated.h DESTINATION include/nanoarrow) +endif() - # Generate package files for the build and install trees. - include(CMakePackageConfigHelpers) - include(GNUInstallDirs) +if(NANOARROW_DEVICE) + if(NANOARROW_DEVICE_WITH_METAL) + if(NOT EXISTS "${CMAKE_BINARY_DIR}/metal-cpp") + message(STATUS "Fetching metal-cpp") + file(DOWNLOAD + "https://developer.apple.com/metal/cpp/files/metal-cpp_macOS12_iOS15.zip" + "${CMAKE_BINARY_DIR}/metal-cpp.zip") + file(ARCHIVE_EXTRACT + INPUT + ${CMAKE_BINARY_DIR}/metal-cpp.zip + DESTINATION + ${CMAKE_BINARY_DIR}) + endif() - foreach(tree_type BUILD INSTALL) - if(tree_type STREQUAL "BUILD") - set(install_location ".") - else() - set(install_location "${CMAKE_INSTALL_LIBDIR}/cmake/nanoarrow") + if(NOT DEFINED CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 17) endif() + set(CMAKE_CXX_STANDARD_REQUIRED ON) - 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::) + find_library(METAL_LIBRARY Metal REQUIRED) + message(STATUS "Metal framework found at '${METAL_LIBRARY}'") - else() - install(DIRECTORY "${build_location}/" DESTINATION "${install_location}") - install(EXPORT nanoarrow-exports - DESTINATION "${install_location}" - FILE "nanoarrow-targets.cmake" - NAMESPACE nanoarrow::) - endif() - endforeach() + find_library(FOUNDATION_LIBRARY Foundation REQUIRED) + message(STATUS "Foundation framework found at '${FOUNDATION_LIBRARY}'") - if(NANOARROW_IPC) - add_library(nanoarrow_ipc src/nanoarrow/nanoarrow_ipc_decoder.c - src/nanoarrow/nanoarrow_ipc_reader.c) - target_link_libraries(nanoarrow_ipc PRIVATE flatccrt) - - target_include_directories(nanoarrow_ipc - PUBLIC $ - $ - $ - $) + find_library(QUARTZ_CORE_LIBRARY QuartzCore REQUIRED) + message(STATUS "CoreFoundation framework found at '${QUARTZ_CORE_LIBRARY}'") - install(TARGETS nanoarrow_ipc DESTINATION lib) - install(FILES src/nanoarrow/nanoarrow_ipc.h - src/nanoarrow/nanoarrow_ipc_flatcc_generated.h - DESTINATION include/nanoarrow) + set(NANOARROW_DEVICE_SOURCES_METAL src/nanoarrow/nanoarrow_device_metal.cc) + set(NANOARROW_DEVICE_INCLUDE_METAL ${CMAKE_BINARY_DIR}/metal-cpp) + set(NANOARROW_DEVICE_LIBS_METAL ${METAL_LIBRARY} ${FOUNDATION_LIBRARY} + ${QUARTZ_CORE_LIBRARY}) + set(NANOARROW_DEVICE_DEFS_METAL "NANOARROW_DEVICE_WITH_METAL") endif() - if(NANOARROW_DEVICE) - if(NANOARROW_DEVICE_WITH_METAL) - if(NOT EXISTS "${CMAKE_BINARY_DIR}/metal-cpp") - message(STATUS "Fetching metal-cpp") - file(DOWNLOAD - "https://developer.apple.com/metal/cpp/files/metal-cpp_macOS12_iOS15.zip" - "${CMAKE_BINARY_DIR}/metal-cpp.zip") - file(ARCHIVE_EXTRACT - INPUT - ${CMAKE_BINARY_DIR}/metal-cpp.zip - DESTINATION - ${CMAKE_BINARY_DIR}) - endif() - - if(NOT DEFINED CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 17) - endif() - set(CMAKE_CXX_STANDARD_REQUIRED ON) - - find_library(METAL_LIBRARY Metal REQUIRED) - message(STATUS "Metal framework found at '${METAL_LIBRARY}'") - - find_library(FOUNDATION_LIBRARY Foundation REQUIRED) - message(STATUS "Foundation framework found at '${FOUNDATION_LIBRARY}'") - - find_library(QUARTZ_CORE_LIBRARY QuartzCore REQUIRED) - message(STATUS "CoreFoundation framework found at '${QUARTZ_CORE_LIBRARY}'") - - set(NANOARROW_DEVICE_SOURCES_METAL src/nanoarrow/nanoarrow_device_metal.cc) - set(NANOARROW_DEVICE_INCLUDE_METAL ${CMAKE_BINARY_DIR}/metal-cpp) - set(NANOARROW_DEVICE_LIBS_METAL ${METAL_LIBRARY} ${FOUNDATION_LIBRARY} - ${QUARTZ_CORE_LIBRARY}) - set(NANOARROW_DEVICE_DEFS_METAL "NANOARROW_DEVICE_WITH_METAL") - endif() + if(NANOARROW_DEVICE_WITH_CUDA) + find_package(CUDAToolkit REQUIRED) + set(NANOARROW_DEVICE_SOURCES_CUDA src/nanoarrow/nanoarrow_device_cuda.c) + set(NANOARROW_DEVICE_LIBS_CUDA CUDA::cuda_driver) + set(NANOARROW_DEVICE_DEFS_CUDA "NANOARROW_DEVICE_WITH_CUDA") + endif() - if(NANOARROW_DEVICE_WITH_CUDA) - find_package(CUDAToolkit REQUIRED) - set(NANOARROW_DEVICE_SOURCES_CUDA src/nanoarrow/nanoarrow_device_cuda.c) - set(NANOARROW_DEVICE_LIBS_CUDA CUDA::cuda_driver) - set(NANOARROW_DEVICE_DEFS_CUDA "NANOARROW_DEVICE_WITH_CUDA") - endif() + # If the bundler didn't already assign the source files for the library, do so here + if(NOT NANOARROW_BUNDLE) + set(NANOARROW_DEVICE_BUILD_SOURCES src/nanoarrow/nanoarrow_device.c) + endif() - add_library(nanoarrow_device - src/nanoarrow/nanoarrow_device.c ${NANOARROW_DEVICE_SOURCES_METAL} - ${NANOARROW_DEVICE_SOURCES_CUDA}) + add_library(nanoarrow_device + ${NANOARROW_DEVICE_BUILD_SOURCES} ${NANOARROW_DEVICE_SOURCES_METAL} + ${NANOARROW_DEVICE_SOURCES_CUDA}) - target_include_directories(nanoarrow_device - PUBLIC $ - $ - $ - $ - $) + target_include_directories(nanoarrow_device + PUBLIC $ + $ + $ + $) - target_compile_definitions(nanoarrow_device PRIVATE ${NANOARROW_DEVICE_DEFS_METAL} - ${NANOARROW_DEVICE_DEFS_CUDA}) - target_link_libraries(nanoarrow_device PUBLIC ${NANOARROW_DEVICE_LIBS_METAL} - ${NANOARROW_DEVICE_LIBS_CUDA}) - target_compile_definitions(nanoarrow_device - PUBLIC "$<$:NANOARROW_DEBUG>") + target_compile_definitions(nanoarrow_device PRIVATE ${NANOARROW_DEVICE_DEFS_METAL} + ${NANOARROW_DEVICE_DEFS_CUDA}) + target_link_libraries(nanoarrow_device PUBLIC ${NANOARROW_DEVICE_LIBS_METAL} + ${NANOARROW_DEVICE_LIBS_CUDA}) + target_compile_definitions(nanoarrow_device PUBLIC "$<$:NANOARROW_DEBUG>") - install(TARGETS nanoarrow_device DESTINATION lib) - install(FILES src/nanoarrow/nanoarrow_device.h DESTINATION include/nanoarrow) - endif() + install(TARGETS nanoarrow_device DESTINATION lib) + install(FILES src/nanoarrow/nanoarrow_device.h DESTINATION include/nanoarrow) endif() # Always build integration test if building tests @@ -458,7 +307,8 @@ if(NANOARROW_BUILD_TESTS OR NANOARROW_BUILD_INTEGRATION_TESTS) add_library(nanoarrow_c_data_integration SHARED src/nanoarrow/integration/c_data_integration.cc) target_include_directories(nanoarrow_c_data_integration - PUBLIC $ + PUBLIC $ + $ $) target_link_libraries(nanoarrow_c_data_integration PRIVATE nanoarrow nlohmann_json) endif() @@ -665,3 +515,44 @@ endif() if(NANOARROW_BUILD_BENCHMARKS) add_subdirectory(dev/benchmarks) endif() + +# Ensure targets/headers can be installed +install(TARGETS ${NANOARROW_INSTALL_TARGETS} + DESTINATION lib + EXPORT nanoarrow-exports) +install(FILES ${NANOARROW_INSTALL_HEADERS} 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() diff --git a/ci/scripts/bundle.py b/ci/scripts/bundle.py new file mode 100644 index 000000000..d1c3702b1 --- /dev/null +++ b/ci/scripts/bundle.py @@ -0,0 +1,367 @@ +# 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. + +import io +import os +import pathlib +import re + + +def read_content(path_or_content): + if isinstance(path_or_content, pathlib.Path): + with open(path_or_content) as f: + return f.read() + else: + return str(path_or_content) + + +def write_content(path_or_content, out_path): + with open(out_path, "w") as f: + f.write(read_content(path_or_content)) + + +def configure_content(paths_or_content, args): + content = read_content(paths_or_content) + + for key, value in args.items(): + replace_key = f"@{key}@" + if content.count(replace_key) != 1: + raise ValueError( + "Expected exactly one occurrence of " + f"'{replace_key}' in '{paths_or_content}'" + ) + + content = content.replace(replace_key, str(value)) + + return content + + +def concatenate_content(paths_or_content): + out = io.StringIO() + + for path in paths_or_content: + out.write(read_content(path)) + + return out.getvalue() + + +def cmakelist_version(path_or_content): + content = read_content(path_or_content) + + version_match = re.search(r'set\(NANOARROW_VERSION "(.*?)"\)', content) + if version_match is None: + raise ValueError(f"Can't find NANOARROW_VERSION in '{path_or_content}'") + + version = version_match.group(1) + + component_match = re.search(r"^([0-9]+)\.([0-9]+)\.([0-9]+)", version) + return (version,) + tuple(int(component) for component in component_match.groups()) + + +def namespace_nanoarrow_includes(path_or_content, header_namespace="nanoarrow"): + content = read_content(path_or_content) + return re.sub( + r'#include "nanoarrow/([^"]+)"', f'#include "{header_namespace}\\1"', content + ) + + +def bundle_nanoarrow( + root_dir, + symbol_namespace=None, + header_namespace="nanoarrow/", + output_source_dir="src", + output_include_dir="include", + cpp=False, +): + root_dir = pathlib.Path(root_dir) + src_dir = root_dir / "src" / "nanoarrow" + + output_source_dir = pathlib.Path(output_source_dir) + output_include_dir = pathlib.Path(output_include_dir) / header_namespace + + version, major, minor, patch = cmakelist_version(root_dir / "CMakeLists.txt") + + if symbol_namespace is None: + namespace_define = "// #define NANOARROW_NAMESPACE YourNamespaceHere" + else: + namespace_define = f"#define NANOARROW_NAMESPACE {symbol_namespace}" + + nanoarrow_config_h = configure_content( + src_dir / "nanoarrow_config.h.in", + { + "NANOARROW_VERSION": version, + "NANOARROW_VERSION_MAJOR": major, + "NANOARROW_VERSION_MINOR": minor, + "NANOARROW_VERSION_PATCH": patch, + "NANOARROW_NAMESPACE_DEFINE": namespace_define, + }, + ) + + # Generate nanoarrow/nanoarrow.h + nanoarrow_h = concatenate_content( + [ + nanoarrow_config_h, + src_dir / "nanoarrow_types.h", + src_dir / "nanoarrow.h", + src_dir / "buffer_inline.h", + src_dir / "array_inline.h", + ] + ) + + nanoarrow_h = re.sub(r'#include "[a-z_.]+"', "", nanoarrow_h) + yield f"{output_include_dir}/nanoarrow.h", nanoarrow_h + + # Generate files that don't need special handling + for filename in [ + "nanoarrow.hpp", + "nanoarrow_testing.hpp", + "nanoarrow_gtest_util.hpp", + ]: + content = read_content(src_dir / filename) + content = namespace_nanoarrow_includes(content, header_namespace) + yield f"{output_include_dir}/{filename}", content + + # Generate nanoarrow/nanoarrow.c + nanoarrow_c = concatenate_content( + [ + src_dir / "utils.c", + src_dir / "schema.c", + src_dir / "array.c", + src_dir / "array_stream.c", + ] + ) + nanoarrow_c = namespace_nanoarrow_includes(nanoarrow_c, header_namespace) + + if cpp: + yield f"{output_source_dir}/nanoarrow.cc", nanoarrow_c + else: + yield f"{output_source_dir}/nanoarrow.c", nanoarrow_c + + +def bundle_nanoarrow_device( + root_dir, + header_namespace="nanoarrow/", + output_source_dir="src", + output_include_dir="include", +): + root_dir = pathlib.Path(root_dir) + src_dir = root_dir / "src" / "nanoarrow" + + output_source_dir = pathlib.Path(output_source_dir) + output_include_dir = pathlib.Path(output_include_dir) / header_namespace + + # Generate headers + for filename in ["nanoarrow_device.h", "nanoarrow_device.hpp"]: + content = read_content(src_dir / filename) + content = namespace_nanoarrow_includes(content, header_namespace) + yield f"{output_include_dir}/{filename}", content + + # Generate sources + for filename in ["nanoarrow_device.c"]: + content = read_content(src_dir / filename) + content = namespace_nanoarrow_includes(content, header_namespace) + yield f"{output_source_dir}/{filename}", content + + +def bundle_nanoarrow_ipc( + root_dir, + header_namespace="nanoarrow/", + output_source_dir="src", + output_include_dir="include", +): + root_dir = pathlib.Path(root_dir) + src_dir = root_dir / "src" / "nanoarrow" + + output_source_dir = pathlib.Path(output_source_dir) + output_include_dir = pathlib.Path(output_include_dir) / header_namespace + + # Generate headers + for filename in [ + "nanoarrow_ipc.h", + "nanoarrow_ipc.hpp", + ]: + content = read_content(src_dir / filename) + content = namespace_nanoarrow_includes(content, header_namespace) + yield f"{output_include_dir}/{filename}", content + + nanoarrow_ipc_c = concatenate_content( + [ + src_dir / "nanoarrow_ipc_flatcc_generated.h", + src_dir / "nanoarrow_ipc_decoder.c", + src_dir / "nanoarrow_ipc_reader.c", + ] + ) + nanoarrow_ipc_c = nanoarrow_ipc_c.replace( + '#include "nanoarrow/nanoarrow_ipc_flatcc_generated.h"', "" + ) + nanoarrow_ipc_c = namespace_nanoarrow_includes(nanoarrow_ipc_c, header_namespace) + yield f"{output_source_dir}/nanoarrow_ipc.c", nanoarrow_ipc_c + + +def bundle_flatcc( + root_dir, + output_source_dir="src", + output_include_dir="include", +): + root_dir = pathlib.Path(root_dir) + flatcc_dir = root_dir / "thirdparty" / "flatcc" + + output_source_dir = pathlib.Path(output_source_dir) + output_include_dir = pathlib.Path(output_include_dir) + + # Generate headers + include_dir = flatcc_dir / "include" + for abs_filename in include_dir.glob("flatcc/**/*.h"): + filename = abs_filename.relative_to(include_dir) + yield f"{output_include_dir}/{filename}", read_content( + flatcc_dir / "include" / filename + ) + + # Generate sources + src_dir = flatcc_dir / "src" / "runtime" + flatcc_c = concatenate_content( + [ + src_dir / "builder.c", + src_dir / "emitter.c", + src_dir / "verifier.c", + src_dir / "refmap.c", + ] + ) + + yield f"{output_source_dir}/flatcc.c", flatcc_c + + +def ensure_output_path_exists(out_path: pathlib.Path): + if out_path.is_dir() and out_path.exists(): + return + + if out_path.is_file() and out_path.exists(): + raise ValueError(f"Can't create directory '{out_path}': exists and is a file") + + ensure_output_path_exists(out_path.parent) + os.mkdir(out_path) + + +def do_bundle(bundler): + for out_file, out_content in bundler: + out_path = pathlib.Path(out_file) + ensure_output_path_exists(out_path.parent) + write_content(out_content, out_path) + + +if __name__ == "__main__": + import argparse + + parser = argparse.ArgumentParser(description="Bundled nanoarrow distribution") + parser.add_argument( + "--include-output-dir", + help="include/ directory in which nanoarrow headers should be placed", + ) + parser.add_argument( + "--source-output-dir", + help="Directory in which nanoarrow source files should be placed", + ) + parser.add_argument( + "--symbol-namespace", help="A value with which symbols should be prefixed" + ) + parser.add_argument( + "--header-namespace", + help=( + "The directory within include-output-dir that nanoarrow headers should be" + "placed" + ), + default="nanoarrow/", + ) + parser.add_argument( + "--output-dir", + help=( + "If include-output-dir or source-output-dir are missing, ensures a single " + "output directory with include/ and src/ subdirectories containing the " + "headers and sources, respectively" + ), + default="dist", + ) + parser.add_argument( + "--cpp", help="Bundle sources as C++ where possible", action="store_true" + ) + parser.add_argument( + "--with-device", + help="Include nanoarrow_device sources/headers", + action="store_true", + ) + parser.add_argument( + "--with-ipc", + help="Include nanoarrow_ipc sources/headers", + action="store_true", + ) + parser.add_argument( + "--with-flatcc", + help="Include flatcc sources/headers", + action="store_true", + ) + + args = parser.parse_args() + if args.include_output_dir is None: + args.include_output_dir = pathlib.Path(args.output_dir) / "include" + if args.source_output_dir is None: + args.source_output_dir = pathlib.Path(args.output_dir) / "src" + + root_dir = pathlib.Path(__file__).parent.parent.parent + + # Bundle nanoarrow + do_bundle( + bundle_nanoarrow( + root_dir, + symbol_namespace=args.symbol_namespace, + header_namespace=args.header_namespace, + output_source_dir=args.source_output_dir, + output_include_dir=args.include_output_dir, + cpp=args.cpp, + ) + ) + + # Bundle nanoarrow_device + if args.with_device: + do_bundle( + bundle_nanoarrow_device( + root_dir, + header_namespace=args.header_namespace, + output_source_dir=args.source_output_dir, + output_include_dir=args.include_output_dir, + ) + ) + + # Bundle nanoarrow_ipc + if args.with_ipc: + do_bundle( + bundle_nanoarrow_ipc( + root_dir, + header_namespace=args.header_namespace, + output_source_dir=args.source_output_dir, + output_include_dir=args.include_output_dir, + ) + ) + + # Bundle flatcc + if args.with_flatcc: + do_bundle( + bundle_flatcc( + root_dir, + output_source_dir=args.source_output_dir, + output_include_dir=args.include_output_dir, + ) + ) diff --git a/ci/scripts/test_bundle.py b/ci/scripts/test_bundle.py new file mode 100644 index 000000000..25ac73a47 --- /dev/null +++ b/ci/scripts/test_bundle.py @@ -0,0 +1,59 @@ +# 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. + +import os +import pathlib +import tempfile + +import bundle +import pytest + + +def test_read_write_content(): + assert bundle.read_content("one two three") == "one two three" + + with tempfile.TemporaryDirectory() as td: + file1 = os.path.join(td, "test1.txt") + bundle.write_content("One\nTwo\nThree\n", file1) + assert bundle.read_content(pathlib.Path(file1)) == "One\nTwo\nThree\n" + + +def test_configure_file(): + replaced = bundle.configure_content( + "@One@\n@Two@\n@Three@\n", {"Three": "Three replaced"} + ) + assert replaced == "@One@\n@Two@\nThree replaced\n" + + with pytest.raises(ValueError, match="Expected exactly one occurrence"): + bundle.configure_content("empty", {"Four": "Four replaced"}) + + +def test_concatenate_files(): + assert bundle.concatenate_content([]) == "" + + concatenated = bundle.concatenate_content( + ["One\nTwo\nThree\n", "Four\nFive\nSix\n"] + ) + assert concatenated == "One\nTwo\nThree\nFour\nFive\nSix\n" + + +def test_cmakelist_version(): + extracted = bundle.cmakelist_version('set(NANOARROW_VERSION "0.1.2-SNAPSHOT")') + assert extracted == ("0.1.2-SNAPSHOT", 0, 1, 2) + + this_cmakelists = pathlib.Path(__file__).parent.parent.parent / "CMakeLists.txt" + assert bundle.cmakelist_version(this_cmakelists) == ("0.6.0-SNAPSHOT", 0, 6, 0) diff --git a/examples/cmake-scenarios/CMakeLists.txt b/examples/cmake-scenarios/CMakeLists.txt index 018286877..61a01fb54 100644 --- a/examples/cmake-scenarios/CMakeLists.txt +++ b/examples/cmake-scenarios/CMakeLists.txt @@ -19,6 +19,7 @@ message(STATUS "Building using CMake version: ${CMAKE_VERSION}") cmake_minimum_required(VERSION 3.12) project(NanoArrowExampleCMakeMinimal LANGUAGES C CXX) +set(CMAKE_CXX_STANDARD 11) option(FIND_NANOARROW "Find an existing nanoarrow" ON) diff --git a/examples/vendored-ipc/README.md b/examples/vendored-ipc/README.md index 21e191982..6e9b3bfd6 100644 --- a/examples/vendored-ipc/README.md +++ b/examples/vendored-ipc/README.md @@ -29,52 +29,26 @@ to by another project. The nanoarrow/ files included in this example are stubs to illustrate how these files could fit in to a library and/or command-line application project. -The easiest way is to use the pre-generated versions in the dist/ folder of this -repository: +You can generate the bundled versions with the namespace defined using the Python +script `ci/scripts/bundle.py`: ```bash git clone https://github.com/apache/arrow-nanoarrow.git cd arrow-nanoarrow/examples/vendored-ipc -mkdir -p src/nanoarrow -cp ../../dist/nanoarrow.h src/nanoarrow/nanoarrow.h -cp ../../dist/nanoarrow.c src/nanoarrow/nanoarrow.c -cp ../../dist/nanoarrow_ipc.h src/nanoarrow/nanoarrow_ipc.h -cp ../../dist/nanoarrow_ipc.c src/nanoarrow/nanoarrow_ipc.c -cp ../../dist/flatcc.c src/nanoarrow/flatcc.c -cp -r ../../dist/flatcc src/nanoarrow/flatcc -``` - -If you use these, you will have to manually `#define NANOARROW_NAMESPACE MyProject` -in nanoarrow.h. - -You can also generate the bundled versions with the namespace defined using `cmake`: - -```bash -git clone https://github.com/apache/arrow-nanoarrow.git -cd arrow-nanoarrow/examples/vendored-ipc - -# First, build and install nanoarrow -mkdir build -pushd build -cmake ../../.. -DNANOARROW_BUNDLE=ON -DNANOARROW_NAMESPACE=ExampleVendored -cmake --build . -cmake --install . --prefix=../src/nanoarrow -popd -# Then, build and install nanoarrow_ipc -mkdir build_ipc -pushd build_ipc -cmake ../../.. -DNANOARROW_BUNDLE=ON -DNANOARROW_IPC=ON -cmake --build . -cmake --install . --prefix=../src/nanoarrow -popd +python ../../ci/scripts/bundle.py \ + --source-output-dir=src \ + --include-output-dir=src \ + --symbol-namespace=MyProject \ + --with-ipc \ + --with-flatcc ``` Then you can build/link the application/library using the build tool of your choosing: ```bash cd src -cc -c library.c nanoarrow/nanoarrow.c nanoarrow/flatcc.c nanoarrow/nanoarrow_ipc.c -I./nanoarrow -I./nanoarrow/flatcc +cc -c library.c nanoarrow.c flatcc.c nanoarrow_ipc.c -I. ar rcs libexample_vendored_ipc_library.a library.o nanoarrow.o nanoarrow_ipc.o flatcc.o cc -o example_vendored_ipc_app app.c libexample_vendored_ipc_library.a ``` diff --git a/examples/vendored-minimal/README.md b/examples/vendored-minimal/README.md index 9654ca200..8450797c4 100644 --- a/examples/vendored-minimal/README.md +++ b/examples/vendored-minimal/README.md @@ -29,28 +29,18 @@ linked to by another project. The nanoarrow.c and nanoarrow.h files included in this example are stubs to illustrate how these files could fit in to a library and/or command-line application project. -The easiest way is to use the pre-generated versions in the dist/ folder of this -repository: - -```bash -git clone https://github.com/apache/arrow-nanoarrow.git -cd arrow-nanoarrow/examples/vendored-minimal -cp ../../dist/nanoarrow.h src/nanoarrow.h -cp ../../dist/nanoarrow.c src/nanoarrow.c -``` - -If you use these, you will have to manually `#define NANOARROW_NAMESPACE MyProject` -manually in nanoarrow.h. - -You can also generate the bundled versions with the namespace defined using `cmake`: +You can generate the bundled versions with the namespace defined using the Python +script `ci/scripts/bundle.py`: ```bash git clone https://github.com/apache/arrow-nanoarrow.git cd arrow-nanoarrow -mkdir build && cd build -cmake .. -DNANOARROW_BUNDLE=ON -DNANOARROW_NAMESPACE=ExampleVendored -cmake --build . -cmake --install . --prefix=../examples/vendored-minimal/src + +cd examples/vendored-minimal +python ../../ci/scripts/bundle.py \ + --source-output-dir=src \ + --include-output-dir=src \ + --symbol-namespace=ExampleVendored ``` Then you can build/link the application/library using the build tool of your choosing: diff --git a/examples/vendored-minimal/src/library.c b/examples/vendored-minimal/src/library.c index fe6f3968f..271fbd163 100644 --- a/examples/vendored-minimal/src/library.c +++ b/examples/vendored-minimal/src/library.c @@ -20,7 +20,7 @@ #include -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" #include "library.h" diff --git a/examples/vendored-minimal/src/nanoarrow.h b/examples/vendored-minimal/src/nanoarrow/nanoarrow.h similarity index 100% rename from examples/vendored-minimal/src/nanoarrow.h rename to examples/vendored-minimal/src/nanoarrow/nanoarrow.h diff --git a/python/bootstrap.py b/python/bootstrap.py index 1ae11707f..4d8ca7609 100644 --- a/python/bootstrap.py +++ b/python/bootstrap.py @@ -15,12 +15,10 @@ # specific language governing permissions and limitations # under the License. -import os import pathlib import re import subprocess -import tempfile -import warnings +import sys # Generate the nanoarrow_c.pxd file used by the Cython extensions @@ -206,42 +204,24 @@ def copy_or_generate_nanoarrow_c(): "Attempt to build source distribution outside the nanoarrow repo" ) - cmake_bin = os.getenv("CMAKE_BIN") - if not cmake_bin: - cmake_bin = "cmake" - has_cmake = os.system(f"{cmake_bin} --version") == 0 - if not has_cmake: - raise ValueError("Attempt to build source distribution without CMake") - vendor_dir.mkdir(exist_ok=True) - - for cmake_project in [source_dir, source_dir]: - with tempfile.TemporaryDirectory() as build_dir: - try: - subprocess.run( - [ - cmake_bin, - "-B", - build_dir, - "-S", - cmake_project, - "-DNANOARROW_BUNDLE=ON", - "-DNANOARROW_DEVICE=ON", - "-DNANOARROW_IPC=ON", - "-DNANOARROW_NAMESPACE=PythonPkg", - ] - ) - subprocess.run( - [ - cmake_bin, - "--install", - build_dir, - "--prefix", - vendor_dir, - ] - ) - except Exception as e: - warnings.warn(f"cmake call failed: {e}") + subprocess.run( + [ + sys.executable, + source_dir / "ci" / "scripts" / "bundle.py", + "--symbol-namespace", + "PythonPkg", + "--header-namespace", + "", + "--source-output-dir", + vendor_dir, + "--include-output-dir", + vendor_dir, + "--with-device", + "--with-ipc", + "--with-flatcc", + ], + ) if not dst["nanoarrow.h"].exists(): raise ValueError("Attempt to vendor nanoarrow.c/h failed") diff --git a/r/bootstrap.R b/r/bootstrap.R index 7f947c103..4f9865aa7 100644 --- a/r/bootstrap.R +++ b/r/bootstrap.R @@ -15,81 +15,36 @@ # specific language governing permissions and limitations # under the License. -# If we are building within the repo, the safest way to proceed is to -# run CMake to regenerate the bundled nanoarrow.c/nanoarrow.h. -temp_dir <- tempfile() -on.exit(unlink(temp_dir, recursive = TRUE)) -dir.create(temp_dir) - -source_dir <- normalizePath("..", winslash = "/") -build_dir <- file.path(temp_dir, "build") -ipc_build_dir <- file.path(temp_dir, "build_ipc") -dist_dir <- file.path(temp_dir, "dist") -dir.create(ipc_build_dir) -dir.create(build_dir) -dir.create(dist_dir) - -cmake_command <- shQuote(Sys.getenv("CMAKE_BIN", "cmake")) - -run_cmake <- function(args, wd = ".") { - force(args) - - previous_wd <- getwd() - setwd(dir = wd) - on.exit(setwd(dir = previous_wd)) +# Use ci/scripts/bundle.py to generate source files/headers that are +# easier to use with the default R package build system + +run_bundler <- function() { + args <- c( + "--symbol-namespace=RPkg", + "--header-namespace=", + "--include-output-dir=src", + "--source-output-dir=src", + "--with-ipc", + "--with-flatcc" + ) + command <- sprintf( + "python3 ../ci/scripts/bundle.py %s", + paste(args, collapse = " ") + ) - command <- sprintf("%s %s", cmake_command, paste(args, collapse = " ")) exit_code <- system(command) message(sprintf("[%d] %s", exit_code, command)) exit_code == 0 } -file.exists("../CMakeLists.txt") && - run_cmake("--version") && - run_cmake( - sprintf("%s -DNANOARROW_BUNDLE=ON -DNANOARROW_NAMESPACE=RPkg -DNANOARROW_IPC=ON", - source_dir), - wd = build_dir - ) && - run_cmake( - sprintf("--install %s --prefix=%s", shQuote(build_dir), shQuote(dist_dir)) - ) && - run_cmake( - sprintf("--install %s --prefix=%s", shQuote(ipc_build_dir), shQuote(dist_dir)) - ) - -# If any of the above failed, we can also copy from ../dist. This is likely for -# for installs via pak or remotes that run pkgbuild::build() -if (!file.exists(file.path(dist_dir, "nanoarrow.h"))) { - dist_dir <- "../dist" -} - -files_to_vendor <- file.path( - dist_dir, - c("nanoarrow.c", "nanoarrow.h", - "nanoarrow_ipc.c", "nanoarrow_ipc.h", - "flatcc.c", "flatcc") -) - -if (all(file.exists(files_to_vendor))) { - files_dst <- file.path("src", basename(files_to_vendor)) +cat("Vendoring files from arrow-nanoarrow to src/:\n") +stopifnot(file.exists("../CMakeLists.txt") && run_bundler()) - # Clean previous files/dirs - for (f in files_dst) { - unlink(f, recursive = TRUE) - } +# Post-process headers for CMD check +f <- "src/flatcc/portable/pdiagnostic.h" +lines <- readLines(f) +writeLines(gsub("^#pragma", "/**/#pragma", lines), f) - cat("Vendoring files from arrow-nanoarrow to src/:\n") - - for (f in files_to_vendor) { - cat(sprintf("- %s\n", basename(f))) - if (!file.copy(f, "src", recursive = TRUE)) { - stop(sprintf("Failed to copy '%s' to src/", basename(f))) - } - } - - # Post-process headers for CMD check - f <- "src/flatcc/portable/pdiagnostic.h" - lines <- readLines(f) - writeLines(gsub("^#pragma", "/**/#pragma", lines), f) -} +# Remove unused files +unused_files <- list.files("src", "\\.hpp$", full.names = TRUE) +unlink(unused_files) diff --git a/src/nanoarrow/array.c b/src/nanoarrow/array.c index ef68350cc..63d315ed5 100644 --- a/src/nanoarrow/array.c +++ b/src/nanoarrow/array.c @@ -20,7 +20,7 @@ #include #include -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" static void ArrowArrayReleaseInternal(struct ArrowArray* array) { // Release buffers held by this array diff --git a/src/nanoarrow/array_stream.c b/src/nanoarrow/array_stream.c index b7eeaac85..28717b649 100644 --- a/src/nanoarrow/array_stream.c +++ b/src/nanoarrow/array_stream.c @@ -17,7 +17,7 @@ #include -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" struct BasicArrayStreamPrivate { struct ArrowSchema schema; diff --git a/src/nanoarrow/nanoarrow.hpp b/src/nanoarrow/nanoarrow.hpp index 5f8aabbac..a5d44f9af 100644 --- a/src/nanoarrow/nanoarrow.hpp +++ b/src/nanoarrow/nanoarrow.hpp @@ -19,7 +19,7 @@ #include #include -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" #ifndef NANOARROW_HPP_INCLUDED #define NANOARROW_HPP_INCLUDED diff --git a/src/nanoarrow/nanoarrow_device.c b/src/nanoarrow/nanoarrow_device.c index 92acd69d5..a2ce46655 100644 --- a/src/nanoarrow/nanoarrow_device.c +++ b/src/nanoarrow/nanoarrow_device.c @@ -18,9 +18,8 @@ #include #include -#include "nanoarrow.h" - -#include "nanoarrow_device.h" +#include "nanoarrow/nanoarrow.h" +#include "nanoarrow/nanoarrow_device.h" ArrowErrorCode ArrowDeviceCheckRuntime(struct ArrowError* error) { const char* nanoarrow_runtime_version = ArrowNanoarrowVersion(); diff --git a/src/nanoarrow/nanoarrow_device.h b/src/nanoarrow/nanoarrow_device.h index 47af82bda..339a88757 100644 --- a/src/nanoarrow/nanoarrow_device.h +++ b/src/nanoarrow/nanoarrow_device.h @@ -18,7 +18,7 @@ #ifndef NANOARROW_DEVICE_H_INCLUDED #define NANOARROW_DEVICE_H_INCLUDED -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" #ifdef __cplusplus extern "C" { diff --git a/src/nanoarrow/nanoarrow_device.hpp b/src/nanoarrow/nanoarrow_device.hpp index 550edceff..ebc29347f 100644 --- a/src/nanoarrow/nanoarrow_device.hpp +++ b/src/nanoarrow/nanoarrow_device.hpp @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -#include "nanoarrow_device.h" +#include "nanoarrow/nanoarrow_device.h" #ifndef NANOARROW_DEVICE_HPP_INCLUDED #define NANOARROW_DEVICE_HPP_INCLUDED diff --git a/src/nanoarrow/nanoarrow_device_cuda.c b/src/nanoarrow/nanoarrow_device_cuda.c index f2fbafd40..a39dfa1bb 100644 --- a/src/nanoarrow/nanoarrow_device_cuda.c +++ b/src/nanoarrow/nanoarrow_device_cuda.c @@ -19,7 +19,7 @@ #include -#include "nanoarrow_device.h" +#include "nanoarrow/nanoarrow_device.h" static inline void ArrowDeviceCudaSetError(CUresult err, const char* op, struct ArrowError* error) { diff --git a/src/nanoarrow/nanoarrow_device_cuda.h b/src/nanoarrow/nanoarrow_device_cuda.h index b05a64da8..055073e1f 100644 --- a/src/nanoarrow/nanoarrow_device_cuda.h +++ b/src/nanoarrow/nanoarrow_device_cuda.h @@ -18,7 +18,7 @@ #ifndef NANOARROW_DEVICE_CUDA_H_INCLUDED #define NANOARROW_DEVICE_CUDA_H_INCLUDED -#include "nanoarrow_device.h" +#include "nanoarrow/nanoarrow_device.h" #ifdef NANOARROW_NAMESPACE diff --git a/src/nanoarrow/nanoarrow_device_cuda_test.cc b/src/nanoarrow/nanoarrow_device_cuda_test.cc index 8d5e8f4b8..d3aad566e 100644 --- a/src/nanoarrow/nanoarrow_device_cuda_test.cc +++ b/src/nanoarrow/nanoarrow_device_cuda_test.cc @@ -20,8 +20,8 @@ #include #include -#include "nanoarrow_device.h" -#include "nanoarrow_device_cuda.h" +#include "nanoarrow/nanoarrow_device.h" +#include "nanoarrow/nanoarrow_device_cuda.h" class CudaTemporaryContext { public: diff --git a/src/nanoarrow/nanoarrow_device_hpp_test.cc b/src/nanoarrow/nanoarrow_device_hpp_test.cc index fc3a555cf..1b4c8d8e9 100644 --- a/src/nanoarrow/nanoarrow_device_hpp_test.cc +++ b/src/nanoarrow/nanoarrow_device_hpp_test.cc @@ -17,7 +17,7 @@ #include -#include "nanoarrow_device.hpp" +#include "nanoarrow/nanoarrow_device.hpp" TEST(NanoarrowDeviceHpp, UniqueDeviceArray) { nanoarrow::device::UniqueDeviceArray array; diff --git a/src/nanoarrow/nanoarrow_device_metal.cc b/src/nanoarrow/nanoarrow_device_metal.cc index 0db18f2c0..b0d31f1b0 100644 --- a/src/nanoarrow/nanoarrow_device_metal.cc +++ b/src/nanoarrow/nanoarrow_device_metal.cc @@ -24,9 +24,8 @@ #define MTL_PRIVATE_IMPLEMENTATION #include -#include "nanoarrow_device.hpp" - -#include "nanoarrow_device_metal.h" +#include "nanoarrow/nanoarrow_device.hpp" +#include "nanoarrow/nanoarrow_device_metal.h" // If non-null, caller must ->release() the return value. This doesn't // release the underlying memory (which must be managed separately). diff --git a/src/nanoarrow/nanoarrow_device_metal.h b/src/nanoarrow/nanoarrow_device_metal.h index 8cb487841..52cda74c1 100644 --- a/src/nanoarrow/nanoarrow_device_metal.h +++ b/src/nanoarrow/nanoarrow_device_metal.h @@ -18,7 +18,7 @@ #ifndef NANOARROW_DEVICE_METAL_H_INCLUDED #define NANOARROW_DEVICE_METAL_H_INCLUDED -#include "nanoarrow_device.h" +#include "nanoarrow/nanoarrow_device.h" #ifdef NANOARROW_NAMESPACE diff --git a/src/nanoarrow/nanoarrow_device_metal_test.cc b/src/nanoarrow/nanoarrow_device_metal_test.cc index 30a5c7f41..0f4cff1b7 100644 --- a/src/nanoarrow/nanoarrow_device_metal_test.cc +++ b/src/nanoarrow/nanoarrow_device_metal_test.cc @@ -21,9 +21,8 @@ #include -#include "nanoarrow_device.hpp" - -#include "nanoarrow_device_metal.h" +#include "nanoarrow/nanoarrow_device.hpp" +#include "nanoarrow/nanoarrow_device_metal.h" TEST(NanoarrowDeviceMetal, DefaultDevice) { nanoarrow::device::UniqueDevice device; diff --git a/src/nanoarrow/nanoarrow_device_test.cc b/src/nanoarrow/nanoarrow_device_test.cc index 8a904559c..ad2ed9c83 100644 --- a/src/nanoarrow/nanoarrow_device_test.cc +++ b/src/nanoarrow/nanoarrow_device_test.cc @@ -19,7 +19,7 @@ #include -#include "nanoarrow_device.h" +#include "nanoarrow/nanoarrow_device.h" TEST(NanoarrowDevice, CheckRuntime) { EXPECT_EQ(ArrowDeviceCheckRuntime(nullptr), NANOARROW_OK); diff --git a/src/nanoarrow/nanoarrow_gtest_util.hpp b/src/nanoarrow/nanoarrow_gtest_util.hpp index 9adbaab1f..16f9b2c9b 100644 --- a/src/nanoarrow/nanoarrow_gtest_util.hpp +++ b/src/nanoarrow/nanoarrow_gtest_util.hpp @@ -18,7 +18,7 @@ #include #include -#include "nanoarrow.hpp" +#include "nanoarrow/nanoarrow.hpp" #ifndef NANOARROW_GTEST_UTIL_HPP_INCLUDED #define NANOARROW_GTEST_UTIL_HPP_INCLUDED diff --git a/src/nanoarrow/nanoarrow_ipc.h b/src/nanoarrow/nanoarrow_ipc.h index 84d0885c6..8819ec1c3 100644 --- a/src/nanoarrow/nanoarrow_ipc.h +++ b/src/nanoarrow/nanoarrow_ipc.h @@ -18,7 +18,7 @@ #ifndef NANOARROW_IPC_H_INCLUDED #define NANOARROW_IPC_H_INCLUDED -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" #ifdef NANOARROW_NAMESPACE diff --git a/src/nanoarrow/nanoarrow_ipc.hpp b/src/nanoarrow/nanoarrow_ipc.hpp index e52fddbcb..2757d28cc 100644 --- a/src/nanoarrow/nanoarrow_ipc.hpp +++ b/src/nanoarrow/nanoarrow_ipc.hpp @@ -18,8 +18,8 @@ #ifndef NANOARROW_IPC_HPP_INCLUDED #define NANOARROW_IPC_HPP_INCLUDED -#include "nanoarrow.hpp" -#include "nanoarrow_ipc.h" +#include "nanoarrow/nanoarrow.hpp" +#include "nanoarrow/nanoarrow_ipc.h" namespace nanoarrow { diff --git a/src/nanoarrow/nanoarrow_ipc_decoder.c b/src/nanoarrow/nanoarrow_ipc_decoder.c index d52166144..6048b0f1b 100644 --- a/src/nanoarrow/nanoarrow_ipc_decoder.c +++ b/src/nanoarrow/nanoarrow_ipc_decoder.c @@ -43,9 +43,9 @@ #endif -#include "nanoarrow.h" -#include "nanoarrow_ipc.h" -#include "nanoarrow_ipc_flatcc_generated.h" +#include "nanoarrow/nanoarrow.h" +#include "nanoarrow/nanoarrow_ipc.h" +#include "nanoarrow/nanoarrow_ipc_flatcc_generated.h" // R 3.6 / Windows builds on a very old toolchain that does not define ENODATA #if defined(_WIN32) && !defined(_MSC_VER) && !defined(ENODATA) diff --git a/src/nanoarrow/nanoarrow_ipc_reader.c b/src/nanoarrow/nanoarrow_ipc_reader.c index 593c3c60c..5415306d2 100644 --- a/src/nanoarrow/nanoarrow_ipc_reader.c +++ b/src/nanoarrow/nanoarrow_ipc_reader.c @@ -20,8 +20,8 @@ #include #include -#include "nanoarrow.h" -#include "nanoarrow_ipc.h" +#include "nanoarrow/nanoarrow.h" +#include "nanoarrow/nanoarrow_ipc.h" // R 3.6 / Windows builds on a very old toolchain that does not define ENODATA #if defined(_WIN32) && !defined(_MSC_VER) && !defined(ENODATA) diff --git a/src/nanoarrow/nanoarrow_testing.hpp b/src/nanoarrow/nanoarrow_testing.hpp index 7435c7eee..73f632986 100644 --- a/src/nanoarrow/nanoarrow_testing.hpp +++ b/src/nanoarrow/nanoarrow_testing.hpp @@ -24,7 +24,7 @@ #include -#include "nanoarrow.hpp" +#include "nanoarrow/nanoarrow.hpp" #ifndef NANOARROW_TESTING_HPP_INCLUDED #define NANOARROW_TESTING_HPP_INCLUDED diff --git a/src/nanoarrow/schema.c b/src/nanoarrow/schema.c index 5398dd898..21cdcd95c 100644 --- a/src/nanoarrow/schema.c +++ b/src/nanoarrow/schema.c @@ -21,7 +21,7 @@ #include #include -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" static void ArrowSchemaReleaseInternal(struct ArrowSchema* schema) { if (schema->format != NULL) ArrowFree((void*)schema->format); diff --git a/src/nanoarrow/utils.c b/src/nanoarrow/utils.c index 4aba25ae4..d8923b854 100644 --- a/src/nanoarrow/utils.c +++ b/src/nanoarrow/utils.c @@ -22,7 +22,7 @@ #include #include -#include "nanoarrow.h" +#include "nanoarrow/nanoarrow.h" const char* ArrowNanoarrowVersion(void) { return NANOARROW_VERSION; }