summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorFabio Alessandrelli <fabio.alessandrelli@gmail.com>2023-06-19 04:58:03 +0200
committerFabio Alessandrelli <fabio.alessandrelli@gmail.com>2023-06-20 13:22:07 +0200
commit86c27ec7efa5b4630ddeff50d02b0deda2ad3db3 (patch)
tree1d00228bde064a94d7cb9c33d74831ccc0383c14 /tools
parentf2ee596bd9a67512f69d170cbcd260e6422e97a9 (diff)
downloadfork-godot-webrtc-native-86c27ec7efa5b4630ddeff50d02b0deda2ad3db3.tar.gz
fork-godot-webrtc-native-86c27ec7efa5b4630ddeff50d02b0deda2ad3db3.tar.bz2
fork-godot-webrtc-native-86c27ec7efa5b4630ddeff50d02b0deda2ad3db3.zip
[SCons] Refactor CMake and OpenSSL tools to use actions.
Improve build reliability, allow for more customization.
Diffstat (limited to 'tools')
-rw-r--r--tools/cmake.py91
-rw-r--r--tools/openssl.py223
-rw-r--r--tools/rtc.py41
3 files changed, 186 insertions, 169 deletions
diff --git a/tools/cmake.py b/tools/cmake.py
index 5b05d15..28e1269 100644
--- a/tools/cmake.py
+++ b/tools/cmake.py
@@ -1,47 +1,14 @@
import os, sys
-
-def exists(env):
- return True
-
-
-def generate(env):
- env.AddMethod(cmake_configure, "CMakeConfigure")
- env.AddMethod(cmake_build, "CMakeBuild")
- env.AddMethod(cmake_platform_flags, "CMakePlatformFlags")
-
-
-def cmake_configure(env, source, target, opt_args):
- args = [
- "-B",
- target,
- ]
-
- if env["platform"] == "windows":
- if env.get("is_msvc", False):
- args.extend(["-G", "NMake Makefiles"])
- elif sys.platform in ["win32", "msys", "cygwin"]:
- args.extend(["-G", "Ninja"])
- else:
- args.extend(["-G", "Unix Makefiles"])
-
- for arg in opt_args:
- args.append(arg)
- args.append(source)
- return env.Execute("cmake " + " ".join(['"%s"' % a for a in args]))
-
-
-def cmake_build(env, source, target="", opt_args=[]):
- jobs = env.GetOption("num_jobs")
- return env.Execute(
- "cmake --build %s %s -j%s %s"
- % (source, "-t %s" % target if target else "", jobs, " ".join(['"%s"' % a for a in opt_args]))
- )
+import SCons.Util
+import SCons.Builder
+import SCons.Action
-def cmake_platform_flags(env, config=None):
- if config is None:
- config = {}
+def cmake_platform_config(env):
+ config = {
+ "CMAKE_BUILD_TYPE": env["CMAKEBUILDTYPE"],
+ }
if "CC" in env:
config["CMAKE_C_COMPILER"] = env["CC"]
@@ -60,8 +27,8 @@ def cmake_platform_flags(env, config=None):
config["CMAKE_SYSTEM_VERSION"] = api
config["CMAKE_ANDROID_ARCH_ABI"] = abi
config["ANDROID_ABI"] = abi
- config["CMAKE_TOOLCHAIN_FILE"] = "%s/build/cmake/android.toolchain.cmake" % os.environ.get(
- "ANDROID_NDK_ROOT", ""
+ config["CMAKE_TOOLCHAIN_FILE"] = "%s/build/cmake/android.toolchain.cmake" % env.get(
+ "ANDROID_NDK_ROOT", os.environ.get("ANDROID_NDK_ROOT", "")
)
config["CMAKE_ANDROID_STL_TYPE"] = "c++_static"
@@ -95,7 +62,7 @@ def cmake_platform_flags(env, config=None):
raise ValueError("iOS architecture not supported: %s" % env["arch"])
config["CMAKE_SYSTEM_NAME"] = "iOS"
config["CMAKE_OSX_ARCHITECTURES"] = env["arch"]
- if env["ios_min_version"] != "default":
+ if env.get("ios_min_version", "default") != "default":
config["CMAKE_OSX_DEPLOYMENT_TARGET"] = env["ios_min_version"]
if env["ios_simulator"]:
config["CMAKE_OSX_SYSROOT"] = "iphonesimulator"
@@ -103,4 +70,40 @@ def cmake_platform_flags(env, config=None):
elif env["platform"] == "windows":
config["CMAKE_SYSTEM_NAME"] = "Windows"
- return config
+ flags = ["'-D%s=%s'" % it for it in config.items()]
+ if env["CMAKEGENERATOR"]:
+ flags.extend(["-G", env["CMAKEGENERATOR"]])
+ elif env["platform"] == "windows":
+ if env.get("is_msvc", False):
+ flags.extend(["-G", "NMake Makefiles"])
+ elif sys.platform in ["win32", "msys", "cygwin"]:
+ flags.extend(["-G", "Ninja"])
+ else:
+ flags.extend(["-G", "Unix Makefiles"])
+ return flags
+
+
+def cmake_emitter(target, source, env):
+ return [str(target[0]) + "/CMakeCache.txt"] + target[1:], [str(source[0]) + "/CMakeLists.txt"] + source[1:]
+
+
+cmake_configure_action = SCons.Action.Action("$CMAKECONFCOM", "$CMAKECONFCOMSTR")
+cmake_build_action = SCons.Action.Action("$CMAKEBUILDCOM", "$CMAKEBUILDCOMSTR")
+cmake_builder = SCons.Builder.Builder(action=[cmake_configure_action, cmake_build_action], emitter=cmake_emitter)
+
+
+def exists(env):
+ return True
+
+
+def generate(env):
+ env["CMAKE"] = "cmake"
+ env["_cmake_platform_config"] = cmake_platform_config
+ env["CMAKEPLATFORMCONFIG"] = "${_cmake_platform_config(__env__)}"
+ env["CMAKEBUILDTYPE"] = "Release"
+ env["CMAKEGENERATOR"] = ""
+ env["CMAKECONFFLAGS"] = SCons.Util.CLVar("")
+ env["CMAKECONFCOM"] = "$CMAKE -B ${TARGET.dir} $CMAKEPLATFORMCONFIG $CMAKECONFFLAGS ${SOURCE.dir}"
+ env["CMAKEBUILDFLAGS"] = SCons.Util.CLVar("")
+ env["CMAKEBUILDCOM"] = "$CMAKE --build ${TARGET.dir} $CMAKEBUILDFLAGS"
+ env["BUILDERS"]["CMake"] = cmake_builder
diff --git a/tools/openssl.py b/tools/openssl.py
index ad61df9..936895d 100644
--- a/tools/openssl.py
+++ b/tools/openssl.py
@@ -1,117 +1,106 @@
import os, sys
+import SCons.Util
+import SCons.Builder
+import SCons.Action
from SCons.Defaults import Mkdir
from SCons.Variables import PathVariable, BoolVariable
-def ssl_emitter(target, source, env):
- env.Depends(env["SSL_LIBS"], env.File(__file__))
- return env["SSL_LIBS"], [env.Dir(env["SSL_SOURCE"]), env.File(env["SSL_SOURCE"] + "/VERSION.dat")]
+def ssl_platform_target(env):
+ targets = {}
+ platform = env["platform"]
+ if platform == "linux":
+ targets = {
+ "x86_32": "linux-x86",
+ "x86_64": "linux-x86_64",
+ }
+ elif platform == "android":
+ targets = {
+ "arm64": "android-arm64",
+ "arm32": "android-arm",
+ "x86_32": "android-x86",
+ "x86_64": "android-x86_64",
+ }
+ elif platform == "macos":
+ targets = {
+ "x86_64": "darwin64-x86_64",
+ "arm64": "darwin64-arm64",
+ }
+ elif platform == "ios":
+ if env["ios_simulator"]:
+ targets = {
+ "x86_64": "iossimulator-xcrun",
+ "arm64": "iossimulator-xcrun",
+ }
+ else:
+ targets = {
+ "arm64": "ios64-xcrun",
+ "arm32": "ios-xcrun",
+ }
+ elif platform == "windows":
+ if env.get("is_msvc", False):
+ targets = {
+ "x86_32": "VC-WIN32",
+ "x86_64": "VC-WIN64A",
+ }
+ else:
+ targets = {
+ "x86_32": "mingw",
+ "x86_64": "mingw64",
+ }
+ arch = env["arch"]
+ target = targets.get(arch, "")
+ if target == "":
+ raise ValueError("Architecture '%s' not supported for platform: '%s'" % (arch, platform))
+ return target
-def ssl_action(target, source, env):
- build_dir = env["SSL_BUILD"]
- source_dir = env["SSL_SOURCE"]
- install_dir = env["SSL_INSTALL"]
- ssl_env = env.Clone()
- args = [
+def ssl_default_options(env):
+ ssl_config_options = [
"no-ssl2",
"no-ssl3",
"no-weak-ssl-ciphers",
"no-legacy",
"no-shared",
"no-tests",
- "--prefix=%s" % install_dir,
- "--openssldir=%s" % install_dir,
]
- if env["openssl_debug"]:
- args.append("-d")
+ if env["platform"] == "windows":
+ ssl_config_options.append("enable-capieng")
+ return ssl_config_options
- if env["platform"] == "linux":
- if env["arch"] == "x86_32":
- args.extend(["linux-x86"])
- else:
- args.extend(["linux-x86_64"])
-
- elif env["platform"] == "android":
- api = env["android_api_level"] if int(env["android_api_level"]) > 28 else "28"
- args.extend(
- [
- {
- "arm64": "android-arm64",
- "arm32": "android-arm",
- "x86_32": "android-x86",
- "x86_64": "android-x86_64",
- }[env["arch"]],
- "-D__ANDROID_API__=%s" % api,
- ]
- )
- # Setup toolchain path.
- ssl_env.PrependENVPath("PATH", os.path.dirname(env["CC"]))
- ssl_env["ENV"]["ANDROID_NDK_ROOT"] = os.environ.get("ANDROID_NDK_ROOT", "")
+def ssl_platform_config(env):
+ opts = ssl_default_options(env)
+ target = ssl_platform_target(env)
+ args = []
+ if env["platform"] == "android" and env.get("android_api_level", ""):
+ api = int(env["android_api_level"])
+ args.append("-D__ANDROID_API__=%s" % api)
elif env["platform"] == "macos":
- if env["arch"] == "x86_64":
- args.extend(["darwin64-x86_64"])
- elif env["arch"] == "arm64":
- args.extend(["darwin64-arm64"])
- else:
- raise ValueError("macOS architecture not supported: %s" % env["arch"])
-
+ # OSXCross toolchain setup.
if sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ:
- args.extend(
- [
- "CC=" + env["CC"],
- "CXX=" + env["CXX"],
- "AR=" + env["AR"],
- "AS=" + env["AS"],
- "RANLIB=" + env["RANLIB"],
- ]
- )
-
- elif env["platform"] == "ios":
- if env["ios_simulator"]:
- args.extend(["iossimulator-xcrun"])
- elif env["arch"] == "arm32":
- args.extend(["ios-xcrun"])
- elif env["arch"] == "arm64":
- args.extend(["ios64-xcrun"])
- else:
- raise ValueError("iOS architecture not supported: %s" % env["arch"])
-
+ for k in ["CC", "CXX", "AR", "AS", "RANLIB"]:
+ args.append("%s=%s" % (k, env[k]))
elif env["platform"] == "windows":
- args.extend(["enable-capieng"])
is_win_host = sys.platform in ["win32", "msys", "cygwin"]
- if env.get("is_msvc", False):
- args.extend(["VC-WIN32" if env["arch"] == "x86_32" else "VC-WIN64A"])
- else:
- if env["arch"] == "x86_32":
- args.extend(["mingw"])
- if not is_win_host:
- args.extend(["--cross-compile-prefix=i686-w64-mingw32-"])
- else:
- args.extend(["mingw64"])
- if not is_win_host:
- args.extend(["--cross-compile-prefix=x86_64-w64-mingw32-"])
-
- jobs = env.GetOption("num_jobs")
- make_cmd = ["make -C %s -j%s" % (build_dir, jobs), "make -C %s install_sw install_ssldirs -j%s" % (build_dir, jobs)]
- if env["platform"] == "windows" and env.get("is_msvc", False):
- make_cmd = ["cd %s && nmake install_sw install_ssldirs" % build_dir]
- ssl_env.Execute(
- [
- Mkdir(build_dir),
- Mkdir(install_dir),
- "cd {} && perl -- {} {}".format(
- build_dir, os.path.join(source_dir, "Configure"), " ".join(['"%s"' % a for a in args])
- ),
- ]
- + make_cmd
- )
- return None
+ if not (is_win_host or env.get("is_msvc", False)):
+ mingw_prefixes = {
+ "x86_32": "--cross-compile-prefix=i686-w64-mingw32-",
+ "x86_64": "--cross-compile-prefix=x86_64-w64-mingw32-",
+ }
+ args.append(mingw_prefixes[env["arch"]])
+ return opts + [target] + args
+
+def ssl_emitter(target, source, env):
+ return env["SSL_LIBS"], [env.File(env["SSL_SOURCE"] + "/Configure"), env.File(env["SSL_SOURCE"] + "/VERSION.dat")]
+
+
+def build_openssl(env, jobs=None):
+ if jobs is None:
+ jobs = int(env.GetOption("num_jobs"))
-def build_openssl(env):
# Since the OpenSSL build system does not support macOS universal binaries, we first need to build the two libraries
# separately, then we join them together using lipo.
if env["platform"] == "macos" and env["arch"] == "universal":
@@ -124,6 +113,7 @@ def build_openssl(env):
benv = build_envs[arch]
benv["arch"] = arch
generate(benv)
+ benv["SSLBUILDJOBS"] = max([1, int(jobs / len(build_envs))])
ssl = benv.OpenSSLBuilder()
arch_ssl.extend(ssl)
benv.NoCache(ssl) # Needs refactoring to properly cache generated headers.
@@ -132,16 +122,17 @@ def build_openssl(env):
env["SSL_INCLUDE"] = build_envs["arm64"]["SSL_INCLUDE"]
# Join libraries using lipo.
+ lipo_action = "lipo $SOURCES -create -output $TARGET"
ssl_libs = list(map(lambda arch: build_envs[arch]["SSL_LIBRARY"], build_envs))
ssl_crypto_libs = list(map(lambda arch: build_envs[arch]["SSL_CRYPTO_LIBRARY"], build_envs))
- ssl = [
- env.Command([env["SSL_LIBRARY"]], ssl_libs, "lipo $SOURCES -output $TARGETS -create"),
- env.Command([env["SSL_CRYPTO_LIBRARY"]], ssl_libs, "lipo $SOURCES -output $TARGETS -create"),
- ]
+ ssl = env.Command(env["SSL_LIBRARY"], ssl_libs, lipo_action)
+ ssl += env.Command(env["SSL_CRYPTO_LIBRARY"], ssl_crypto_libs, lipo_action)
env.Depends(ssl, arch_ssl)
else:
- ssl = env.OpenSSLBuilder()
- env.NoCache(ssl) # Needs refactoring to properly cache generated headers.
+ benv = env.Clone()
+ benv["SSLBUILDJOBS"] = jobs
+ ssl = benv.OpenSSLBuilder()
+ benv.NoCache(ssl) # Needs refactoring to properly cache generated headers.
env.Prepend(CPPPATH=[env["SSL_INCLUDE"]])
env.Prepend(LIBPATH=[env["SSL_BUILD"]])
@@ -164,6 +155,14 @@ def exists(env):
def generate(env):
+ # Android needs the NDK in ENV, and proper PATH setup.
+ if env["platform"] == "android" and env["ENV"].get("ANDROID_NDK_ROOT", "") == "":
+ cc_path = os.path.dirname(env["CC"])
+ if cc_path and cc_path not in env["ENV"]:
+ env.PrependENVPath("PATH", cc_path)
+ if "ANDROID_NDK_ROOT" not in env["ENV"]:
+ env["ENV"]["ANDROID_NDK_ROOT"] = env.get("ANDROID_NDK_ROOT", os.environ.get("ANDROID_NDK_ROOT", ""))
+
env["SSL_SOURCE"] = env.Dir(env["openssl_source"]).abspath
env["SSL_BUILD"] = env.Dir(
env["openssl_build"]
@@ -175,5 +174,33 @@ def generate(env):
env["SSL_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libssl" + lib_ext)
env["SSL_CRYPTO_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libcrypto" + lib_ext)
env["SSL_LIBS"] = [env["SSL_LIBRARY"], env["SSL_CRYPTO_LIBRARY"]]
- env.Append(BUILDERS={"OpenSSLBuilder": env.Builder(action=ssl_action, emitter=ssl_emitter)})
+
+ # Configure action
+ env["PERL"] = env.get("PERL", "perl")
+ env["_ssl_platform_config"] = ssl_platform_config
+ env["SSLPLATFORMCONFIG"] = "${_ssl_platform_config(__env__)}"
+ env["SSLCONFFLAGS"] = SCons.Util.CLVar("")
+ # fmt: off
+ env["SSLCONFIGCOM"] = "cd ${TARGET.dir} && $PERL -- ${SOURCE.abspath} --prefix=$SSL_INSTALL --openssldir=$SSL_INSTALL $SSLPLATFORMCONFIG $SSLCONFFLAGS"
+ # fmt: on
+
+ # Build action
+ env["SSLBUILDJOBS"] = "${__env__.GetOption('num_jobs')}"
+ # fmt: off
+ env["SSLBUILDCOM"] = "make -j$SSLBUILDJOBS -C ${TARGET.dir} && make -j$SSLBUILDJOBS -C ${TARGET.dir} install_sw install_ssldirs"
+ # fmt: on
+
+ # Windows MSVC needs to build using NMake
+ if env["platform"] == "windows" and env.get("is_msvc", False):
+ env["SSLBUILDCOM"] = "cd ${TARGET.dir} && nmake install_sw install_ssldirs"
+
+ env["BUILDERS"]["OpenSSLBuilder"] = SCons.Builder.Builder(
+ action=[
+ Mkdir("$SSL_BUILD"),
+ Mkdir("$SSL_INSTALL"),
+ SCons.Action.Action("$SSLCONFIGCOM", "$SSLCONFIGCOMSTR"),
+ SCons.Action.Action("$SSLBUILDCOM", "$SSLBUILDCOMSTR"),
+ ],
+ emitter=ssl_emitter,
+ )
env.AddMethod(build_openssl, "OpenSSL")
diff --git a/tools/rtc.py b/tools/rtc.py
index 81c3edd..798dc94 100644
--- a/tools/rtc.py
+++ b/tools/rtc.py
@@ -12,49 +12,36 @@ def rtc_cmake_config(env):
"OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"],
"OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"],
"OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"],
- "OPENSSL_ROOT_DIR": env["SSL_BUILD"],
- "CMAKE_BUILD_TYPE": "%s" % ("RelWithDebInfo" if env["debug_symbols"] else "Release"),
+ "OPENSSL_ROOT_DIR": env["SSL_INSTALL"],
}
- return env.CMakePlatformFlags(config)
+ return config
-def rtc_emitter(target, source, env):
+def build_library(env):
if env["platform"] == "windows":
env.PrependUnique(LIBS=["iphlpapi", "bcrypt"])
env.Prepend(LIBS=env["RTC_LIBS"])
- env.Depends(env["RTC_LIBS"], env["SSL_LIBS"])
- env.Depends(
- env["RTC_LIBS"],
- [env.File(__file__), env.Dir(env["RTC_SOURCE"]), env.File(env["RTC_SOURCE"] + "/CMakeLists.txt")],
- )
- return env["RTC_LIBS"], env.Dir(env["RTC_SOURCE"])
-
-
-def rtc_action(target, source, env):
rtc_env = env.Clone()
- build_dir = env["RTC_BUILD"]
- source_dir = env["RTC_SOURCE"]
- opts = rtc_cmake_config(rtc_env)
- rtc_env.CMakeConfigure(source_dir, build_dir, ["-D%s=%s" % it for it in opts.items()])
- opt_args = []
- if env.get("is_msvc", False):
- opt_args = ["--config", opts["CMAKE_BUILD_TYPE"]]
- rtc_env.CMakeBuild(build_dir, "datachannel-static", opt_args=opt_args)
- return None
+ rtc_targets = [env.Dir(env["RTC_BUILD"])] + env["RTC_LIBS"]
+ rtc_sources = [env.Dir(env["RTC_SOURCE"])]
+ rtc_env.Append(CMAKECONFFLAGS=["'-D%s=%s'" % it for it in rtc_cmake_config(env).items()])
+ rtc_env.Append(CMAKEBUILDFLAGS=["-t", "datachannel-static", "-j%s" % env.GetOption("num_jobs")])
+ rtc = rtc_env.CMake(rtc_targets, rtc_sources, CMAKEBUILDTYPE=env["RTC_BUILD_TYPE"])
+ rtc_env.Depends(rtc, rtc_env["SSL_LIBS"])
+ return rtc
def exists(env):
- return "CMakeConfigure" in env and "CMakeBuild" in env
+ return "CMake" in env
def generate(env):
env["RTC_SOURCE"] = env.Dir("#thirdparty/libdatachannel").abspath
+ env["RTC_BUILD_TYPE"] = "RelWithDebInfo" if env["debug_symbols"] else "Release"
env["RTC_BUILD"] = env.Dir(
- "#bin/thirdparty/libdatachannel/{}/{}/{}".format(
- env["platform"], env["arch"], "RelWithDebInfo" if env["debug_symbols"] else "Release"
- )
+ "#bin/thirdparty/libdatachannel/{}/{}/{}".format(env["platform"], env["arch"], env["RTC_BUILD_TYPE"])
).abspath
env["RTC_INCLUDE"] = env["RTC_SOURCE"] + "/include"
lib_ext = ".a"
@@ -71,6 +58,6 @@ def generate(env):
"deps/usrsctp/usrsctplib/{}usrsctp{}".format(lib_prefix, lib_ext),
]
]
- env.Append(BUILDERS={"BuildLibDataChannel": env.Builder(action=rtc_action, emitter=rtc_emitter)})
+ env.AddMethod(build_library, "BuildLibDataChannel")
env.Append(LIBPATH=[env["RTC_BUILD"]])
env.Append(CPPPATH=[env["RTC_INCLUDE"]])