diff --git a/bazel/tvm_ffi_configure.bzl b/bazel/tvm_ffi_configure.bzl index b224dd1..effa34d 100644 --- a/bazel/tvm_ffi_configure.bzl +++ b/bazel/tvm_ffi_configure.bzl @@ -101,45 +101,88 @@ def _tvm_ffi_configure(repository_ctx): repository_ctx.symlink(include_dir, "include") repository_ctx.symlink(dlpack_dir, "dlpack") - # Step 6: Symlink the import library for linking - # On Windows, we need the .lib file to link against TVM FFI at compile time. - # The .dll is loaded at runtime via tvm_ffi.load_module() in Python. - lib_files_srcs = "" - if lib_files: - # Take the first library file (typically the import library) - for lib_file in lib_files: - # Create symlink to the .lib file - lib_name = repository_ctx.path(lib_file).basename - repository_ctx.symlink(lib_file, lib_name) - - # Format for BUILD file - use filegroup for proper handling - lib_files_srcs += '"%s",' % lib_name - - - # Step 7: Generate BUILD file - # The BUILD file defines a cc_library that propagates include paths. - # Using includes (not copts) ensures paths propagate to dependent targets. - # Note: TVM FFI is a pre-built binary, so we don't compile any source files. - # The library is loaded at runtime via dlopen/LoadLibrary from Python. + # Step 6: Symlink library files and detect platform-specific binaries. + # --libfiles returns: .lib (Windows import lib), .so (Linux), .dylib (macOS). + # On Windows, the runtime .dll is a sibling of the .lib in the same directory. + win_implib = None + win_dll = None + unix_shared = None # .so or .dylib + + for lib_file in lib_files: + lib_path = repository_ctx.path(lib_file) + lib_name = lib_path.basename + repository_ctx.symlink(lib_file, lib_name) + + if lib_name.endswith(".lib"): + win_implib = lib_name + dll_name = lib_name[:-4] + ".dll" + dll_path = lib_path.dirname.get_child(dll_name) + if dll_path.exists: + repository_ctx.symlink(str(dll_path), dll_name) + win_dll = dll_name + elif lib_name.endswith(".so") or lib_name.endswith(".dylib"): + unix_shared = lib_name + + + # Step 7: Generate BUILD file with platform-specific cc_import targets. + # Each cc_import pulls the shared library into dependents' runfiles for both + # link-time and runtime. The aggregating cc_library propagates include paths + # and selects the right import for the host platform via select(). + imports = "" + select_branches = "" + + if win_implib and win_dll: + imports += """ +cc_import( + name = "tvm_ffi_dll", + interface_library = "{implib}", + shared_library = "{dll}", + target_compatible_with = ["@platforms//os:windows"], + visibility = ["//visibility:private"], +) +""".format(implib = win_implib, dll = win_dll) + select_branches += '\n "@platforms//os:windows": [":tvm_ffi_dll"],' + + if unix_shared and unix_shared.endswith(".so"): + imports += """ +cc_import( + name = "tvm_ffi_so", + shared_library = "{so}", + target_compatible_with = ["@platforms//os:linux"], + visibility = ["//visibility:private"], +) +""".format(so = unix_shared) + select_branches += '\n "@platforms//os:linux": [":tvm_ffi_so"],' + + if unix_shared and unix_shared.endswith(".dylib"): + imports += """ +cc_import( + name = "tvm_ffi_dylib", + shared_library = "{dylib}", + target_compatible_with = ["@platforms//os:osx"], + visibility = ["//visibility:private"], +) +""".format(dylib = unix_shared) + select_branches += '\n "@platforms//os:osx": [":tvm_ffi_dylib"],' + build_content = """ package(default_visibility = ["//visibility:public"]) -load("@rules_cc//cc:cc_library.bzl", "cc_library") - +load("@rules_cc//cc:defs.bzl", "cc_import", "cc_library") +{imports} cc_library( name = "tvm_ffi", - # Relative paths via symlinked directories - Bazel requires this includes = [ "include", "dlpack", ], - # Link against TVM FFI import library (.lib on Windows) - # {lib_files_srcs} is intentionally left without leading comma if empty - srcs = [{lib_files_srcs}], - visibility = ["//visibility:public"], + deps = select({{{select} + "//conditions:default": [], + }}), ) """.format( - lib_files_srcs = lib_files_srcs, + imports = imports, + select = select_branches, ) # Write the generated BUILD file to the external repository root diff --git a/pyproject.toml b/pyproject.toml index 8d85ee1..0466a55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,8 +12,43 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -[tool.uv.workspace] -members = ["python"] +[build-system] +requires = ["setuptools>=61"] +build-backend = "setuptools.build_meta" + +[project] +name = "vila" +description = "Commonly used Python libraries" +readme = "python/README.md" +requires-python = ">=3.10" +authors = [{ name = "Wenyi Tang", email = "wenyitang@outlook.com" }] +license = { file = "python/LICENSE" } +classifiers = ["License :: OSI Approved :: MIT License"] +dynamic = ["version"] +dependencies = ["numpy"] + +[project.urls] +Home = "https://github.com/llteco/vila" +Docs = "https://llteco.github.io/vila" + +[project.optional-dependencies] +test = ["pre-commit", "pytest", "pytest-cov", "pooch"] + +[tool.setuptools.packages.find] +where = ["python"] +include = ["vila*"] + +[tool.setuptools.dynamic] +version = { attr = "vila.__version__" } + +[dependency-groups] +dev = [ + "apache-tvm-ffi>=0.1.12", + "pooch>=1.9.0", + "pre-commit>=4.5.1", + "pytest>=9.0.2", + "pytest-cov>=7.0.0", +] [tool.pyright] include = ["python"] diff --git a/python/pyproject.toml b/python/pyproject.toml deleted file mode 100644 index 19a5f43..0000000 --- a/python/pyproject.toml +++ /dev/null @@ -1,43 +0,0 @@ -# -# Copyright (C) 2024-2026 The VILA Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[build-system] -requires = ["flit_core >=3.2,<4"] -build-backend = "flit_core.buildapi" - -[project] -name = "vila" -readme = "README.md" -requires-python = ">=3.10" -authors = [{ name = "Wenyi Tang", email = "wenyitang@outlook.com" }] -license = { file = "LICENSE" } -classifiers = ["License :: OSI Approved :: MIT License"] -dynamic = ["version", "description"] -dependencies = ["numpy"] - -[project.urls] -Home = "https://github.com/llteco/vila" -Docs = "https://llteco.github.io/vila" - -[project.optional-dependencies] -test = ["pre-commit", "pytest", "pytest-cov", "pooch"] - -[dependency-groups] -dev = [ - "pooch>=1.9.0", - "pre-commit>=4.5.1", - "pytest>=9.0.2", - "pytest-cov>=7.0.0", -]