Skip to content

Commit c133f76

Browse files
committed
fix: build unit tests with shared library
1 parent da91626 commit c133f76

27 files changed

+275
-119
lines changed

CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,25 @@ option(ICEBERG_BUILD_REST_INTEGRATION_TESTS "Build rest catalog integration test
4646
option(ICEBERG_ENABLE_ASAN "Enable Address Sanitizer" OFF)
4747
option(ICEBERG_ENABLE_UBSAN "Enable Undefined Behavior Sanitizer" OFF)
4848

49+
if(ICEBERG_BUILD_SHARED)
50+
set(ICEBERG_TEST_LINKAGE_DEFAULT "shared")
51+
else()
52+
set(ICEBERG_TEST_LINKAGE_DEFAULT "static")
53+
endif()
54+
set(ICEBERG_TEST_LINKAGE
55+
${ICEBERG_TEST_LINKAGE_DEFAULT}
56+
CACHE STRING "Linkage of Iceberg libraries with unit tests executables")
57+
if(ICEBERG_BUILD_TESTS)
58+
if(ICEBERG_TEST_LINKAGE STREQUAL "shared" AND NOT ICEBERG_BUILD_SHARED)
59+
message(FATAL_ERROR "If using ICEBERG_TEST_LINKAGE=shared, must also pass ICEBERG_BUILD_SHARED=ON"
60+
)
61+
endif()
62+
if(ICEBERG_TEST_LINKAGE STREQUAL "static" AND NOT ICEBERG_BUILD_STATIC)
63+
message(FATAL_ERROR "If using ICEBERG_TEST_LINKAGE=static, must also pass ICEBERG_BUILD_STATIC=ON"
64+
)
65+
endif()
66+
endif()
67+
4968
include(GNUInstallDirs)
5069
include(FetchContent)
5170

cmake_modules/IcebergThirdpartyToolchain.cmake

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ endmacro()
8383
function(resolve_arrow_dependency)
8484
prepare_fetchcontent()
8585

86-
set(ARROW_BUILD_SHARED OFF)
86+
set(ARROW_BUILD_SHARED ${ICEBERG_BUILD_SHARED})
8787
set(ARROW_BUILD_STATIC ON)
8888
# Work around undefined symbol: arrow::ipc::ReadSchema(arrow::io::InputStream*, arrow::ipc::DictionaryMemo*)
8989
set(ARROW_IPC ON)
@@ -150,6 +150,28 @@ function(resolve_arrow_dependency)
150150
install(FILES ${arrow_bundled_dependencies_location}
151151
DESTINATION ${ICEBERG_INSTALL_LIBDIR})
152152
endif()
153+
154+
if(ARROW_BUILD_SHARED)
155+
if(NOT TARGET Arrow::arrow_shared)
156+
add_library(Arrow::arrow_shared INTERFACE IMPORTED)
157+
target_link_libraries(Arrow::arrow_shared INTERFACE arrow_shared)
158+
target_include_directories(Arrow::arrow_shared
159+
INTERFACE ${vendoredarrow_BINARY_DIR}/src
160+
${vendoredarrow_SOURCE_DIR}/cpp/src)
161+
endif()
162+
163+
if(NOT TARGET Parquet::parquet_shared)
164+
add_library(Parquet::parquet_shared INTERFACE IMPORTED)
165+
target_link_libraries(Parquet::parquet_shared INTERFACE parquet_shared)
166+
target_include_directories(Parquet::parquet_shared
167+
INTERFACE ${vendoredarrow_BINARY_DIR}/src
168+
${vendoredarrow_SOURCE_DIR}/cpp/src)
169+
endif()
170+
171+
set_target_properties(arrow_shared PROPERTIES OUTPUT_NAME "iceberg_vendored_arrow")
172+
set_target_properties(parquet_shared PROPERTIES OUTPUT_NAME
173+
"iceberg_vendored_parquet")
174+
endif()
153175
else()
154176
set(ARROW_VENDORED FALSE)
155177
list(APPEND ICEBERG_SYSTEM_DEPENDENCIES Arrow)

src/iceberg/CMakeLists.txt

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -91,35 +91,31 @@ set(ICEBERG_SOURCES
9191

9292
set(ICEBERG_STATIC_BUILD_INTERFACE_LIBS)
9393
set(ICEBERG_SHARED_BUILD_INTERFACE_LIBS)
94+
set(ICEBERG_SHARED_PRIVATE_BUILD_INTERFACE_LIBS)
9495
set(ICEBERG_STATIC_INSTALL_INTERFACE_LIBS)
9596
set(ICEBERG_SHARED_INSTALL_INTERFACE_LIBS)
9697

9798
list(APPEND
9899
ICEBERG_STATIC_BUILD_INTERFACE_LIBS
99-
nanoarrow::nanoarrow_static
100+
nanoarrow::nanoarrow
100101
nlohmann_json::nlohmann_json
101102
roaring::roaring
102103
spdlog::spdlog
103104
ZLIB::ZLIB)
104105
list(APPEND
105-
ICEBERG_SHARED_BUILD_INTERFACE_LIBS
106-
nanoarrow::nanoarrow_shared
106+
ICEBERG_SHARED_PRIVATE_BUILD_INTERFACE_LIBS
107+
nanoarrow::nanoarrow
107108
nlohmann_json::nlohmann_json
108109
roaring::roaring
109110
spdlog::spdlog
110111
ZLIB::ZLIB)
111112
list(APPEND
112113
ICEBERG_STATIC_INSTALL_INTERFACE_LIBS
113-
"$<IF:$<BOOL:${NANOARROW_VENDORED}>,iceberg::nanoarrow_static,$<IF:$<TARGET_EXISTS:nanoarrow::nanoarrow_static>,nanoarrow::nanoarrow_static,nanoarrow::nanoarrow_shared>>"
114-
"$<IF:$<BOOL:${NLOHMANN_JSON_VENDORED}>,iceberg::nlohmann_json,$<IF:$<TARGET_EXISTS:nlohmann_json::nlohmann_json>,nlohmann_json::nlohmann_json,nlohmann_json::nlohmann_json>>"
114+
"$<IF:$<BOOL:${NANOARROW_VENDORED}>,iceberg::nanoarrow_static,nanoarrow::nanoarrow>"
115+
"$<IF:$<BOOL:${NLOHMANN_JSON_VENDORED}>,iceberg::nlohmann_json,nlohmann_json::nlohmann_json>"
115116
"$<IF:$<BOOL:${CROARING_VENDORED}>,iceberg::roaring,roaring::roaring>"
116-
"$<IF:$<BOOL:${SPDLOG_VENDORED}>,iceberg::spdlog,spdlog::spdlog>")
117-
list(APPEND
118-
ICEBERG_SHARED_INSTALL_INTERFACE_LIBS
119-
"$<IF:$<BOOL:${NANOARROW_VENDORED}>,iceberg::nanoarrow_shared,$<IF:$<TARGET_EXISTS:nanoarrow::nanoarrow_shared>,nanoarrow::nanoarrow_shared,nanoarrow::nanoarrow_static>>"
120-
"$<IF:$<BOOL:${NLOHMANN_JSON_VENDORED}>,iceberg::nlohmann_json,$<IF:$<TARGET_EXISTS:nlohmann_json::nlohmann_json>,nlohmann_json::nlohmann_json,nlohmann_json::nlohmann_json>>"
121-
"$<IF:$<BOOL:${CROARING_VENDORED}>,iceberg::roaring,roaring::roaring>"
122-
"$<IF:$<BOOL:${SPDLOG_VENDORED}>,iceberg::spdlog,spdlog::spdlog>")
117+
"$<IF:$<BOOL:${SPDLOG_VENDORED}>,iceberg::spdlog,spdlog::spdlog>"
118+
ZLIB::ZLIB)
123119

124120
add_iceberg_lib(iceberg
125121
SOURCES
@@ -128,6 +124,8 @@ add_iceberg_lib(iceberg
128124
${ICEBERG_INCLUDES}
129125
SHARED_LINK_LIBS
130126
${ICEBERG_SHARED_BUILD_INTERFACE_LIBS}
127+
SHARED_PRIVATE_LINK_LIBS
128+
${ICEBERG_SHARED_PRIVATE_BUILD_INTERFACE_LIBS}
131129
STATIC_LINK_LIBS
132130
${ICEBERG_STATIC_BUILD_INTERFACE_LIBS}
133131
STATIC_INSTALL_INTERFACE_LIBS
@@ -165,44 +163,38 @@ if(ICEBERG_BUILD_BUNDLE)
165163
# Libraries to link with exported libiceberg_bundle.{so,a}.
166164
set(ICEBERG_BUNDLE_STATIC_BUILD_INTERFACE_LIBS)
167165
set(ICEBERG_BUNDLE_SHARED_BUILD_INTERFACE_LIBS)
166+
set(ICEBERG_BUNDLE_SHARED_PRIVATE_BUILD_INTERFACE_LIBS)
168167
set(ICEBERG_BUNDLE_STATIC_INSTALL_INTERFACE_LIBS)
169168
set(ICEBERG_BUNDLE_SHARED_INSTALL_INTERFACE_LIBS)
170169

171170
list(APPEND
172171
ICEBERG_BUNDLE_STATIC_BUILD_INTERFACE_LIBS
173-
"$<IF:$<TARGET_EXISTS:iceberg_static>,iceberg_static,iceberg_shared>"
174-
"$<IF:$<TARGET_EXISTS:Arrow::arrow_static>,Arrow::arrow_static,Arrow::arrow_shared>"
175-
"$<IF:$<TARGET_EXISTS:Parquet::parquet_static>,Parquet::parquet_static,Parquet::parquet_shared>"
176-
"$<IF:$<TARGET_EXISTS:avro-cpp::avrocpp_static>,avro-cpp::avrocpp_static,avro-cpp::avrocpp_shared>"
177-
)
172+
iceberg_static
173+
Arrow::arrow_static
174+
Parquet::parquet_static
175+
avro-cpp::avrocpp_static)
178176
list(APPEND
179177
ICEBERG_BUNDLE_SHARED_BUILD_INTERFACE_LIBS
180-
"$<IF:$<TARGET_EXISTS:iceberg_shared>,iceberg_shared,iceberg_static>"
181-
"$<IF:$<TARGET_EXISTS:Arrow::arrow_shared>,Arrow::arrow_shared,Arrow::arrow_static>"
182-
"$<IF:$<TARGET_EXISTS:Parquet::parquet_shared>,Parquet::parquet_shared,Parquet::parquet_static>"
183-
"$<IF:$<TARGET_EXISTS:avro-cpp::avrocpp_shared>,avro-cpp::avrocpp_shared,avro-cpp::avrocpp_static>"
184-
)
185-
178+
iceberg_shared
179+
Arrow::arrow_shared
180+
Parquet::parquet_shared)
181+
list(APPEND ICEBERG_BUNDLE_SHARED_PRIVATE_BUILD_INTERFACE_LIBS nanoarrow::nanoarrow
182+
avro-cpp::avrocpp_static)
186183
list(APPEND
187184
ICEBERG_BUNDLE_STATIC_INSTALL_INTERFACE_LIBS
188-
"$<IF:$<TARGET_EXISTS:iceberg::iceberg_static>,iceberg::iceberg_static,iceberg::iceberg_shared>"
189-
"$<IF:$<BOOL:${ARROW_VENDORED}>,iceberg::arrow_static,$<IF:$<TARGET_EXISTS:Arrow::arrow_static>,Arrow::arrow_static,Arrow::arrow_shared>>"
190-
"$<IF:$<BOOL:${ARROW_VENDORED}>,iceberg::parquet_static,$<IF:$<TARGET_EXISTS:Parquet::parquet_static>,Parquet::parquet_static,Parquet::parquet_shared>>"
191-
"$<IF:$<BOOL:${AVRO_VENDORED}>,iceberg::avrocpp_s,$<IF:$<TARGET_EXISTS:avro-cpp::avrocpp_static>,avro-cpp::avrocpp_static,avro-cpp::avrocpp_shared>>"
192-
)
193-
list(APPEND
194-
ICEBERG_BUNDLE_SHARED_INSTALL_INTERFACE_LIBS
195-
"$<IF:$<TARGET_EXISTS:iceberg::iceberg_shared>,iceberg::iceberg_shared,iceberg::iceberg_static>"
196-
"$<IF:$<BOOL:${ARROW_VENDORED}>,iceberg::arrow_static,$<IF:$<TARGET_EXISTS:Arrow::arrow_shared>,Arrow::arrow_shared,Arrow::arrow_static>>"
197-
"$<IF:$<BOOL:${ARROW_VENDORED}>,iceberg::parquet_static,$<IF:$<TARGET_EXISTS:Parquet::parquet_shared>,Parquet::parquet_shared,Parquet::parquet_static>>"
198-
"$<IF:$<BOOL:${AVRO_VENDORED}>,iceberg::avrocpp_s,$<IF:$<TARGET_EXISTS:avro-cpp::avrocpp_shared>,avro-cpp::avrocpp_shared,avro-cpp::avrocpp_static>>"
199-
)
185+
iceberg::iceberg_static
186+
"$<IF:$<BOOL:${ARROW_VENDORED}>,iceberg::arrow_shared,Arrow::arrow_shared>"
187+
"$<IF:$<BOOL:${ARROW_VENDORED}>,iceberg::parquet_shared,Parquet::parquet_shared>"
188+
"$<IF:$<BOOL:${AVRO_VENDORED}>,iceberg::avrocpp_s,avro-cpp::avrocpp_static>")
189+
list(APPEND ICEBERG_BUNDLE_SHARED_INSTALL_INTERFACE_LIBS iceberg::iceberg_shared)
200190

201191
add_iceberg_lib(iceberg_bundle
202192
SOURCES
203193
${ICEBERG_BUNDLE_SOURCES}
204194
SHARED_LINK_LIBS
205195
${ICEBERG_BUNDLE_SHARED_BUILD_INTERFACE_LIBS}
196+
SHARED_PRIVATE_LINK_LIBS
197+
${ICEBERG_BUNDLE_SHARED_PRIVATE_BUILD_INTERFACE_LIBS}
206198
STATIC_LINK_LIBS
207199
${ICEBERG_BUNDLE_STATIC_BUILD_INTERFACE_LIBS}
208200
STATIC_INSTALL_INTERFACE_LIBS

src/iceberg/arrow_c_data_guard_internal.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "iceberg/arrow_c_data_guard_internal.h"
2121

22+
#include <nanoarrow/nanoarrow.h>
23+
2224
namespace iceberg::internal {
2325

2426
ArrowArrayGuard::~ArrowArrayGuard() {

src/iceberg/arrow_c_data_guard_internal.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,16 @@
1919

2020
#pragma once
2121

22-
#include <nanoarrow/nanoarrow.h>
22+
#include "iceberg/iceberg_export.h"
2323

24-
#include "iceberg/arrow_c_data.h"
24+
struct ArrowArray;
25+
struct ArrowArrayView;
26+
struct ArrowBuffer;
27+
struct ArrowSchema;
2528

2629
namespace iceberg::internal {
2730

28-
class ArrowArrayGuard {
31+
class ICEBERG_EXPORT ArrowArrayGuard {
2932
public:
3033
explicit ArrowArrayGuard(ArrowArray* array) : array_(array) {}
3134
~ArrowArrayGuard();
@@ -34,7 +37,7 @@ class ArrowArrayGuard {
3437
ArrowArray* array_;
3538
};
3639

37-
class ArrowSchemaGuard {
40+
class ICEBERG_EXPORT ArrowSchemaGuard {
3841
public:
3942
explicit ArrowSchemaGuard(ArrowSchema* schema) : schema_(schema) {}
4043
~ArrowSchemaGuard();
@@ -43,7 +46,7 @@ class ArrowSchemaGuard {
4346
ArrowSchema* schema_;
4447
};
4548

46-
class ArrowArrayViewGuard {
49+
class ICEBERG_EXPORT ArrowArrayViewGuard {
4750
public:
4851
explicit ArrowArrayViewGuard(ArrowArrayView* view) : view_(view) {}
4952
~ArrowArrayViewGuard();
@@ -52,7 +55,7 @@ class ArrowArrayViewGuard {
5255
ArrowArrayView* view_;
5356
};
5457

55-
class ArrowArrayBufferGuard {
58+
class ICEBERG_EXPORT ArrowArrayBufferGuard {
5659
public:
5760
explicit ArrowArrayBufferGuard(ArrowBuffer* buffer) : buffer_(buffer) {}
5861
~ArrowArrayBufferGuard();

src/iceberg/avro/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ iceberg_install_all_headers(iceberg/avro)
1919

2020
# avro_scan benchmark executable
2121
add_executable(avro_scan avro_scan.cc)
22-
target_link_libraries(avro_scan PRIVATE iceberg_bundle_static)
22+
23+
if(ICEBERG_BUILD_SHARED)
24+
target_link_libraries(avro_scan PRIVATE iceberg_bundle_shared Arrow::arrow_static)
25+
else()
26+
target_link_libraries(avro_scan PRIVATE iceberg_bundle_static Arrow::arrow_static)
27+
endif()
28+
2329
set_target_properties(avro_scan PROPERTIES RUNTIME_OUTPUT_DIRECTORY
2430
"${CMAKE_BINARY_DIR}/src/iceberg/avro")

src/iceberg/avro/avro_data_util_internal.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919

2020
#pragma once
2121

22-
#include <arrow/array/builder_base.h>
23-
#include <avro/GenericDatum.hh>
22+
#include <arrow/type_fwd.h>
2423

24+
#include "iceberg/iceberg_bundle_export.h"
2525
#include "iceberg/schema_util.h"
2626

27+
namespace avro {
28+
class Node;
29+
class GenericDatum;
30+
using NodePtr = std::shared_ptr<Node>;
31+
} // namespace avro
32+
2733
namespace iceberg::avro {
2834

2935
/// \brief Append an Avro datum to an Arrow array builder.
@@ -37,19 +43,20 @@ namespace iceberg::avro {
3743
/// \param projected_schema The projected schema
3844
/// \param array_builder The Arrow array builder to append to (must be a struct builder)
3945
/// \return Status indicating success or failure
40-
Status AppendDatumToBuilder(const ::avro::NodePtr& avro_node,
41-
const ::avro::GenericDatum& avro_datum,
42-
const SchemaProjection& projection,
43-
const Schema& projected_schema,
44-
::arrow::ArrayBuilder* array_builder);
46+
ICEBERG_BUNDLE_EXPORT Status AppendDatumToBuilder(const ::avro::NodePtr& avro_node,
47+
const ::avro::GenericDatum& avro_datum,
48+
const SchemaProjection& projection,
49+
const Schema& projected_schema,
50+
::arrow::ArrayBuilder* array_builder);
4551

4652
/// \brief Extract an Avro datum from an Arrow array.
4753
///
4854
/// \param array The Arrow array to extract from.
4955
/// \param index The index of the element to extract.
5056
/// \param datum The Avro datum to extract to. Its Avro type should be consistent with the
5157
/// Arrow type.
52-
Status ExtractDatumFromArray(const ::arrow::Array& array, int64_t index,
53-
::avro::GenericDatum* datum);
58+
ICEBERG_BUNDLE_EXPORT Status ExtractDatumFromArray(const ::arrow::Array& array,
59+
int64_t index,
60+
::avro::GenericDatum* datum);
5461

5562
} // namespace iceberg::avro

src/iceberg/avro/avro_schema_util_internal.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <avro/Node.hh>
2525

26+
#include "iceberg/iceberg_bundle_export.h"
2627
#include "iceberg/name_mapping.h"
2728
#include "iceberg/result.h"
2829
#include "iceberg/schema_util.h"
@@ -40,7 +41,7 @@ struct MapLogicalType : public ::avro::CustomLogicalType {
4041
};
4142

4243
/// \brief A visitor that converts an Iceberg type to an Avro node.
43-
class ToAvroNodeVisitor {
44+
class ICEBERG_BUNDLE_EXPORT ToAvroNodeVisitor {
4445
public:
4546
Status Visit(const BooleanType& type, ::avro::NodePtr* node);
4647
Status Visit(const IntType& type, ::avro::NodePtr* node);
@@ -67,7 +68,7 @@ class ToAvroNodeVisitor {
6768
};
6869

6970
/// \brief A visitor that checks the presence of field IDs in an Avro schema.
70-
class HasIdVisitor {
71+
class ICEBERG_BUNDLE_EXPORT HasIdVisitor {
7172
public:
7273
HasIdVisitor() = default;
7374

@@ -137,8 +138,9 @@ class HasIdVisitor {
137138
/// \param avro_node The Avro node to read data from.
138139
/// \param prune_source Whether the source schema can be pruned.
139140
/// \return The schema projection result.
140-
Result<SchemaProjection> Project(const Schema& expected_schema,
141-
const ::avro::NodePtr& avro_node, bool prune_source);
141+
ICEBERG_BUNDLE_EXPORT Result<SchemaProjection> Project(const Schema& expected_schema,
142+
const ::avro::NodePtr& avro_node,
143+
bool prune_source);
142144

143145
std::string ToString(const ::avro::NodePtr& node);
144146
std::string ToString(const ::avro::LogicalType& logical_type);
@@ -157,14 +159,14 @@ bool HasMapLogicalType(const ::avro::NodePtr& node);
157159
///
158160
/// \param name The name to check.
159161
/// \return True if the name is valid, false otherwise.
160-
bool ValidAvroName(std::string_view name);
162+
ICEBERG_BUNDLE_EXPORT bool ValidAvroName(std::string_view name);
161163

162164
/// \brief Create a new Avro node with field IDs from name mapping.
163165
/// \param original_node The original Avro node to copy.
164166
/// \param mapping The name mapping to apply field IDs from.
165167
/// \return A new Avro node with field IDs applied, or an error.
166-
Result<::avro::NodePtr> MakeAvroNodeWithFieldIds(const ::avro::NodePtr& original_node,
167-
const NameMapping& mapping);
168+
ICEBERG_BUNDLE_EXPORT Result<::avro::NodePtr> MakeAvroNodeWithFieldIds(
169+
const ::avro::NodePtr& original_node, const NameMapping& mapping);
168170

169171
/// \brief Sanitize a field name to make it compatible with Avro field name requirements.
170172
///
@@ -187,6 +189,6 @@ Result<::avro::NodePtr> MakeAvroNodeWithFieldIds(const ::avro::NodePtr& original
187189
///
188190
/// \param field_name The original field name to sanitize.
189191
/// \return A sanitized field name that follows Avro naming conventions.
190-
std::string SanitizeFieldName(std::string_view field_name);
192+
ICEBERG_BUNDLE_EXPORT std::string SanitizeFieldName(std::string_view field_name);
191193

192194
} // namespace iceberg::avro

0 commit comments

Comments
 (0)