forked from NVIDIA/warp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
setup.py
138 lines (107 loc) · 4.67 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import argparse
import os
import shutil
from typing import NamedTuple
import setuptools
from wheel.bdist_wheel import bdist_wheel
# Parse --build-option arguments meant for the bdist_wheel command. We have to parse these
# ourselves because when bdist_wheel runs it's too late to select a subset of libraries for package_data.
parser = argparse.ArgumentParser()
parser.add_argument("command")
parser.add_argument("--platform", "-P", type=str, default="", help="Wheel platform: windows|linux|macos")
args = parser.parse_known_args()[0]
class Platform(NamedTuple):
name: str
fancy_name: str
extension: str
tag: str
platforms = [
Platform("windows", "Windows", ".dll", "win_amd64"),
Platform("linux", "Linux", ".so", "manylinux2014_x86_64"),
Platform("macos", "macOS", ".dylib", "macosx_10_13_x86_64"),
]
# Determine supported platforms of warp/bin libraries based on their extension
def detect_warp_platforms():
detected_platforms = set()
for filename in os.listdir("warp/bin"):
for p in platforms:
if os.path.splitext(filename)[1] == p.extension:
detected_platforms.add(p)
if len(detected_platforms) == 0:
raise Exception("No libraries found in warp/bin. Please run build_lib.py first.")
return detected_platforms
detected_platforms = detect_warp_platforms()
wheel_platform = None # The one platform for which we're building a wheel
if args.command == "bdist_wheel":
if args.platform != "":
for p in platforms:
if args.platform == p.name or args.platform == p.fancy_name:
wheel_platform = p
print(f"Platform argument specified for building {p.fancy_name} wheel")
break
if wheel_platform is None:
print(f"Platform argument '{args.platform}' not recognized")
elif wheel_platform not in detected_platforms:
print(f"No libraries found for {wheel_platform.fancy_name}")
print(f"Falling back to auto-detection")
wheel_platform = None
if wheel_platform is None:
if len(detected_platforms) > 1:
print("Libraries for multiple platforms were detected. Picking the first one.")
print("Run `python -m build --wheel -C--build-option=-P[windows|linux|macos]` to select a specific one.")
wheel_platform = next(iter(detected_platforms))
print("Creating Warp wheel for " + wheel_platform.fancy_name)
# Binary wheel distribution builds assume that the platform you're building on will be the platform
# of the package. This class overrides the platform tag.
# https://packaging.python.org/en/latest/specifications/platform-compatibility-tags
class WarpBDistWheel(bdist_wheel):
# Even though we parse the platform argument ourselves, we need to declare it here as well so
# setuptools.Command can validate the command line options.
user_options = bdist_wheel.user_options + [
("platform=", "P", "Wheel platform: windows|linux|macos"),
]
def initialize_options(self):
super().initialize_options()
self.platform = ""
def get_tag(self):
# The wheel's complete tag format is {python tag}-{abi tag}-{platform tag}.
return "py3", "none", wheel_platform.tag
def run(self):
super().run()
# Clean up so we can re-invoke `py -m build --wheel -C--build-option=--platform=...`
# See https://github.com/pypa/setuptools/issues/1871 for details.
shutil.rmtree("./build", ignore_errors=True)
shutil.rmtree("./warp_lang.egg-info", ignore_errors=True)
# Distributions are identified as non-pure (i.e. containing non-Python code, or binaries) if the
# setuptools.setup() `ext_modules` parameter is not empty, but this assumes building extension
# modules from source through the Python build. This class provides an override for prebuilt binaries:
class BinaryDistribution(setuptools.Distribution):
def has_ext_modules(self):
return True
def get_warp_libraries(extension):
libraries = []
for filename in os.listdir("warp/bin"):
if os.path.splitext(filename)[1] == extension:
libraries.append("bin/" + filename)
return libraries
if wheel_platform is not None:
warp_binary_libraries = get_warp_libraries(wheel_platform.extension)
else:
warp_binary_libraries = [] # Not needed during egg_info command
setuptools.setup(
package_data={
"": [
"native/*.cpp",
"native/*.cu",
"native/*.h",
"native/clang/*.cpp",
"native/nanovdb/*.h",
"tests/assets/*",
]
+ warp_binary_libraries,
},
distclass=BinaryDistribution,
cmdclass={
"bdist_wheel": WarpBDistWheel,
},
)