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 da7007f chore(build): Split `src/ffi/extra/testing.cc` into
`libtvm_ffi_testing.so` (#114)
da7007f is described below
commit da7007fda1b1ece445cb66dbfbcf8c4bf8afb4bc
Author: Junru Shao <[email protected]>
AuthorDate: Tue Oct 14 17:19:08 2025 -0700
chore(build): Split `src/ffi/extra/testing.cc` into `libtvm_ffi_testing.so`
(#114)
---
CMakeLists.txt | 19 ++++++++++++-
cmake/Utils/Library.cmake | 15 ++++++++++
python/tvm_ffi/__init__.py | 2 --
python/tvm_ffi/libinfo.py | 52 +++++++++++++++++++++++++++++------
python/tvm_ffi/testing.py | 6 ++++
rust/tvm-ffi-sys/build.rs | 1 +
rust/tvm-ffi-sys/src/c_api.rs | 1 +
rust/tvm-ffi/tests/test_function.rs | 6 ++++
src/ffi/backtrace_win.cc | 21 ++++++++------
src/ffi/{extra => testing}/testing.cc | 2 ++
tests/cpp/CMakeLists.txt | 1 +
tests/cpp/test_function.cc | 7 +++++
12 files changed, 113 insertions(+), 20 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff1a146..b268152 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,7 +72,6 @@ set(_tvm_ffi_extra_objs_sources
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_dynamic_lib.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/env_context.cc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/env_c_api.cc"
- "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/testing.cc"
)
if (TVM_FFI_USE_EXTRA_CXX_API)
list(APPEND _tvm_ffi_objs_sources ${_tvm_ffi_extra_objs_sources})
@@ -132,6 +131,23 @@ target_link_libraries(tvm_ffi_objs PUBLIC tvm_ffi_header)
target_link_libraries(tvm_ffi_shared PUBLIC tvm_ffi_header)
target_link_libraries(tvm_ffi_static PUBLIC tvm_ffi_header)
+# ######### Target: `tvm_ffi_testing` ##########
+# Build testing utilities as a separate shared library that can be loaded on
demand
+# `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_features(tvm_ffi_testing PRIVATE cxx_std_17)
+set_target_properties(
+ tvm_ffi_testing
+ PROPERTIES CXX_EXTENSIONS OFF
+ CXX_STANDARD_REQUIRED ON
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+)
+target_link_libraries(tvm_ffi_testing PRIVATE tvm_ffi_shared)
+target_link_libraries(tvm_ffi_testing PUBLIC tvm_ffi_header)
+tvm_ffi_add_msvc_flags(tvm_ffi_testing)
+tvm_ffi_add_apple_dsymutil(tvm_ffi_testing)
+
# ----------------------------------------------------------------------------
# The following code section only is triggered when the project is the root
and will be skipped when
# the project is a subproject.
@@ -265,6 +281,7 @@ endif ()
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/tvm/ffi/ DESTINATION
include/tvm/ffi/)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/dlpack/include/
DESTINATION include/)
install(TARGETS tvm_ffi_shared DESTINATION lib)
+install(TARGETS tvm_ffi_testing DESTINATION lib)
# ship additional dSYM files for debugging symbols on if available
if (APPLE)
install(
diff --git a/cmake/Utils/Library.cmake b/cmake/Utils/Library.cmake
index 1a76fa6..73817e9 100644
--- a/cmake/Utils/Library.cmake
+++ b/cmake/Utils/Library.cmake
@@ -100,6 +100,14 @@ function (tvm_ffi_add_target_from_obj target_name
obj_target_name)
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
)
+ add_library(${target_name}_testing SHARED)
+ set_target_properties(
+ ${target_name}_testing
+ PROPERTIES OUTPUT_NAME "${target_name}_testing"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ )
if (WIN32)
target_compile_definitions(${obj_target_name} PRIVATE TVM_FFI_EXPORTS)
# set the output directory for each config type so msbuild also get into
lib without appending
@@ -118,7 +126,14 @@ function (tvm_ffi_add_target_from_obj target_name
obj_target_name)
LIBRARY_OUTPUT_DIRECTORY_${config_type}
"${CMAKE_BINARY_DIR}/lib"
ARCHIVE_OUTPUT_DIRECTORY_${config_type}
"${CMAKE_BINARY_DIR}/lib"
)
+ set_target_properties(
+ ${target_name}_testing
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${config_type}
"${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY_${config_type}
"${CMAKE_BINARY_DIR}/lib"
+ ARCHIVE_OUTPUT_DIRECTORY_${config_type}
"${CMAKE_BINARY_DIR}/lib"
+ )
endforeach ()
endif ()
tvm_ffi_add_apple_dsymutil(${target_name}_shared)
+ tvm_ffi_add_apple_dsymutil(${target_name}_testing)
endfunction ()
diff --git a/python/tvm_ffi/__init__.py b/python/tvm_ffi/__init__.py
index df04cf1..f6d9045 100644
--- a/python/tvm_ffi/__init__.py
+++ b/python/tvm_ffi/__init__.py
@@ -45,7 +45,6 @@ from .module import Module, system_lib, load_module
from .stream import StreamContext, get_raw_stream, use_raw_stream,
use_torch_stream
from . import serialization
from . import access_path
-from . import testing
from . import dataclasses
# optional module to speedup dlpack conversion
@@ -81,5 +80,4 @@ __all__ = [
"remove_global_func",
"serialization",
"system_lib",
- "testing",
]
diff --git a/python/tvm_ffi/libinfo.py b/python/tvm_ffi/libinfo.py
index fd0e784..df814cf 100644
--- a/python/tvm_ffi/libinfo.py
+++ b/python/tvm_ffi/libinfo.py
@@ -14,7 +14,11 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-"""Utilities to locate tvm_ffi libraries, headers, and helper include paths."""
+"""Utilities to locate tvm_ffi libraries, headers, and helper include paths.
+
+This module also provides helpers to locate and load platform-specific shared
+libraries by a base name (e.g., ``tvm_ffi`` -> ``libtvm_ffi.so`` on Linux).
+"""
import os
import sys
@@ -62,14 +66,46 @@ def get_dll_directories() -> list[str]:
def find_libtvm_ffi() -> str:
- """Find libtvm_ffi."""
+ """Find libtvm_ffi.
+
+ Returns
+ -------
+ path
+ The full path to the located library.
+
+ """
+ return find_library_by_basename("tvm_ffi")
+
+
+def find_library_by_basename(base: str) -> str:
+ """Find a shared library by base name across known directories.
+
+ Parameters
+ ----------
+ base
+ Base name (e.g., ``"tvm_ffi"`` or ``"tvm_ffi_testing"``).
+
+ Returns
+ -------
+ path
+ The full path to the located library.
+
+ Raises
+ ------
+ RuntimeError
+ If the library cannot be found in any of the candidate directories.
+
+ """
dll_path = [Path(p) for p in get_dll_directories()]
if sys.platform.startswith("win32"):
- lib_dll_names = ["tvm_ffi.dll"]
+ lib_dll_names = [f"{base}.dll"]
elif sys.platform.startswith("darwin"):
- lib_dll_names = ["libtvm_ffi.dylib", "libtvm_ffi.so"]
- else:
- lib_dll_names = ["libtvm_ffi.so"]
+ lib_dll_names = [ # Prefer dylib, also allow .so for some toolchains
+ f"lib{base}.dylib",
+ f"lib{base}.so",
+ ]
+ else: # Linux, FreeBSD, etc
+ lib_dll_names = [f"lib{base}.so"]
lib_dll_path = [p / name for name in lib_dll_names for p in dll_path]
lib_found = [p for p in lib_dll_path if p.exists() and p.is_file()]
@@ -77,9 +113,7 @@ def find_libtvm_ffi() -> str:
if not lib_found:
candidate_list = "\n".join(str(p) for p in lib_dll_path)
raise RuntimeError(
- "Cannot find library: {}\nList of candidates:\n{}".format(
- ", ".join(lib_dll_names), candidate_list
- )
+ f"Cannot find library: {', '.join(lib_dll_names)}\nList of
candidates:\n{candidate_list}"
)
return str(lib_found[0])
diff --git a/python/tvm_ffi/testing.py b/python/tvm_ffi/testing.py
index 820fd60..04b6387 100644
--- a/python/tvm_ffi/testing.py
+++ b/python/tvm_ffi/testing.py
@@ -19,6 +19,12 @@
from __future__ import annotations
+from . import libinfo
+from .module import load_module
+
+_LIBTVM_FFI_TESTING =
load_module(libinfo.find_library_by_basename("tvm_ffi_testing"))
+
+
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Any, ClassVar
diff --git a/rust/tvm-ffi-sys/build.rs b/rust/tvm-ffi-sys/build.rs
index 24e1f6c..7cd7f24 100644
--- a/rust/tvm-ffi-sys/build.rs
+++ b/rust/tvm-ffi-sys/build.rs
@@ -61,6 +61,7 @@ fn main() {
println!("cargo:rustc-link-search=native={}", lib_dir);
// link the library
println!("cargo:rustc-link-lib=dylib=tvm_ffi");
+ println!("cargo:rustc-link-lib=dylib=tvm_ffi_testing");
// update the LD_LIBRARY_PATH environment variable
update_ld_library_path(&lib_dir);
}
diff --git a/rust/tvm-ffi-sys/src/c_api.rs b/rust/tvm-ffi-sys/src/c_api.rs
index a55470d..e0bf085 100644
--- a/rust/tvm-ffi-sys/src/c_api.rs
+++ b/rust/tvm-ffi-sys/src/c_api.rs
@@ -429,4 +429,5 @@ unsafe extern "C" {
cross_ffi_boundary: i32,
) -> *const TVMFFIByteArray;
pub fn TVMFFIGetTypeInfo(type_index: i32) -> *const TVMFFITypeInfo;
+ pub fn TVMFFITestingDummyTarget() -> i32;
}
diff --git a/rust/tvm-ffi/tests/test_function.rs
b/rust/tvm-ffi/tests/test_function.rs
index fef5e34..08efc66 100644
--- a/rust/tvm-ffi/tests/test_function.rs
+++ b/rust/tvm-ffi/tests/test_function.rs
@@ -18,6 +18,12 @@
*/
use tvm_ffi::*;
+#[test]
+fn test_function_dummpy_c_api() {
+ let ret = unsafe { tvm_ffi_sys::TVMFFITestingDummyTarget() };
+ assert_eq!(ret, 0);
+}
+
#[test]
fn test_function_get_global_required() {
let fecho = Function::get_global("testing.echo").unwrap();
diff --git a/src/ffi/backtrace_win.cc b/src/ffi/backtrace_win.cc
index c4491db..ca5cf06 100644
--- a/src/ffi/backtrace_win.cc
+++ b/src/ffi/backtrace_win.cc
@@ -62,18 +62,23 @@ const TVMFFIByteArray* TVMFFIBacktrace(const char*
filename, int lineno, const c
STACKFRAME64 stack = {};
DWORD machine_type;
-#if defined(_M_X64)
- machine_type = IMAGE_FILE_MACHINE_AMD64;
- stack.AddrPC.Offset = context.Rip;
- stack.AddrFrame.Offset = context.Rbp;
- stack.AddrStack.Offset = context.Rsp;
-#elif defined(_M_IX86)
+#ifdef _M_IX86
machine_type = IMAGE_FILE_MACHINE_I386;
stack.AddrPC.Offset = context.Eip;
- stack.AddrFrame.Offset = context.Ebp;
stack.AddrStack.Offset = context.Esp;
+ stack.AddrFrame.Offset = context.Ebp;
+#elif _M_X64
+ machine_type = IMAGE_FILE_MACHINE_AMD64;
+ stack.AddrPC.Offset = context.Rip;
+ stack.AddrStack.Offset = context.Rsp;
+ stack.AddrFrame.Offset = context.Rbp;
+#elif _M_ARM64
+ machine_type = IMAGE_FILE_MACHINE_ARM64;
+ stack.AddrPC.Offset = context.Pc;
+ stack.AddrStack.Offset = context.Sp;
+ stack.AddrFrame.Offset = context.Fp;
#else
-#error "Platform not supported!"
+#error "Unsupported architecture"
#endif
stack.AddrPC.Mode = AddrModeFlat;
diff --git a/src/ffi/extra/testing.cc b/src/ffi/testing/testing.cc
similarity index 99%
rename from src/ffi/extra/testing.cc
rename to src/ffi/testing/testing.cc
index 11772ad..95c8b30 100644
--- a/src/ffi/extra/testing.cc
+++ b/src/ffi/testing/testing.cc
@@ -451,3 +451,5 @@ TVM_FFI_STATIC_INIT_BLOCK() {
} // namespace ffi
} // namespace tvm
+
+extern "C" TVM_FFI_DLL_EXPORT int TVMFFITestingDummyTarget() { return 0; }
diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt
index 069ba4b..7ab3c2a 100644
--- a/tests/cpp/CMakeLists.txt
+++ b/tests/cpp/CMakeLists.txt
@@ -22,6 +22,7 @@ add_sanitizer_address(tvm_ffi_tests)
tvm_ffi_add_apple_dsymutil(tvm_ffi_tests)
tvm_ffi_add_msvc_flags(tvm_ffi_tests)
target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi_shared)
+target_link_libraries(tvm_ffi_tests PRIVATE tvm_ffi_testing)
tvm_ffi_add_gtest(tvm_ffi_tests)
if (MSVC)
diff --git a/tests/cpp/test_function.cc b/tests/cpp/test_function.cc
index b8ff769..b32b701 100644
--- a/tests/cpp/test_function.cc
+++ b/tests/cpp/test_function.cc
@@ -269,4 +269,11 @@ int invoke_testing_add1(int x) {
TEST(Func, InvokeExternC) { EXPECT_EQ(invoke_testing_add1(1), 2); }
+extern "C" TVM_FFI_DLL int TVMFFITestingDummyTarget();
+
+TEST(Func, DummyCFunc) {
+ int value = TVMFFITestingDummyTarget();
+ EXPECT_EQ(value, 0);
+}
+
} // namespace