Skip to content

Commit 48168e0

Browse files
authored
fix: Ensure CMake linking against built/installed nanoarrow works for all components (#614)
Closes #407.
1 parent 1c43700 commit 48168e0

File tree

5 files changed

+106
-35
lines changed

5 files changed

+106
-35
lines changed

CMakeLists.txt

+22-9
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ endif()
148148

149149
# Add the nanoarrow library target
150150
add_library(nanoarrow ${NANOARROW_BUILD_SOURCES})
151-
add_library(nanoarrow::nanoarrow ALIAS nanoarrow)
152151

153152
target_include_directories(nanoarrow
154153
PUBLIC $<BUILD_INTERFACE:${NANOARROW_BUILD_INCLUDE_DIR}>
@@ -212,16 +211,18 @@ if(NANOARROW_IPC)
212211
endif()
213212

214213
add_library(nanoarrow_ipc ${NANOARROW_IPC_BUILD_SOURCES})
215-
target_link_libraries(nanoarrow_ipc PRIVATE flatccrt nanoarrow_coverage_config)
214+
target_link_libraries(nanoarrow_ipc
215+
PRIVATE flatccrt
216+
PUBLIC nanoarrow nanoarrow_coverage_config)
216217
target_include_directories(nanoarrow_ipc
217218
PUBLIC $<BUILD_INTERFACE:${NANOARROW_BUILD_INCLUDE_DIR}>
218219
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>
219220
$<BUILD_INTERFACE:${NANOARROW_IPC_FLATCC_INCLUDE_DIR}>
220221
$<INSTALL_INTERFACE:include>)
221222

222223
install(TARGETS nanoarrow_ipc DESTINATION lib)
223-
install(FILES src/nanoarrow/nanoarrow_ipc.h src/nanoarrow/ipc/flatcc_generated.h
224-
DESTINATION include/nanoarrow)
224+
install(FILES src/nanoarrow/nanoarrow_ipc.h src/nanoarrow/nanoarrow_ipc.hpp
225+
src/nanoarrow/ipc/flatcc_generated.h DESTINATION include/nanoarrow)
225226
endif()
226227

227228
if(NANOARROW_IPC AND (NANOARROW_BUILD_INTEGRATION_TESTS OR NANOARROW_BUILD_TESTS))
@@ -308,11 +309,13 @@ if(NANOARROW_DEVICE)
308309
target_compile_definitions(nanoarrow_device PRIVATE ${NANOARROW_DEVICE_DEFS_METAL}
309310
${NANOARROW_DEVICE_DEFS_CUDA})
310311
target_link_libraries(nanoarrow_device
311-
PUBLIC ${NANOARROW_DEVICE_LIBS_CUDA}
312-
${NANOARROW_DEVICE_LIBS_METAL} nanoarrow_coverage_config)
312+
PRIVATE ${NANOARROW_DEVICE_LIBS_CUDA}
313+
${NANOARROW_DEVICE_LIBS_METAL}
314+
PUBLIC nanoarrow nanoarrow_coverage_config)
313315

314316
install(TARGETS nanoarrow_device DESTINATION lib)
315-
install(FILES src/nanoarrow/nanoarrow_device.h DESTINATION include/nanoarrow)
317+
install(FILES src/nanoarrow/nanoarrow_device.h src/nanoarrow/nanoarrow_device.hpp
318+
DESTINATION include/nanoarrow)
316319
endif()
317320

318321
if(NANOARROW_TESTING
@@ -337,9 +340,11 @@ if(NANOARROW_TESTING
337340
PUBLIC $<BUILD_INTERFACE:${NANOARROW_BUILD_INCLUDE_DIR}>
338341
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/src>
339342
$<INSTALL_INTERFACE:include>)
340-
target_link_libraries(nanoarrow_testing PRIVATE nlohmann_json::nlohmann_json nanoarrow)
341-
target_link_libraries(nanoarrow_testing PUBLIC nanoarrow)
343+
target_link_libraries(nanoarrow_testing
344+
PRIVATE nlohmann_json::nlohmann_json
345+
PUBLIC nanoarrow nanoarrow_coverage_config)
342346
set_target_properties(nanoarrow_testing PROPERTIES POSITION_INDEPENDENT_CODE ON)
347+
install(FILES src/nanoarrow/nanoarrow_testing.hpp DESTINATION include/nanoarrow)
343348
endif()
344349

345350
# Always build integration test if building tests
@@ -365,12 +370,19 @@ foreach(target
365370
nanoarrow_c_data_integration
366371
nanoarrow_ipc_json_integration)
367372
if(TARGET ${target})
373+
# Define the nanoarrow::xxx alias target
374+
add_library(nanoarrow::${target} ALIAS ${target})
375+
376+
# Ensure NANOARROW_DEBUG is defined for debug builds
368377
target_compile_definitions(${target} PUBLIC "$<$<CONFIG:Debug>:NANOARROW_DEBUG>")
369378

379+
# Ensure target is added to nanoarrow-exports
370380
install(TARGETS ${target}
371381
DESTINATION lib
372382
EXPORT nanoarrow-exports)
373383

384+
# For debug builds, ensure we aggressively set compiler warning flags and
385+
# error for any compiler warnings
374386
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
375387
target_compile_options(${target}
376388
PRIVATE $<$<CONFIG:Debug>:-Wall
@@ -564,6 +576,7 @@ if(NANOARROW_BUILD_TESTS)
564576
target_link_libraries(nanoarrow_device_cuda_test
565577
nanoarrow_device
566578
nanoarrow
579+
CUDA::cuda_driver
567580
gtest_main
568581
nanoarrow_coverage_config)
569582
gtest_discover_tests(nanoarrow_device_cuda_test)

examples/cmake-scenarios/CMakeLists.txt

+18-8
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,31 @@ option(FIND_NANOARROW "Find an existing nanoarrow" ON)
2929
# link to their own copy of nanoarrow. You may wish to include the namespace only
3030
# on release builds, since the namespace implementation obscures inline help
3131
# available in many text editors.
32-
set(NANOARROW_NAMESPACE "ExampleCmakeMinimal")
32+
set(NANOARROW_NAMESPACE "ExampleCmakeScenarios")
33+
34+
include(FetchContent)
3335

3436
if(FIND_NANOARROW)
3537
# Users should pin to a specific version of nanoarrow if they choose
3638
# to find nanoarrow rather than pinning to a specific version via
3739
# FetchContent.
3840
find_package(nanoarrow REQUIRED)
3941
else()
40-
include(FetchContent)
41-
fetchcontent_declare(nanoarrow_example_cmake_minimal
42-
GIT_REPOSITORY https://github.com/apache/arrow-nanoarrow.git
43-
GIT_TAG main
44-
GIT_SHALLOW TRUE)
45-
fetchcontent_makeavailable(nanoarrow_example_cmake_minimal)
42+
# We need all these components for our test
43+
set(NANOARROW_DEVICE ON)
44+
set(NANOARROW_IPC ON)
45+
set(NANOARROW_TESTING ON)
46+
47+
# Using SOURCE_DIR here such that CI accurately reflects the state of the
48+
# source; however, using GIT_TAG or URL of a pinned version is a more realistic
49+
# user pattern.
50+
fetchcontent_declare(nanoarrow SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../..")
51+
fetchcontent_makeavailable(nanoarrow)
4652
endif()
4753

4854
add_executable(minimal_cpp_app src/app.cpp)
49-
target_link_libraries(minimal_cpp_app nanoarrow::nanoarrow)
55+
target_link_libraries(minimal_cpp_app
56+
nanoarrow::nanoarrow
57+
nanoarrow::nanoarrow_device
58+
nanoarrow::nanoarrow_ipc
59+
nanoarrow::nanoarrow_testing)

examples/cmake-scenarios/build.sh

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020
set -exuo pipefail
2121

2222
# Build nanoarrow statically.
23-
cmake -S ../.. -B scratch/nanoarrow_build_static/ -DCMAKE_INSTALL_PREFIX=scratch/nanoarrow_install_static/
23+
cmake -S ../.. -B scratch/nanoarrow_build_static/ \
24+
-DCMAKE_INSTALL_PREFIX=scratch/nanoarrow_install_static/ \
25+
-DNANOARROW_IPC=ON -DNANOARROW_DEVICE=ON -DNANOARROW_TESTING=ON
2426
cmake --build scratch/nanoarrow_build_static/
2527
cmake --install scratch/nanoarrow_build_static/
2628

2729
# Build nanoarrow dynamically.
28-
cmake -S ../.. -B scratch/nanoarrow_build_shared/ -DCMAKE_INSTALL_PREFIX=scratch/nanoarrow_install_shared/ -DBUILD_SHARED_LIBS=ON
30+
cmake -S ../.. -B scratch/nanoarrow_build_shared/ \
31+
-DCMAKE_INSTALL_PREFIX=scratch/nanoarrow_install_shared/ \
32+
-DBUILD_SHARED_LIBS=ON \
33+
-DNANOARROW_IPC=ON -DNANOARROW_DEVICE=ON -DNANOARROW_TESTING=ON \
34+
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
2935
cmake --build scratch/nanoarrow_build_shared/
3036
cmake --install scratch/nanoarrow_build_shared/
3137

examples/cmake-scenarios/src/app.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,40 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
#include <cstdio>
19+
#include <cstring>
20+
#include <iostream>
21+
22+
// Usually, including either .h or .hpp is fine; however, use this version
23+
// to make sure all the include paths used in all the files will work.
1824
#include "nanoarrow/nanoarrow.h"
1925
#include "nanoarrow/nanoarrow.hpp"
26+
#include "nanoarrow/nanoarrow_device.h"
27+
#include "nanoarrow/nanoarrow_device.hpp"
28+
#include "nanoarrow/nanoarrow_ipc.h"
29+
#include "nanoarrow/nanoarrow_ipc.hpp"
30+
#include "nanoarrow/nanoarrow_testing.hpp"
2031

2132
int main(int argc, char* argv[]) {
33+
// Use something from nanoarrow.hpp / libnanoarrow
2234
nanoarrow::UniqueSchema schema;
2335
NANOARROW_RETURN_NOT_OK(ArrowSchemaInitFromType(schema.get(), NANOARROW_TYPE_INT32));
24-
printf("Schema format for int32 is '%s'", schema->format);
36+
std::printf("Schema format for int32 is '%s'\n", schema->format);
37+
38+
// Use something from nanoarrow_device.hpp / libnanoarrow_device
39+
nanoarrow::device::UniqueDevice device;
40+
ArrowDeviceInitCpu(device.get());
41+
std::printf("Device ID of CPU device is %d\n", static_cast<int>(device->device_id));
42+
43+
// Use something from nanoarrow_ipc.hpp / libnanoarrow_ipc
44+
nanoarrow::ipc::UniqueOutputStream output_stream;
45+
NANOARROW_RETURN_NOT_OK(ArrowIpcOutputStreamInitFile(output_stream.get(), stdout, 0));
46+
std::printf("Address of private data ptr is %p\n", output_stream->private_data);
47+
48+
// Use something from nanoarrow_testing.hpp / libnanoarrow_testing
49+
nanoarrow::testing::TestingJSONWriter json_writer;
50+
NANOARROW_RETURN_NOT_OK(json_writer.WriteField(std::cout, schema.get()));
51+
std::cout << "\n";
52+
2553
return EXIT_SUCCESS;
2654
}

src/nanoarrow/nanoarrow_device.hpp

+29-15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
#include "nanoarrow/nanoarrow.hpp"
1819
#include "nanoarrow/nanoarrow_device.h"
1920

2021
#ifndef NANOARROW_DEVICE_HPP_INCLUDED
@@ -24,63 +25,76 @@ namespace nanoarrow {
2425

2526
namespace internal {
2627

27-
static inline void init_pointer(struct ArrowDeviceArray* data) {
28+
template <>
29+
inline void init_pointer(struct ArrowDeviceArray* data) {
2830
data->array.release = nullptr;
2931
data->sync_event = nullptr;
3032
}
3133

32-
static inline void move_pointer(struct ArrowDeviceArray* src,
33-
struct ArrowDeviceArray* dst) {
34+
template <>
35+
inline void move_pointer(struct ArrowDeviceArray* src, struct ArrowDeviceArray* dst) {
3436
ArrowDeviceArrayMove(src, dst);
3537
}
3638

37-
static inline void release_pointer(struct ArrowDeviceArray* data) {
39+
template <>
40+
inline void release_pointer(struct ArrowDeviceArray* data) {
3841
if (data->array.release != nullptr) {
3942
ArrowArrayRelease(&data->array);
4043
}
4144

4245
data->sync_event = nullptr;
4346
}
4447

45-
static inline void init_pointer(struct ArrowDeviceArrayStream* data) {
48+
template <>
49+
inline void init_pointer(struct ArrowDeviceArrayStream* data) {
4650
data->release = nullptr;
4751
}
4852

49-
static inline void move_pointer(struct ArrowDeviceArrayStream* src,
50-
struct ArrowDeviceArrayStream* dst) {
53+
template <>
54+
inline void move_pointer(struct ArrowDeviceArrayStream* src,
55+
struct ArrowDeviceArrayStream* dst) {
5156
memcpy(dst, src, sizeof(struct ArrowDeviceArrayStream));
5257
src->release = nullptr;
5358
}
5459

55-
static inline void release_pointer(struct ArrowDeviceArrayStream* data) {
60+
template <>
61+
inline void release_pointer(struct ArrowDeviceArrayStream* data) {
5662
if (data->release != nullptr) {
5763
data->release(data);
5864
}
5965
}
6066

61-
static inline void init_pointer(struct ArrowDeviceArrayView* data) {
67+
template <>
68+
inline void init_pointer(struct ArrowDeviceArrayView* data) {
6269
ArrowDeviceArrayViewInit(data);
6370
}
6471

65-
static inline void move_pointer(struct ArrowDeviceArrayView* src,
66-
struct ArrowDeviceArrayView* dst) {
72+
template <>
73+
inline void move_pointer(struct ArrowDeviceArrayView* src,
74+
struct ArrowDeviceArrayView* dst) {
6775
ArrowArrayViewMove(&src->array_view, &dst->array_view);
6876
dst->device = src->device;
6977
src->device = nullptr;
7078
}
7179

72-
static inline void release_pointer(struct ArrowDeviceArrayView* data) {
80+
template <>
81+
inline void release_pointer(struct ArrowDeviceArrayView* data) {
7382
ArrowArrayViewReset(&data->array_view);
7483
}
7584

76-
static inline void init_pointer(struct ArrowDevice* data) { data->release = nullptr; }
85+
template <>
86+
inline void init_pointer(struct ArrowDevice* data) {
87+
data->release = nullptr;
88+
}
7789

78-
static inline void move_pointer(struct ArrowDevice* src, struct ArrowDevice* dst) {
90+
template <>
91+
inline void move_pointer(struct ArrowDevice* src, struct ArrowDevice* dst) {
7992
memcpy(dst, src, sizeof(struct ArrowDevice));
8093
src->release = nullptr;
8194
}
8295

83-
static inline void release_pointer(struct ArrowDevice* data) {
96+
template <>
97+
inline void release_pointer(struct ArrowDevice* data) {
8498
if (data->release != nullptr) {
8599
data->release(data);
86100
}

0 commit comments

Comments
 (0)