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>

Reply via email to