This is an automated email from the ASF dual-hosted git repository.
yaooqinn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gluten.git
The following commit(s) were added to refs/heads/main by this push:
new 55eb0d348f [Velox] Fix Iceberg writer aggregate-init build failure on
macOS C++20 libc++ (#12115)
55eb0d348f is described below
commit 55eb0d348ff1b5880e7162048cfebba35db03df5
Author: jackylee <[email protected]>
AuthorDate: Fri May 29 00:32:09 2026 +0800
[Velox] Fix Iceberg writer aggregate-init build failure on macOS C++20
libc++ (#12115)
Two call sites in cpp/velox/compute/iceberg/IcebergWriter.cc construct
aggregate types via paren-init with multiple arguments:
fields.emplace_back(name, type, transform, parameter); // line 311
return WriteStats(numWrittenBytes, // line 262
numWrittenFiles, writeIOTimeNs,
writeWallNs);
Both target types are pure aggregate structs without a user-defined
constructor:
// Velox: velox/connectors/hive/iceberg/PartitionSpec.h
struct IcebergPartitionSpec::Field {
std::string name;
TypePtr type;
TransformType transformType;
std::optional<int32_t> parameter;
};
// Gluten: cpp/velox/compute/iceberg/IcebergWriter.h
struct WriteStats {
uint64_t numWrittenBytes{0};
uint32_t numWrittenFiles{0};
uint64_t writeIOTimeNs{0};
uint64_t writeWallNs{0};
...
};
C++20 P0960R3 made aggregates initializable via paren-init at the
language level, but the standard library implementation of
std::construct_at (which std::vector::emplace_back routes through to do
in-place construction) is uneven across stdlibs:
- libstdc++ (Linux GCC): construct_at accepts aggregate paren-init,
so emplace_back(a, b, c, d) compiles for aggregate types.
- libc++ (Apple Clang 17, macOS): construct_at still requires a real
constructor, so the substitution fails:
error: no matching function for call to 'construct_at'
note: candidate template ignored: substitution failure
[with _Tp = IcebergPartitionSpec::Field, _Args = ...]:
no matching constructor for initialization of
'IcebergPartitionSpec::Field'
Result: builds with --enable_enhanced_features=ON on macOS abort
hard at IcebergWriter.cc.cpp.o (~156/217) before producing
libgluten.dylib, blocking any macOS user from running the Iceberg
writer integration that this gate adds.
The fix is a minimal style change at the two call sites — switch
from paren-init to brace-init, which is aggregate initialization on
every C++17/20 toolchain (libstdc++, libc++, MSVC):
fields.push_back({name, type, transform, parameter});
return WriteStats{numWrittenBytes, numWrittenFiles, ...};
Linux libstdc++ continues to compile cleanly: brace-init resolves to
the same aggregate initialization the paren-init form selected via
P0960. Zero runtime change, identical field-by-field initialization.
Verification:
- macOS 14 arm64 + Apple Clang 17 + --enable_enhanced_features=ON:
cpp build now reaches 217/217 (was 156/217 before this fix).
- cpp ctest matrix on the same configuration: 5539 / 5539 pass,
including the enhanced-only velox_iceberg_test executable.
- Linux x86_64 build remains green; brace-init for aggregates is
unchanged in libstdc++.
Co-authored-by: Kent Yao <[email protected]>
---
cpp/velox/compute/iceberg/IcebergWriter.cc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/cpp/velox/compute/iceberg/IcebergWriter.cc
b/cpp/velox/compute/iceberg/IcebergWriter.cc
index 576524d499..e248fe4d27 100644
--- a/cpp/velox/compute/iceberg/IcebergWriter.cc
+++ b/cpp/velox/compute/iceberg/IcebergWriter.cc
@@ -259,11 +259,11 @@ WriteStats IcebergWriter::writeStats() const {
const auto currentTimeNs = getCurrentTimeNano();
VELOX_CHECK_GE(currentTimeNs, createTimeNs_);
const auto sinkStats = dataSink_->stats();
- return WriteStats(
+ return WriteStats{
sinkStats.numWrittenBytes,
sinkStats.numWrittenFiles,
sinkStats.writeIOTimeUs * 1000,
- currentTimeNs - createTimeNs_);
+ currentTimeNs - createTimeNs_};
}
std::shared_ptr<const iceberg::IcebergPartitionSpec>
@@ -308,7 +308,7 @@ parseIcebergPartitionSpec(const uint8_t* data, const
int32_t length, RowTypePtr
parameter = protoField.parameter();
}
- fields.emplace_back(protoField.name(),
rowType->findChild(protoField.name()), transform, parameter);
+ fields.push_back({protoField.name(),
rowType->findChild(protoField.name()), transform, parameter});
}
return std::make_shared<iceberg::IcebergPartitionSpec>(protoSpec.spec_id(),
fields);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]