-
Notifications
You must be signed in to change notification settings - Fork 144
/
SConstruct
234 lines (186 loc) Β· 7.19 KB
/
SConstruct
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
import os
import re
import shutil
from datetime import datetime
from SCons.Platform.virtualenv import ImportVirtualenv
from SCons.Errors import UserError
EnsurePythonVersion(3, 7)
EnsureSConsVersion(3, 0)
def extract_version():
# Hold my beer...
gl = {}
exec(open("pythonscript/godot/_version.py").read(), gl)
return gl["__version__"]
def godot_binary_converter(val, env):
file = File(val)
if file.exists():
# Note here `env["godot_binary_download_version"]` is not defined, this is ok given
# this variable shouldn't be needed if Godot doesn't have to be downloaded
return file
# Provided value is version information with format <major>.<minor>.<patch>[-<extra>]
match = re.match(r"^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-(\w+))?$", val)
if match:
major, minor, patch, extra = match.groups()
else:
raise UserError(
f"`{val}` is neither an existing file nor a valid <major>.<minor>.<patch>[-<extra>] Godot version format"
)
env["godot_binary_download_version"] = (major, minor, patch, extra or "stable")
# `godot_binary` is set to None to indicate it should be downloaded
return None
vars = Variables("custom.py")
vars.Add(
EnumVariable(
"platform",
"Target platform",
"",
allowed_values=("x11-64", "x11-32", "windows-64", "windows-32", "osx-64"),
)
)
vars.Add("pytest_args", "Pytest arguments passed to tests functions", "")
vars.Add(
"godot_args", "Additional arguments passed to godot binary when running tests&examples", ""
)
vars.Add("release_suffix", "Suffix to add to the release archive", extract_version())
vars.Add(
"godot_binary",
"Path to Godot binary or version of Godot to use",
default="3.2.2",
converter=godot_binary_converter,
)
vars.Add("godot_headers", "Path to Godot GDnative headers", "")
vars.Add("debugger", "Run test with a debugger", "")
vars.Add(BoolVariable("debug", "Compile with debug symbols", False))
vars.Add(BoolVariable("headless", "Run tests in headless mode", False))
vars.Add(BoolVariable("compressed_stdlib", "Compress Python std lib as a zip to save space", True))
vars.Add(
BoolVariable(
"bindings_generate_sample",
"Generate only a subset of the bindings (faster build time)",
False,
)
)
vars.Add("CC", "C compiler")
vars.Add("CFLAGS", "Custom flags for the C compiler")
vars.Add("LINK", "linker")
vars.Add("LINKFLAGS", "Custom flags for the linker")
vars.Add("CPYTHON_CFLAGS", "Custom flags for the C compiler used to compile CPython")
vars.Add("CPYTHON_LINKFLAGS", "Custom flags for the linker used to compile CPython")
vars.Add("OPENSSL_PATH", "Path to the root of openssl installation to link CPython against")
vars.Add(
"MSVC_VERSION",
"MSVC version to use (Windows only) -- version num X.Y. Default: highest installed.",
)
vars.Add(
BoolVariable(
"MSVC_USE_SCRIPT",
(
"Set to True to let SCons find compiler (with MSVC_VERSION and TARGET_ARCH), "
"False to use cmd.exe env (MSVC_VERSION and TARGET_ARCH will be ignored), "
"or vcvarsXY.bat script name to use."
),
True,
)
)
# Set Visual Studio arch according to platform target
vanilla_vars_update = vars.Update
def _patched_vars_update(env, args=None):
vanilla_vars_update(env, args=None)
if env["platform"] == "windows-64":
env["TARGET_ARCH"] = "x86_64"
elif env["platform"] == "windows-32":
env["TARGET_ARCH"] = "x86"
vars.Update = _patched_vars_update
env = Environment(
variables=vars,
tools=["default", "cython", "symlink", "virtual_target", "download"],
ENV=os.environ,
# ENV = {'PATH' : os.environ['PATH']},
)
# Detect compiler
env["CC_IS_MSVC"] = env.get("CC") in ("cl", "cl.exe")
env["CC_IS_GCC"] = "gcc" in env.get("CC")
env["CC_IS_CLANG"] = "clang" in env.get("CC")
Help(vars.GenerateHelpText(env))
# if env["HOST_OS"] == "win32":
# # Fix ImportVirtualenv raising error if PATH make reference to other drives
# from SCons.Platform import virtualenv
# vanilla_IsInVirtualenv = virtualenv.IsInVirtualenv
# def patched_IsInVirtualenv(path):
# try:
# return vanilla_IsInVirtualenv(path)
# except ValueError:
# return False
# virtualenv.IsInVirtualenv = patched_IsInVirtualenv
# ImportVirtualenv(env)
if env["godot_headers"]:
env["godot_headers"] = Dir(env["godot_headers"])
else:
env["godot_headers"] = Dir("godot_headers")
env.AppendUnique(CPPPATH=["$godot_headers"])
# TODO: not sure why, but CPPPATH scan result for cython modules change between
# first and subsequent runs of scons (module is considered to no longer depend
# on godot_headers on subsequent run, so the build redone)
SetOption("implicit_cache", 1)
### Save my eyes plz ###
env["ENV"]["TERM"] = os.environ.get("TERM", "")
if env["CC_IS_CLANG"]:
env.Append(CCFLAGS=["-fcolor-diagnostics"])
if env["CC_IS_GCC"]:
env.Append(CCFLAGS=["-fdiagnostics-color=always"])
### Default compile flags ###
if not env["CC_IS_MSVC"]:
if env["debug"]:
env.Append(CFLAGS=["-g", "-ggdb"])
env.Append(LINKFLAGS=["-g", "-ggdb"])
else:
env.Append(CFLAGS=["-O2"])
else:
if env["debug"]:
env.Append(CFLAGS=["/DEBUG:FULL"])
env.Append(LINKFLAGS=["/DEBUG:FULL"])
else:
env.Append(CFLAGS=["/WX", "/W2"])
env["DIST_ROOT"] = Dir(f"build/dist")
env["DIST_PLATFORM"] = Dir(f"{env['DIST_ROOT']}/addons/pythonscript/{env['platform']}")
VariantDir(f"build/{env['platform']}/platforms", f"platforms")
VariantDir(f"build/{env['platform']}/pythonscript", "pythonscript")
### Load sub scons scripts ###
Export(env=env)
SConscript(
[
f"build/{env['platform']}/platforms/SConscript", # Must be kept first
f"build/{env['platform']}/pythonscript/SConscript",
"tests/SConscript",
"examples/SConscript",
]
)
### Define default target ###
env.Default(env["DIST_ROOT"])
env.Alias("build", env["DIST_ROOT"])
### Static files added to dist ###
env.VanillaInstallAs(
target="$DIST_ROOT/pythonscript.gdnlib", source="#/misc/release_pythonscript.gdnlib"
)
env.VanillaInstallAs(
target="$DIST_ROOT/addons/pythonscript/LICENSE.txt", source="#/misc/release_LICENSE.txt"
)
env.Command(target="$DIST_ROOT/addons/pythonscript/.gdignore", source=None, action=Touch("$TARGET"))
# SCons install on directory doesn't check for file changes
for item in env.Glob("addons/pythonscript_repl/*"):
env.VanillaInstall(target="$DIST_ROOT/addons/pythonscript_repl", source=item)
### Release archive ###
def generate_release(target, source, env):
for suffix, format in [(".zip", "zip"), (".tar.bz2", "bztar")]:
if target[0].name.endswith(suffix):
base_name = target[0].abspath[: -len(suffix)]
break
shutil.make_archive(base_name, format, root_dir=source[0].abspath)
# Zip format doesn't support symlinks that are needed for Linux&macOS
if env["platform"].startswith("windows"):
release_target = "build/godot-python-${release_suffix}-${platform}.zip"
else:
release_target = "build/godot-python-${release_suffix}-${platform}.tar.bz2"
release = env.Command(release_target, env["DIST_ROOT"], generate_release)
env.Alias("release", release)
env.AlwaysBuild("release")