-
Notifications
You must be signed in to change notification settings - Fork 57
/
build.py
156 lines (130 loc) · 5.39 KB
/
build.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import sys
import os
import sys
import shutil
import time
import platform
import distutils.dir_util
from wheel.bdist_wheel import bdist_wheel
'''
BDistWheel forces python and abi wheel tags for binary distributions
'''
class BDistWheel(bdist_wheel):
def finalize_options(self):
bdist_wheel.finalize_options(self)
self.root_is_pure = ("--universal" in sys.argv)
'''
Sort out the platform library for binary distribution and add to the package directory.
Place all libraries onto the package directory for source distribution.
Place the XML doc file onto the package directory.
'''
class PackageDataBuilder():
def __init__(self):
self.pkg_dir = os.path.join(os.curdir, "delphifmx")
self.plat_name = None
for arg in sys.argv:
if arg.startswith("--plat-name=") and (len(arg.split("=")) == 2):
self.plat_name = arg.split("=")[1]
'''
Must run "python setup.py clean --all" between builds.
'''
def clean_up(self):
lib_dirs = [os.path.join(self.pkg_dir, "Win32"),
os.path.join(self.pkg_dir, "Win64"),
os.path.join(self.pkg_dir, "Linux64"),
os.path.join(self.pkg_dir, "OSX64"),
os.path.join(self.pkg_dir, "OSXARM64")]
for lib_dir in lib_dirs:
if os.path.isdir(lib_dir):
shutil.rmtree(lib_dir)
# Wait until the OS remove all dirs
for lib_dir in lib_dirs:
for attempts in range(3):
if not os.path.isdir(lib_dir):
break
else:
time.sleep(1)
'''
Cross-compiling wheel.
This generates a wheel following the cross platform set on --plat-name.
See: https://docs.python.org/3/distutils/builtdist.html#cross-compiling-on-windows
'''
def __check_cross_compiling(self):
is_cross_compiling = False
lib_dir = None
if self.plat_name:
is_cross_compiling = True
if self.plat_name == "win32":
lib_dir = "Win32"
elif self.plat_name == "win_amd64":
lib_dir = "Win64"
elif self.plat_name == "manylinux1_x86_64":
lib_dir = "Linux64"
# macosx_10_9_x86_64
elif self.plat_name.startswith("macosx") and self.plat_name.endswith("x86_64"):
lib_dir = "OSX64"
# macosx_11_0_arm64
elif self.plat_name.startswith("macosx") and self.plat_name.endswith("arm64"):
lib_dir = "OSXARM64"
else:
is_cross_compiling = False
return (is_cross_compiling, lib_dir)
'''
Copy the FMX extension module(s) to the package data folder.
Source distributions and Universal binary distributions will deliver
all library versions. The right one will be loaded by __init__.py.
Platform distributions will deliver only the library that matches the runner.
'''
def __pick_and_copy_libraries(self):
if ("sdist" in sys.argv) or (("bdist_wheel" in sys.argv) and ("--universal" in sys.argv)):
# sdist/bdist[--universal] deploy all extension modules
distutils.dir_util.copy_tree("lib", self.pkg_dir)
else:
# Deploys the current platform extension module only
is_cross_compiling, lib_dir = self.__check_cross_compiling()
if not is_cross_compiling:
plat_sys = platform.system()
plat_mac = platform.machine()
if plat_sys == "Windows":
if (sys.maxsize > 2**32):
# Win x64
lib_dir = "Win64"
else:
# Win x86
lib_dir = "Win32"
elif plat_sys == "Linux":
if plat_mac == "x86_64":
# Linux x86_64
lib_dir = "Linux64"
elif plat_sys == "Darwin":
if plat_mac == "x86_64":
# macOS x86_64
lib_dir = "OSX64"
elif plat_mac == "arm64":
# macOS arm64
lib_dir = "OSXARM64"
if lib_dir:
distutils.dir_util.copy_tree(os.path.join(
"lib", lib_dir), os.path.join(self.pkg_dir, lib_dir))
else:
raise ValueError("Unsupported platform.")
'''
Copy the XML doc file to the package data folder.
The docs.xml file is the result of the compilation of all xml doc files.
'''
def __pick_and_copy_docs(self):
# Copy the doc files to the package folder into the doc subfolder
docs_file = os.path.join("docs", "xml", "docs.xml")
if os.path.exists(docs_file):
pkg_doc_dir = os.path.join(self.pkg_dir, "doc")
if not os.path.exists(pkg_doc_dir):
os.mkdir(pkg_doc_dir)
distutils.file_util.copy_file(
docs_file, os.path.join(pkg_doc_dir, "docs.xml"))
def build_package_data(self):
self.__pick_and_copy_libraries()
self.__pick_and_copy_docs()
def setup():
builder = PackageDataBuilder()
builder.clean_up()
builder.build_package_data()