blob: 81940a5030a1ebb78e006826c506c379ee8e412f [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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 helper: stages the native library and binary-distribution legal files."""
import os
import platform
import shutil
from setuptools import Distribution, setup
from setuptools.command.build_py import build_py
from wheel.bdist_wheel import bdist_wheel
LEGAL_FILES = ("LICENSE", "NOTICE", "LICENSE-binary")
LEGAL_SOURCE_FILES = {
"LICENSE": "LICENSE",
"NOTICE": "NOTICE",
"LICENSE-binary": "LICENSE-binary-ffi",
}
def _lib_name():
system = platform.system()
if system == "Darwin":
return "libpaimon_vindex_ffi.dylib"
if system == "Windows":
return "paimon_vindex_ffi.dll"
return "libpaimon_vindex_ffi.so"
def _find_native_lib():
here = os.path.dirname(os.path.abspath(__file__))
lib = _lib_name()
env_path = os.environ.get("PAIMON_VINDEX_LIB_PATH")
if env_path:
if os.path.isfile(env_path):
return env_path
candidate = os.path.join(env_path, lib)
if os.path.isfile(candidate):
return candidate
for profile in ["release", "debug"]:
candidate = os.path.join(here, "..", "target", profile, lib)
if os.path.isfile(candidate):
return candidate
return None
def _stage_legal_files(destination_dir):
here = os.path.dirname(os.path.abspath(__file__))
staged = []
for name in LEGAL_FILES:
source = os.path.join(here, "..", LEGAL_SOURCE_FILES[name])
destination = os.path.join(destination_dir, name)
if not os.path.isfile(source):
raise RuntimeError(f"required binary legal file is missing: {source}")
if os.path.exists(destination):
with open(source, "rb") as source_file:
source_bytes = source_file.read()
with open(destination, "rb") as destination_file:
destination_bytes = destination_file.read()
if source_bytes != destination_bytes:
raise RuntimeError(
f"staged binary legal file does not match repository copy: {destination}"
)
continue
shutil.copy2(source, destination)
staged.append(destination)
return staged
class BuildPyWithNativeLib(build_py):
def run(self):
src = _find_native_lib()
if src:
dst = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"paimon_vindex",
_lib_name(),
)
shutil.copy2(src, dst)
staged_legal_files = _stage_legal_files(
os.path.join(os.path.dirname(os.path.abspath(__file__)), "paimon_vindex")
)
try:
super().run()
finally:
for path in staged_legal_files:
os.remove(path)
class PlatformWheel(bdist_wheel):
"""Tag wheel as py3-none-{platform} since this is a ctypes package."""
def finalize_options(self):
bdist_wheel.finalize_options(self)
self.root_is_pure = False
def get_tag(self):
_, _, plat = bdist_wheel.get_tag(self)
return "py3", "none", plat
class BinaryDistribution(Distribution):
"""Force the wheel to be platform-specific."""
def has_ext_modules(self):
return True
staged_distribution_legal_files = _stage_legal_files(
os.path.dirname(os.path.abspath(__file__))
)
try:
setup(
cmdclass={"build_py": BuildPyWithNativeLib, "bdist_wheel": PlatformWheel},
distclass=BinaryDistribution,
)
finally:
for path in staged_distribution_legal_files:
os.remove(path)