Skip to content

Commit 03050db

Browse files
committed
Unify bits, android_arch, macos_arch ios_arch into arch, support non-x86
Unify arguments and add support for ARM64 and RV64 Linux
1 parent eaaf941 commit 03050db

File tree

8 files changed

+128
-76
lines changed

8 files changed

+128
-76
lines changed

.github/workflows/ci.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,47 +13,48 @@ jobs:
1313
os: ubuntu-18.04
1414
platform: linux
1515
artifact-name: godot-cpp-linux-glibc2.27-x86_64-release
16-
artifact-path: bin/libgodot-cpp.linux.release.64.a
16+
artifact-path: bin/libgodot-cpp.linux.release.x86_64.a
1717

1818
- name: 🐧 Linux (GCC, Double Precision)
1919
os: ubuntu-18.04
2020
platform: linux
2121
artifact-name: godot-cpp-linux-glibc2.27-x86_64-double-release
22-
artifact-path: bin/libgodot-cpp.linux.release.64.a
22+
artifact-path: bin/libgodot-cpp.linux.release.x86_64.a
2323
flags: float=64
2424

2525
- name: 🏁 Windows (x86_64, MSVC)
2626
os: windows-2019
2727
platform: windows
2828
artifact-name: godot-cpp-windows-msvc2019-x86_64-release
29-
artifact-path: bin/libgodot-cpp.windows.release.64.lib
29+
artifact-path: bin/libgodot-cpp.windows.release.x86_64.lib
3030

3131
- name: 🏁 Windows (x86_64, MinGW)
3232
os: windows-2019
3333
platform: windows
3434
artifact-name: godot-cpp-linux-mingw-x86_64-release
35-
artifact-path: bin/libgodot-cpp.windows.release.64.a
35+
artifact-path: bin/libgodot-cpp.windows.release.x86_64.a
3636
flags: use_mingw=yes
3737

3838
- name: 🍎 macOS (universal)
3939
os: macos-11
4040
platform: osx
4141
artifact-name: godot-cpp-macos-universal-release
4242
artifact-path: bin/libgodot-cpp.osx.release.universal.a
43-
flags: macos_arch=universal
43+
flags: arch=universal
4444

4545
- name: 🤖 Android (arm64)
4646
os: ubuntu-18.04
4747
platform: android
4848
artifact-name: godot-cpp-android-arm64-release
49-
artifact-path: bin/libgodot-cpp.android.release.arm64v8.a
50-
flags: android_arch=arm64v8
49+
artifact-path: bin/libgodot-cpp.android.release.arm64.a
50+
flags: arch=arm64
5151

5252
- name: 🍏 iOS (arm64)
5353
os: macos-11
5454
platform: ios
5555
artifact-name: godot-cpp-ios-arm64-release
5656
artifact-path: bin/libgodot-cpp.ios.release.arm64.a
57+
flags: arch=arm64
5758

5859
steps:
5960
- name: Checkout

SConstruct

Lines changed: 102 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python
22

33
import os
4+
import platform
45
import sys
56
import subprocess
67
from binding_generator import scons_generate_bindings, scons_emit_files
@@ -82,15 +83,6 @@ else:
8283

8384
env = Environment(ENV=os.environ)
8485

85-
is64 = sys.maxsize > 2**32
86-
if (
87-
env["TARGET_ARCH"] == "amd64"
88-
or env["TARGET_ARCH"] == "emt64"
89-
or env["TARGET_ARCH"] == "x86_64"
90-
or env["TARGET_ARCH"] == "arm64-v8a"
91-
):
92-
is64 = True
93-
9486
opts = Variables([], ARGUMENTS)
9587
opts.Add(
9688
EnumVariable(
@@ -101,7 +93,7 @@ opts.Add(
10193
ignorecase=2,
10294
)
10395
)
104-
opts.Add(EnumVariable("bits", "Target platform bits", "64" if is64 else "32", ("32", "64")))
96+
10597
opts.Add(BoolVariable("use_llvm", "Use the LLVM compiler - only effective when targeting Linux or FreeBSD", False))
10698
opts.Add(BoolVariable("use_mingw", "Use the MinGW compiler instead of MSVC - only effective on Windows", False))
10799
# Must be the same setting as used for cpp_bindings
@@ -115,11 +107,8 @@ opts.Add(PathVariable("custom_api_file", "Path to a custom JSON API file", None,
115107
opts.Add(
116108
BoolVariable("generate_bindings", "Force GDExtension API bindings generation. Auto-detected by default.", False)
117109
)
118-
opts.Add(EnumVariable("android_arch", "Target Android architecture", "armv7", ["armv7", "arm64v8", "x86", "x86_64"]))
119110
opts.Add("macos_deployment_target", "macOS deployment target", "default")
120111
opts.Add("macos_sdk_path", "macOS SDK path", "")
121-
opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "universal", ["universal", "x86_64", "arm64"]))
122-
opts.Add(EnumVariable("ios_arch", "Target iOS architecture", "arm64", ["universal", "arm64", "x86_64"]))
123112
opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
124113
opts.Add(
125114
"IPHONEPATH",
@@ -129,7 +118,7 @@ opts.Add(
129118
opts.Add(
130119
"android_api_level",
131120
"Target Android API level",
132-
"18" if ARGUMENTS.get("android_arch", "armv7") in ["armv7", "x86"] else "21",
121+
"18" if "32" in ARGUMENTS.get("arch", "arm64") else "21",
133122
)
134123
opts.Add(
135124
"ANDROID_NDK_ROOT",
@@ -141,26 +130,74 @@ opts.Add(BoolVariable("generate_template_get_node", "Generate a template version
141130
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
142131
opts.Add(EnumVariable("float", "Floating-point precision", "32", ("32", "64")))
143132

133+
# CPU architecture options.
134+
architecture_array = ["", "universal", "x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32"]
135+
architecture_aliases = {
136+
"x64": "x86_64",
137+
"amd64": "x86_64",
138+
"armv7": "arm32",
139+
"armv8": "arm64",
140+
"arm64v8": "arm64",
141+
"aarch64": "arm64",
142+
"rv": "rv64",
143+
"riscv": "rv64",
144+
"riscv64": "rv64",
145+
"ppcle": "ppc32",
146+
"ppc": "ppc32",
147+
"ppc64le": "ppc64",
148+
}
149+
opts.Add(EnumVariable("arch", "CPU architecture", "", architecture_array, architecture_aliases))
150+
144151
opts.Update(env)
145152
Help(opts.GenerateHelpText(env))
146153

154+
# Process CPU architecture argument.
155+
if env["arch"] == "":
156+
# No architecture specified. Default to arm64 if building for Android,
157+
# universal if building for macOS or iOS, wasm32 if building for web,
158+
# otherwise default to the host architecture.
159+
if env["platform"] in ["osx", "ios"]:
160+
env["arch"] = "universal"
161+
elif env["platform"] == "android":
162+
env["arch"] = "arm64"
163+
elif env["platform"] == "javascript":
164+
env["arch"] = "wasm32"
165+
else:
166+
host_machine = platform.machine().lower()
167+
if host_machine in architecture_array:
168+
env["arch"] = host_machine
169+
elif host_machine in architecture_aliases.keys():
170+
env["arch"] = architecture_aliases[host_machine]
171+
elif "86" in host_machine:
172+
# Catches x86, i386, i486, i586, i686, etc.
173+
env["arch"] = "x86_32"
174+
else:
175+
print("Unsupported CPU architecture: " + host_machine)
176+
Exit()
177+
178+
# We use this to re-set env["arch"] anytime we call opts.Update(env).
179+
env_arch = env["arch"]
180+
147181
# Detect and print a warning listing unknown SCons variables to ease troubleshooting.
148182
unknown = opts.UnknownVariables()
149183
if unknown:
150184
print("WARNING: Unknown SCons variables were passed and will be ignored:")
151185
for item in unknown.items():
152186
print(" " + item[0] + "=" + item[1])
153187

188+
print("Building for architecture " + env["arch"] + " on platform " + env["platform"])
189+
154190
# This makes sure to keep the session environment variables on Windows.
155191
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
156192
# all the required tools
157193
if host_platform == "windows" and env["platform"] != "android":
158-
if env["bits"] == "64":
194+
if env["arch"] == "x86_64":
159195
env = Environment(TARGET_ARCH="amd64")
160-
elif env["bits"] == "32":
196+
elif env["arch"] == "x86_32":
161197
env = Environment(TARGET_ARCH="x86")
162198

163199
opts.Update(env)
200+
env["arch"] = env_arch
164201

165202
# Require C++17
166203
if host_platform == "windows" and env["platform"] == "windows" and not env["use_mingw"]:
@@ -187,26 +224,35 @@ if env["platform"] == "linux" or env["platform"] == "freebsd":
187224
elif env["target"] == "release":
188225
env.Append(CCFLAGS=["-O3"])
189226

190-
if env["bits"] == "64":
191-
env.Append(CCFLAGS=["-m64"])
192-
env.Append(LINKFLAGS=["-m64"])
193-
elif env["bits"] == "32":
194-
env.Append(CCFLAGS=["-m32"])
195-
env.Append(LINKFLAGS=["-m32"])
227+
if env["arch"] == "x86_64":
228+
# -m64 and -m32 are x86-specific already, but it doesn't hurt to
229+
# be clear and also specify -march=x86_64. Similar with 32-bit.
230+
env.Append(CCFLAGS=["-m64", "-march=x86-64"])
231+
env.Append(LINKFLAGS=["-m64", "-march=x86-64"])
232+
elif env["arch"] == "x86_32":
233+
env.Append(CCFLAGS=["-m32", "-march=i686"])
234+
env.Append(LINKFLAGS=["-m32", "-march=i686"])
235+
elif env_arch == "arm64":
236+
env.Append(CCFLAGS=["-march=armv8-a"])
237+
env.Append(LINKFLAGS=["-march=armv8-a"])
238+
elif env_arch == "rv64":
239+
env.Append(CCFLAGS=["-march=rv64gc"])
240+
env.Append(LINKFLAGS=["-march=rv64gc"])
196241

197242
elif env["platform"] == "osx":
243+
if env["arch"] not in ("universal", "arm64", "x86_64"):
244+
print("Only universal, arm64, and x86_64 are supported on macOS. Exiting.")
245+
Exit()
246+
198247
# Use Clang on macOS by default
199248
env["CXX"] = "clang++"
200249

201-
if env["bits"] == "32":
202-
raise ValueError("Only 64-bit builds are supported for the macOS target.")
203-
204-
if env["macos_arch"] == "universal":
250+
if env["arch"] == "universal":
205251
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
206252
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
207253
else:
208-
env.Append(LINKFLAGS=["-arch", env["macos_arch"]])
209-
env.Append(CCFLAGS=["-arch", env["macos_arch"]])
254+
env.Append(LINKFLAGS=["-arch", env["arch"]])
255+
env.Append(CCFLAGS=["-arch", env["arch"]])
210256

211257
if env["macos_deployment_target"] != "default":
212258
env.Append(CCFLAGS=["-mmacosx-version-min=" + env["macos_deployment_target"]])
@@ -230,6 +276,10 @@ elif env["platform"] == "osx":
230276
env.Append(CCFLAGS=["-O3"])
231277

232278
elif env["platform"] == "ios":
279+
if env["arch"] not in ("universal", "arm64", "x86_64"):
280+
print("Only universal, arm64, and x86_64 are supported on iOS. Exiting.")
281+
Exit()
282+
233283
if env["ios_simulator"]:
234284
sdk_name = "iphonesimulator"
235285
env.Append(CCFLAGS=["-mios-simulator-version-min=10.0"])
@@ -251,16 +301,16 @@ elif env["platform"] == "ios":
251301
env["RANLIB"] = compiler_path + "ranlib"
252302
env["SHLIBSUFFIX"] = ".dylib"
253303

254-
if env["ios_arch"] == "universal":
304+
if env["arch"] == "universal":
255305
if env["ios_simulator"]:
256306
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
257307
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
258308
else:
259309
env.Append(LINKFLAGS=["-arch", "arm64"])
260310
env.Append(CCFLAGS=["-arch", "arm64"])
261311
else:
262-
env.Append(LINKFLAGS=["-arch", env["ios_arch"]])
263-
env.Append(CCFLAGS=["-arch", env["ios_arch"]])
312+
env.Append(LINKFLAGS=["-arch", env["arch"]])
313+
env.Append(CCFLAGS=["-arch", env["arch"]])
264314

265315
env.Append(CCFLAGS=["-isysroot", sdk_path])
266316
env.Append(LINKFLAGS=["-isysroot", sdk_path, "-F" + sdk_path])
@@ -282,12 +332,12 @@ elif env["platform"] == "windows":
282332

283333
elif host_platform == "linux" or host_platform == "freebsd" or host_platform == "osx":
284334
# Cross-compilation using MinGW
285-
if env["bits"] == "64":
335+
if env["arch"] == "x86_64":
286336
env["CXX"] = "x86_64-w64-mingw32-g++"
287337
env["AR"] = "x86_64-w64-mingw32-ar"
288338
env["RANLIB"] = "x86_64-w64-mingw32-ranlib"
289339
env["LINK"] = "x86_64-w64-mingw32-g++"
290-
elif env["bits"] == "32":
340+
elif env["arch"] == "x86_32":
291341
env["CXX"] = "i686-w64-mingw32-g++"
292342
env["AR"] = "i686-w64-mingw32-ar"
293343
env["RANLIB"] = "i686-w64-mingw32-ranlib"
@@ -297,6 +347,7 @@ elif env["platform"] == "windows":
297347
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
298348
env = Environment(ENV=os.environ, tools=["mingw"])
299349
opts.Update(env)
350+
env["arch"] = env_arch
300351

301352
# Still need to use C++17.
302353
env.Append(CCFLAGS=["-std=c++17"])
@@ -322,10 +373,15 @@ elif env["platform"] == "windows":
322373
)
323374

324375
elif env["platform"] == "android":
376+
if env["arch"] not in ("arm64", "x86_64", "arm32", "x86_32"):
377+
print("Only arm64, x86_64, arm32, and x86_32 are supported on Android. Exiting.")
378+
Exit()
379+
325380
if host_platform == "windows":
326381
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
327382
env = Environment(ENV=os.environ, tools=["mingw"])
328383
opts.Update(env)
384+
env["arch"] = env_arch
329385

330386
# Long line hack. Use custom spawn, quick AR append (to avoid files with the same names to override each other).
331387
env["SPAWN"] = mySpawn
@@ -339,7 +395,7 @@ elif env["platform"] == "android":
339395

340396
# Validate API level
341397
api_level = int(env["android_api_level"])
342-
if env["android_arch"] in ["x86_64", "arm64v8"] and api_level < 21:
398+
if "64" in env["arch"] and api_level < 21:
343399
print("WARN: 64-bit Android architectures require an API level of at least 21; setting android_api_level=21")
344400
env["android_api_level"] = "21"
345401
api_level = 21
@@ -360,21 +416,21 @@ elif env["platform"] == "android":
360416

361417
# Get architecture info
362418
arch_info_table = {
363-
"armv7": {
419+
"arm32": {
364420
"march": "armv7-a",
365421
"target": "armv7a-linux-androideabi",
366422
"tool_path": "arm-linux-androideabi",
367423
"compiler_path": "armv7a-linux-androideabi",
368424
"ccflags": ["-mfpu=neon"],
369425
},
370-
"arm64v8": {
426+
"arm64": {
371427
"march": "armv8-a",
372428
"target": "aarch64-linux-android",
373429
"tool_path": "aarch64-linux-android",
374430
"compiler_path": "aarch64-linux-android",
375431
"ccflags": [],
376432
},
377-
"x86": {
433+
"x86_32": {
378434
"march": "i686",
379435
"target": "i686-linux-android",
380436
"tool_path": "i686-linux-android",
@@ -389,7 +445,7 @@ elif env["platform"] == "android":
389445
"ccflags": [],
390446
},
391447
}
392-
arch_info = arch_info_table[env["android_arch"]]
448+
arch_info = arch_info_table[env["arch"]]
393449

394450
# Setup tools
395451
env["CC"] = toolchain + "/bin/clang"
@@ -409,9 +465,14 @@ elif env["platform"] == "android":
409465
env.Append(CCFLAGS=["-O3"])
410466

411467
elif env["platform"] == "javascript":
468+
if env["arch"] not in ("wasm32"):
469+
print("Only wasm32 supported on web. Exiting.")
470+
Exit()
471+
412472
if host_platform == "windows":
413473
env = Environment(ENV=os.environ, tools=["cc", "c++", "ar", "link", "textfile", "zip"])
414474
opts.Update(env)
475+
env["arch"] = env_arch
415476
else:
416477
env["ENV"] = os.environ
417478

@@ -474,17 +535,9 @@ add_sources(sources, "src/core", "cpp")
474535
add_sources(sources, "src/variant", "cpp")
475536
sources.extend([f for f in bindings if str(f).endswith(".cpp")])
476537

477-
env["arch_suffix"] = env["bits"]
478-
if env["platform"] == "android":
479-
env["arch_suffix"] = env["android_arch"]
480-
elif env["platform"] == "ios":
481-
env["arch_suffix"] = env["ios_arch"]
482-
if env["ios_simulator"]:
483-
env["arch_suffix"] += ".simulator"
484-
elif env["platform"] == "javascript":
485-
env["arch_suffix"] = "wasm"
486-
elif env["platform"] == "osx":
487-
env["arch_suffix"] = env["macos_arch"]
538+
env["arch_suffix"] = env["arch"]
539+
if env["ios_simulator"]:
540+
env["arch_suffix"] += ".simulator"
488541

489542
library = None
490543
env["OBJSUFFIX"] = ".{}.{}.{}{}".format(env["platform"], env["target"], env["arch_suffix"], env["OBJSUFFIX"])

binding_generator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def scons_generate_bindings(target, source, env):
6767
generate_bindings(
6868
str(source[0]),
6969
env["generate_template_get_node"],
70-
env["bits"],
70+
"32" if "32" in env["arch"] else "64",
7171
"double" if (env["float"] == "64") else "float",
7272
target[0].abspath,
7373
)

0 commit comments

Comments
 (0)