Skip to content

Commit

Permalink
Unify bits, android_arch, macos_arch ios_arch into arch, support non-x86
Browse files Browse the repository at this point in the history
Unify arguments and add support for ARM64 and RV64 Linux
  • Loading branch information
aaronfranke committed Feb 27, 2022
1 parent 2eedcb0 commit 1b74ca6
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 183 deletions.
26 changes: 13 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,27 @@ jobs:
sudo apt-get update -qq
sudo apt-get install -qqq build-essential pkg-config
python -m pip install scons
curl -LO https://downloads.tuxfamily.org/godotengine/3.4/Godot_v3.4-stable_linux_server.64.zip
unzip Godot_v3.4-stable_linux_server.64.zip
curl -LO https://downloads.tuxfamily.org/godotengine/3.5/beta1/Godot_v3.5-beta1_linux_server.64.zip
unzip Godot_v3.5-beta1_linux_server.64.zip
- name: Build godot-cpp
run: |
scons target=release generate_bindings=yes -j $(nproc)
scons target=release platform=linux arch=x86_64 generate_bindings=yes -j $(nproc)
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: godot-cpp-linux-glibc2.27-x86_64-release
path: bin/libgodot-cpp.linux.release.64.a
path: bin/libgodot-cpp.linux.release.x86_64.a
if-no-files-found: error

- name: Build test GDNative library
run: |
scons target=release platform=linux bits=64 -j $(nproc) -C test
scons target=release platform=linux arch=x86_64 -j $(nproc) -C test
- name: Run test GDNative library
run: |
./Godot_v3.4-stable_linux_server.64 --path test -s script.gd
./Godot_v3.5-beta1_linux_server.64 --path test -s script.gd
windows-msvc:
name: Build (Windows, MSVC)
Expand Down Expand Up @@ -69,7 +69,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: godot-cpp-windows-msvc2019-x86_64-release
path: bin/libgodot-cpp.windows.release.64.lib
path: bin/libgodot-cpp.windows.release.x86_64.lib
if-no-files-found: error

windows-mingw:
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: godot-cpp-linux-mingw-x86_64-release
path: bin/libgodot-cpp.windows.release.64.a
path: bin/libgodot-cpp.windows.release.x86_64.a
if-no-files-found: error

macos:
Expand All @@ -123,23 +123,23 @@ jobs:
- name: Install dependencies
run: |
python -m pip install scons
curl -LO https://downloads.tuxfamily.org/godotengine/3.4/Godot_v3.4-stable_osx.universal.zip
unzip Godot_v3.4-stable_osx.universal.zip
curl -LO https://downloads.tuxfamily.org/godotengine/3.5/beta1/Godot_v3.5-beta1_osx.universal.zip
unzip Godot_v3.5-beta1_osx.universal.zip
- name: Build godot-cpp
run: |
scons target=release generate_bindings=yes -j $(sysctl -n hw.logicalcpu)
scons target=release platform=osx arch=universal -j $(sysctl -n hw.logicalcpu) generate_bindings=yes
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: godot-cpp-macos-universal-release
path: bin/libgodot-cpp.osx.release.64.a
path: bin/libgodot-cpp.osx.release.universal.a
if-no-files-found: error

- name: Build test GDNative library
run: |
scons target=release platform=osx bits=64 macos_arch=universal -j $(sysctl -n hw.logicalcpu) -C test
scons target=release platform=osx arch=universal -j $(sysctl -n hw.logicalcpu) -C test
- name: Run test GDNative library
run: |
Expand Down
146 changes: 88 additions & 58 deletions SConstruct
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python

import os
import platform
import sys
import subprocess

Expand All @@ -9,6 +10,7 @@ if sys.version_info < (3,):
def decode_utf8(x):
return x


else:
import codecs

Expand Down Expand Up @@ -81,15 +83,6 @@ else:

env = Environment(ENV=os.environ)

is64 = sys.maxsize > 2 ** 32
if (
env["TARGET_ARCH"] == "amd64"
or env["TARGET_ARCH"] == "emt64"
or env["TARGET_ARCH"] == "x86_64"
or env["TARGET_ARCH"] == "arm64-v8a"
):
is64 = True

opts = Variables([], ARGUMENTS)
opts.Add(
EnumVariable(
Expand All @@ -100,7 +93,6 @@ opts.Add(
ignorecase=2,
)
)
opts.Add(EnumVariable("bits", "Target platform bits", "64" if is64 else "32", ("32", "64")))
opts.Add(BoolVariable("use_llvm", "Use the LLVM compiler - only effective when targeting Linux or FreeBSD", False))
opts.Add(BoolVariable("use_mingw", "Use the MinGW compiler instead of MSVC - only effective on Windows", False))
# Must be the same setting as used for cpp_bindings
Expand All @@ -123,18 +115,8 @@ opts.Add(
ignorecase=2,
)
)
opts.Add(
EnumVariable(
"android_arch",
"Target Android architecture",
"armv7",
["armv7", "arm64v8", "x86", "x86_64"],
)
)
opts.Add("macos_deployment_target", "macOS deployment target", "default")
opts.Add("macos_sdk_path", "macOS SDK path", "")
opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "universal", ["universal", "x86_64", "arm64"]))
opts.Add(EnumVariable("ios_arch", "Target iOS architecture", "arm64", ["armv7", "arm64", "x86_64"]))
opts.Add(BoolVariable("ios_simulator", "Target iOS Simulator", False))
opts.Add(
"IPHONEPATH",
Expand All @@ -144,7 +126,7 @@ opts.Add(
opts.Add(
"android_api_level",
"Target Android API level",
"18" if ARGUMENTS.get("android_arch", "armv7") in ["armv7", "x86"] else "21",
"18" if "32" in ARGUMENTS.get("arch", "arm32") else "21",
)
opts.Add(
"ANDROID_NDK_ROOT",
Expand All @@ -159,19 +141,64 @@ opts.Add(
)
)

# CPU architecture options.
architecture_array = ["", "universal", "x86_32", "x86_64", "arm32", "arm64", "rv64", "ppc32", "ppc64", "wasm32"]
architecture_aliases = {
"x64": "x86_64",
"amd64": "x86_64",
"armv7": "arm32",
"armv8": "arm64",
"arm64v8": "arm64",
"aarch64": "arm64",
"rv": "rv64",
"riscv": "rv64",
"riscv64": "rv64",
"ppcle": "ppc32",
"ppc": "ppc32",
"ppc64le": "ppc64",
}
opts.Add(EnumVariable("arch", "CPU architecture", "", architecture_array, architecture_aliases))

opts.Update(env)
Help(opts.GenerateHelpText(env))

# Process CPU architecture argument.
if env["arch"] == "":
# No architecture specified. Default to universal if building for macOS,
# arm64 if building for mobile, wasm32 if building for web,
# otherwise default to the host architecture.
if env["platform"] == "osx":
env["arch"] = "universal"
elif env["platform"] in ["android", "ios"]:
env["arch"] = "arm64"
elif env["platform"] == "javascript":
env["arch"] = "wasm32"
else:
host_machine = platform.machine().lower()
if host_machine in architecture_array:
env["arch"] = host_machine
elif host_machine in architecture_aliases.keys():
env["arch"] = architecture_aliases[host_machine]
elif "86" in host_machine:
# Catches x86, i386, i486, i586, i686, etc.
env["arch"] = "x86_32"
else:
print("Unsupported CPU architecture: " + host_machine)
Exit()

env_arch = env["arch"]

# This makes sure to keep the session environment variables on Windows.
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
# all the required tools
if host_platform == "windows" and env["platform"] != "android":
if env["bits"] == "64":
if env["arch"] == "x86_64":
env = Environment(TARGET_ARCH="amd64")
elif env["bits"] == "32":
elif env["arch"] == "x86_32":
env = Environment(TARGET_ARCH="x86")

opts.Update(env)
env["arch"] = env_arch

if env["platform"] == "linux" or env["platform"] == "freebsd":
if env["use_llvm"]:
Expand All @@ -185,26 +212,33 @@ if env["platform"] == "linux" or env["platform"] == "freebsd":
elif env["target"] == "release":
env.Append(CCFLAGS=["-O3"])

if env["bits"] == "64":
env.Append(CCFLAGS=["-m64"])
env.Append(LINKFLAGS=["-m64"])
elif env["bits"] == "32":
env.Append(CCFLAGS=["-m32"])
env.Append(LINKFLAGS=["-m32"])
if env_arch == "x86_64":
env.Append(CCFLAGS=["-m64", "-march=x86-64"])
env.Append(LINKFLAGS=["-m64", "-march=x86-64"])
elif env_arch == "x86_32":
env.Append(CCFLAGS=["-m32", "-march=i686"])
env.Append(LINKFLAGS=["-m32", "-march=i686"])
elif env_arch == "arm64":
env.Append(CCFLAGS=["-march=armv8-a"])
env.Append(LINKFLAGS=["-march=armv8-a"])
elif env_arch == "rv64":
env.Append(CCFLAGS=["-march=rv64gc"])
env.Append(LINKFLAGS=["-march=rv64gc"])

elif env["platform"] == "osx":
# Use Clang on macOS by default
env["CXX"] = "clang++"

if env["bits"] == "32":
raise ValueError("Only 64-bit builds are supported for the macOS target.")
if env["arch"] not in ("universal", "x86_64", "arm64"):
print("Only universal, x86_64, and arm64 are supported on macOS. Exiting.")
Exit()

if env["macos_arch"] == "universal":
if env["arch"] == "universal":
env.Append(LINKFLAGS=["-arch", "x86_64", "-arch", "arm64"])
env.Append(CCFLAGS=["-arch", "x86_64", "-arch", "arm64"])
else:
env.Append(LINKFLAGS=["-arch", env["macos_arch"]])
env.Append(CCFLAGS=["-arch", env["macos_arch"]])
env.Append(LINKFLAGS=["-arch", env["arch"]])
env.Append(CCFLAGS=["-arch", env["arch"]])

env.Append(CCFLAGS=["-std=c++14"])

Expand Down Expand Up @@ -251,11 +285,15 @@ elif env["platform"] == "ios":
env["AR"] = compiler_path + "ar"
env["RANLIB"] = compiler_path + "ranlib"

env.Append(CCFLAGS=["-std=c++14", "-arch", env["ios_arch"], "-isysroot", sdk_path])
if env["arch"] == "arm32":
env.Append(CCFLAGS=["-arch", "armv7"])
env.Append(LINKFLAGS=["-arch", "armv7"])
else:
env.Append(CCFLAGS=["-arch", env["arch"]])
env.Append(LINKFLAGS=["-arch", env["arch"]])
env.Append(CCFLAGS=["-std=c++14", "-isysroot", sdk_path])
env.Append(
LINKFLAGS=[
"-arch",
env["ios_arch"],
"-framework",
"Cocoa",
"-Wl,-undefined,dynamic_lookup",
Expand All @@ -281,12 +319,12 @@ elif env["platform"] == "windows":

elif host_platform == "linux" or host_platform == "freebsd" or host_platform == "osx":
# Cross-compilation using MinGW
if env["bits"] == "64":
if env["arch"] == "x86_64":
env["CXX"] = "x86_64-w64-mingw32-g++"
env["AR"] = "x86_64-w64-mingw32-ar"
env["RANLIB"] = "x86_64-w64-mingw32-ranlib"
env["LINK"] = "x86_64-w64-mingw32-g++"
elif env["bits"] == "32":
elif env["arch"] == "x86_32":
env["CXX"] = "i686-w64-mingw32-g++"
env["AR"] = "i686-w64-mingw32-ar"
env["RANLIB"] = "i686-w64-mingw32-ranlib"
Expand All @@ -296,6 +334,7 @@ elif env["platform"] == "windows":
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
env = Environment(ENV=os.environ, tools=["mingw"])
opts.Update(env)
env["arch"] = env_arch
# env = env.Clone(tools=['mingw'])

env["SPAWN"] = mySpawn
Expand All @@ -318,6 +357,7 @@ elif env["platform"] == "android":
# Don't Clone the environment. Because otherwise, SCons will pick up msvc stuff.
env = Environment(ENV=os.environ, tools=["mingw"])
opts.Update(env)
env["arch"] = env_arch
# env = env.Clone(tools=['mingw'])

env["SPAWN"] = mySpawn
Expand All @@ -330,7 +370,7 @@ elif env["platform"] == "android":

# Validate API level
api_level = int(env["android_api_level"])
if env["android_arch"] in ["x86_64", "arm64v8"] and api_level < 21:
if "64" in env["arch"] and api_level < 21:
print("WARN: 64-bit Android architectures require an API level of at least 21; setting android_api_level=21")
env["android_api_level"] = "21"
api_level = 21
Expand All @@ -339,9 +379,7 @@ elif env["platform"] == "android":
toolchain = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/"
if host_platform == "windows":
toolchain += "windows"
import platform as pltfm

if pltfm.machine().endswith("64"):
if platform.machine().endswith("64"):
toolchain += "-x86_64"
elif host_platform == "linux":
toolchain += "linux-x86_64"
Expand All @@ -351,21 +389,21 @@ elif env["platform"] == "android":

# Get architecture info
arch_info_table = {
"armv7": {
"arm32": {
"march": "armv7-a",
"target": "armv7a-linux-androideabi",
"tool_path": "arm-linux-androideabi",
"compiler_path": "armv7a-linux-androideabi",
"ccflags": ["-mfpu=neon"],
},
"arm64v8": {
"arm64": {
"march": "armv8-a",
"target": "aarch64-linux-android",
"tool_path": "aarch64-linux-android",
"compiler_path": "aarch64-linux-android",
"ccflags": [],
},
"x86": {
"x86_32": {
"march": "i686",
"target": "i686-linux-android",
"tool_path": "i686-linux-android",
Expand All @@ -380,7 +418,7 @@ elif env["platform"] == "android":
"ccflags": [],
},
}
arch_info = arch_info_table[env["android_arch"]]
arch_info = arch_info_table[env["arch"]]

# Setup tools
env["CC"] = toolchain + "/bin/clang"
Expand All @@ -406,6 +444,7 @@ elif env["platform"] == "android":
env.Append(CCFLAGS=["-O3"])

elif env["platform"] == "javascript":
env["arch"] = "wasm32"
env["ENV"] = os.environ
env["CC"] = "emcc"
env["CXX"] = "em++"
Expand All @@ -414,7 +453,7 @@ elif env["platform"] == "javascript":
env.Append(CPPFLAGS=["-s", "SIDE_MODULE=1"])
env.Append(LINKFLAGS=["-s", "SIDE_MODULE=1"])
env["SHOBJSUFFIX"] = ".bc"
env["SHLIBSUFFIX"] = ".wasm"
env["SHLIBSUFFIX"] = ".wasm32"
# Use TempFileMunge since some AR invocations are too long for cmd.exe.
# Use POSIX-style paths, required with TempFileMunge.
env["ARCOM_POSIX"] = env["ARCOM"].replace("$TARGET", "$TARGET.posix").replace("$SOURCES", "$SOURCES.posix")
Expand Down Expand Up @@ -473,16 +512,7 @@ sources = []
add_sources(sources, "src/core", "cpp")
add_sources(sources, "src/gen", "cpp")

arch_suffix = env["bits"]
if env["platform"] == "android":
arch_suffix = env["android_arch"]
elif env["platform"] == "ios":
arch_suffix = env["ios_arch"]
elif env["platform"] == "osx":
if env["macos_arch"] != "universal":
arch_suffix = env["macos_arch"]
elif env["platform"] == "javascript":
arch_suffix = "wasm"
arch_suffix = env["arch"]

library = env.StaticLibrary(
target="bin/" + "libgodot-cpp.{}.{}.{}{}".format(env["platform"], env["target"], arch_suffix, env["LIBSUFFIX"]),
Expand Down
Loading

0 comments on commit 1b74ca6

Please sign in to comment.