This is an automated email from the ASF dual-hosted git repository.
junrushao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new 63224e3f fix(build): resolve type ambiguity and macro redefinition in
unity builds (#512)
63224e3f is described below
commit 63224e3f1e464cc62307223787926a48fc8df8c0
Author: Junru Shao <[email protected]>
AuthorDate: Tue Mar 24 12:31:44 2026 -0700
fix(build): resolve type ambiguity and macro redefinition in unity builds
(#512)
## Summary
- **`src/ffi/object.cc`**: Replace `using namespace tvm::ffi;` with a
namespace alias (`namespace ffi = ::tvm::ffi;`) and fully qualify all
type names in the static init block. This prevents ambiguous type
references (e.g. `Object` matching both `tvm::ffi::Object` and
`tvm::runtime::Object`) in downstream wasm projects that include tvm-ffi
sources in a unity build.
- **`src/ffi/testing/testing.cc`**: Remove the `#define
TVM_FFI_DLL_EXPORT_INCLUDE_METADATA 1` from the source file to avoid
macro redefinition warnings in unity builds where the macro is already
set by the build system.
- **`CMakeLists.txt`**: Add `target_compile_definitions(tvm_ffi_testing
PRIVATE TVM_FFI_DLL_EXPORT_INCLUDE_METADATA=1)` so the define is
provided via the build system instead of hardcoded in source.
## Test plan
- [ ] Verify existing C++ tests pass (`ctest` in CI)
- [ ] Verify downstream wasm unity builds compile without ambiguity
errors or macro redefinition warnings
---
CMakeLists.txt | 1 +
src/ffi/object.cc | 63 +++++++++++++++++++++++++---------------------
src/ffi/testing/testing.cc | 3 +--
3 files changed, 36 insertions(+), 31 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 94e8e935..427a106f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -164,6 +164,7 @@ target_link_libraries(tvm_ffi_static PUBLIC tvm_ffi_header)
# `tvm_ffi_testing` won't be inlcuded in `libtvm_ffi` and contains functions
that are registered
# only for testing purposes
target_sources(tvm_ffi_testing PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/testing/testing.cc")
+target_compile_definitions(tvm_ffi_testing PRIVATE
TVM_FFI_DLL_EXPORT_INCLUDE_METADATA=1)
target_compile_features(tvm_ffi_testing PRIVATE cxx_std_17)
set_target_properties(
tvm_ffi_testing
diff --git a/src/ffi/object.cc b/src/ffi/object.cc
index 2429b869..197b0941 100644
--- a/src/ffi/object.cc
+++ b/src/ffi/object.cc
@@ -595,37 +595,42 @@ int TVMFFIBytesFromByteArray(const TVMFFIByteArray*
input, TVMFFIAny* out) {
namespace {
TVM_FFI_STATIC_INIT_BLOCK() {
- using namespace tvm::ffi;
- namespace refl = tvm::ffi::reflection;
- refl::TypeAttrDef<Object>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<ObjectRef>);
- refl::TypeAttrDef<details::StringObj>().def(
- refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<String>);
- refl::TypeAttrDef<details::BytesObj>().def(
- refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<Bytes>);
- refl::TypeAttrDef<ErrorObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<Error>);
- refl::TypeAttrDef<FunctionObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<Function>);
- refl::TypeAttrDef<ShapeObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<Shape>);
- refl::TypeAttrDef<TensorObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<Tensor>);
- refl::TypeAttrDef<ArrayObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<Array<Any>>);
- refl::TypeAttrDef<MapObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<Map<Any, Any>>);
+ namespace ffi = ::tvm::ffi;
+ namespace refl = ::tvm::ffi::reflection;
+ refl::TypeAttrDef<ffi::Object>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::ObjectRef>);
+ refl::TypeAttrDef<ffi::details::StringObj>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::String>);
+ refl::TypeAttrDef<ffi::details::BytesObj>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Bytes>);
+ refl::TypeAttrDef<ffi::ErrorObj>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Error>);
+ refl::TypeAttrDef<ffi::FunctionObj>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Function>);
+ refl::TypeAttrDef<ffi::ShapeObj>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Shape>);
+ refl::TypeAttrDef<ffi::TensorObj>().def(
+ refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Tensor>);
+ refl::TypeAttrDef<ffi::ArrayObj>().def(
+ refl::type_attr::kConvert,
+ &refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Array<ffi::Any>>);
+ refl::TypeAttrDef<ffi::MapObj>().def(
+ refl::type_attr::kConvert,
+ &refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Map<ffi::Any,
ffi::Any>>);
// Skipped: TypeIndex::kTVMFFIModule
// Skipped: TypeIndex::kTVMFFIOpaquePyObject
- refl::TypeAttrDef<ListObj>().def(refl::type_attr::kConvert,
-
&refl::details::FFIConvertFromAnyViewToObjectRef<List<Any>>);
- refl::TypeAttrDef<DictObj>().def(
- refl::type_attr::kConvert,
&refl::details::FFIConvertFromAnyViewToObjectRef<Dict<Any, Any>>);
+ refl::TypeAttrDef<ffi::ListObj>().def(
+ refl::type_attr::kConvert,
+ &refl::details::FFIConvertFromAnyViewToObjectRef<ffi::List<ffi::Any>>);
+ refl::TypeAttrDef<ffi::DictObj>().def(
+ refl::type_attr::kConvert,
+ &refl::details::FFIConvertFromAnyViewToObjectRef<ffi::Dict<ffi::Any,
ffi::Any>>);
refl::GlobalDef()
- .def_method(
- "ffi.GetRegisteredTypeKeys",
- []() -> Array<String> { return
tvm::ffi::TypeTable::Global()->GetRegisteredTypeKeys(); })
- .def("ffi.GetInvalidObject", GetMissingObject)
- .def("ffi.GetKwargsObject", GetKwargsObject);
+ .def_method("ffi.GetRegisteredTypeKeys",
+ []() -> ffi::Array<ffi::String> {
+ return ffi::TypeTable::Global()->GetRegisteredTypeKeys();
+ })
+ .def("ffi.GetInvalidObject", ffi::GetMissingObject)
+ .def("ffi.GetKwargsObject", ffi::GetKwargsObject);
}
} // namespace
diff --git a/src/ffi/testing/testing.cc b/src/ffi/testing/testing.cc
index 5d4373f3..ad31b75b 100644
--- a/src/ffi/testing/testing.cc
+++ b/src/ffi/testing/testing.cc
@@ -17,8 +17,7 @@
* under the License.
*/
// This file is used for testing the FFI API.
-#define TVM_FFI_DLL_EXPORT_INCLUDE_METADATA 1
-
+// NOTE: TVM_FFI_DLL_EXPORT_INCLUDE_METADATA=1 is set via CMake
target_compile_definitions
#include <dlpack/dlpack.h>
#include <tvm/ffi/any.h>
#include <tvm/ffi/container/array.h>