diff options
author | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2021-09-22 23:16:23 +0200 |
---|---|---|
committer | Fabio Alessandrelli <fabio.alessandrelli@gmail.com> | 2022-06-15 21:38:12 +0200 |
commit | e19b3701260d4a855736c623b8c8a270413f041e (patch) | |
tree | 905bce590cbc44c4077defa52276bac245c22a2a /SConstruct | |
parent | 8c18112f5dcf96bf24fab14ab4470c00ab7f7f70 (diff) | |
download | fork-godot-webrtc-native-e19b3701260d4a855736c623b8c8a270413f041e.tar.gz fork-godot-webrtc-native-e19b3701260d4a855736c623b8c8a270413f041e.tar.bz2 fork-godot-webrtc-native-e19b3701260d4a855736c623b8c8a270413f041e.zip |
Use libdatachannel library, add Godot 4 support.
Diffstat (limited to 'SConstruct')
-rw-r--r-- | SConstruct | 434 |
1 files changed, 90 insertions, 344 deletions
@@ -2,17 +2,7 @@ import os, sys, platform, json, subprocess -if sys.version_info < (3,): - - def decode_utf8(x): - return x - - -else: - import codecs - - def decode_utf8(x): - return codecs.utf_8_decode(x)[0] +import builders def add_sources(sources, dirpath, extension): @@ -21,367 +11,123 @@ def add_sources(sources, dirpath, extension): sources.append(dirpath + "/" + f) -def gen_gdnative_lib(target, source, env): - for t in target: - with open(t.srcnode().path, "w") as w: - w.write( - decode_utf8(source[0].get_contents()) - .replace("{GDNATIVE_PATH}", os.path.splitext(t.name)[0]) - .replace("{TARGET}", env["target"]) - ) +def replace_flags(flags, replaces): + for k, v in replaces.items(): + if k in flags: + flags[flags.index(k)] = v env = Environment() - -target_arch = ARGUMENTS.get("b", ARGUMENTS.get("bits", "64")) -target_platform = ARGUMENTS.get("p", ARGUMENTS.get("platform", "linux")) -if target_platform == "windows": - # This makes sure to keep the session environment variables on windows, - # that way you can run scons in a vs 2017 prompt and it will find all the required tools - if target_arch == "64": - env = Environment(ENV=os.environ, TARGET_ARCH="amd64") - else: - env = Environment(ENV=os.environ, TARGET_ARCH="x86") - -env.Append(BUILDERS={"GDNativeLibBuilder": Builder(action=gen_gdnative_lib)}) - -customs = ["custom.py"] -opts = Variables(customs, ARGUMENTS) - -opts.Add(BoolVariable("use_llvm", "Use the LLVM compiler", False)) -opts.Add(EnumVariable("target", "Compilation target", "debug", ("debug", "release"))) - -opts.Add(EnumVariable("android_arch", "Target Android architecture", "armv7", ["armv7", "arm64v8", "x86", "x86_64"])) -opts.Add( - "android_api_level", - "Target Android API level", - "18" if ARGUMENTS.get("android_arch", "armv7") in ["armv7", "x86"] else "21", -) -opts.Add( - "ANDROID_NDK_ROOT", - "Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.", - os.environ.get("ANDROID_NDK_ROOT", None), -) - -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", - "Path to iPhone toolchain", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain", -) -opts.Add("macos_sdk_path", "macOS SDK path", "") -opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "x86_64", ["x86_64", "arm64"])) - -# Update environment (parse options) +opts = Variables(["customs.py"], ARGUMENTS) +opts.Add(EnumVariable("godot_version", "The Godot target version", "4", ["3", "4"])) opts.Update(env) -target = env["target"] - -if target_platform == "android": - target_arch = env["android_arch"] -elif target_platform == "ios": - target_arch = env["ios_arch"] - -host_platform = platform.system() -# Local dependency paths, adapt them to your setup -godot_headers = ARGUMENTS.get("headers", "godot-cpp/godot-headers") -godot_cpp_headers = ARGUMENTS.get("godot_cpp_headers", "godot-cpp/include") -godot_cpp_lib_dir = ARGUMENTS.get("godot_cpp_lib_dir", "godot-cpp/bin") -result_path = os.path.join("bin", "webrtc" if env["target"] == "release" else "webrtc_debug", "lib") -lib_prefix = "" - -# Convenience check to enforce the use_llvm overrides when CXX is clang(++) -if "CXX" in env and "clang" in os.path.basename(env["CXX"]): - env["use_llvm"] = True - -if target_platform == "linux": - env["CXX"] = "g++" - - # LLVM - if env["use_llvm"]: - if "clang++" not in os.path.basename(env["CXX"]): - env["CC"] = "clang" - env["CXX"] = "clang++" - env["LINK"] = "clang++" - - if env["target"] == "debug": - env.Prepend(CCFLAGS=["-g3"]) - env.Append(LINKFLAGS=["-rdynamic"]) - else: - env.Prepend(CCFLAGS=["-O3"]) - - env.Append(CCFLAGS=["-fPIC", "-std=c++14"]) - - if target_arch == "32": - env.Append(CCFLAGS=["-m32"]) - env.Append(LINKFLAGS=["-m32"]) - elif target_arch == "64": - env.Append(CCFLAGS=["-m64"]) - env.Append(LINKFLAGS=["-m64"]) - # i386 does not like static libstdc++ - env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) - -elif target_platform == "windows": - if host_platform == "Windows": - - lib_prefix = "lib" - env.Append(LINKFLAGS=["/WX"]) - if target == "debug": - env.Append(CCFLAGS=["/EHsc", "/D_DEBUG", "/MDd"]) - else: - env.Append(CCFLAGS=["/O2", "/EHsc", "/DNDEBUG", "/MD"]) - else: - if target_arch == "32": - env["CXX"] = "i686-w64-mingw32-g++" - elif target_arch == "64": - env["CXX"] = "x86_64-w64-mingw32-g++" - - if env["target"] == "debug": - env.Append(CCFLAGS=["-Og", "-g"]) - elif env["target"] == "release": - env.Append(CCFLAGS=["-O3"]) - - env.Append(CCFLAGS=["-std=c++14", "-Wwrite-strings"]) - env.Append(LINKFLAGS=["--static", "-Wl,--no-undefined", "-static-libgcc", "-static-libstdc++"]) - -elif target_platform == "osx": - if env["use_llvm"]: - env["CXX"] = "clang++" - - # Only 64-bits is supported for OS X - target_arch = "64" - if env["macos_arch"] != "x86_64": - target_arch = "arm64" +if env["godot_version"] == "3": + env = SConscript("godot-cpp-3.x/SConstruct") - env.Append(CCFLAGS=["-std=c++14", "-arch", env["macos_arch"]]) - env.Append(LINKFLAGS=["-arch", env["macos_arch"], "-framework", "Cocoa", "-Wl,-undefined,dynamic_lookup"]) + # Patch base env + replace_flags(env["CCFLAGS"], { + "-mios-simulator-version-min=10.0": "-mios-simulator-version-min=11.0", + "-miphoneos-version-min=10.0": "-miphoneos-version-min=11.0", + "/std:c++14": "/std:c++17", + "-std=c++14": "-std=c++17", + }) - if env["macos_sdk_path"]: - env.Append(CCFLAGS=["-isysroot", env["macos_sdk_path"]]) - env.Append(LINKFLAGS=["-isysroot", env["macos_sdk_path"]]) + env = env.Clone() if env["target"] == "debug": - env.Append(CCFLAGS=["-Og", "-g"]) - elif env["target"] == "release": - env.Append(CCFLAGS=["-O3"]) - -elif target_platform == "ios": - if env["ios_simulator"]: - sdk_name = "iphonesimulator" - env.Append(CCFLAGS=["-mios-simulator-version-min=10.0"]) - env["LIBSUFFIX"] = ".simulator" + env["LIBSUFFIX"] - else: - sdk_name = "iphoneos" - env.Append(CCFLAGS=["-miphoneos-version-min=10.0"]) - - try: - sdk_path = decode_utf8(subprocess.check_output(["xcrun", "--sdk", sdk_name, "--show-sdk-path"]).strip()) - except (subprocess.CalledProcessError, OSError): - raise ValueError("Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name)) - - compiler_path = env["IPHONEPATH"] + "/usr/bin/" - env["ENV"]["PATH"] = env["IPHONEPATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"] - - env["CC"] = compiler_path + "clang" - env["CXX"] = compiler_path + "clang++" - env["AR"] = compiler_path + "ar" - env["RANLIB"] = compiler_path + "ranlib" - - env.Append(CCFLAGS=["-std=c++14", "-arch", env["ios_arch"], "-isysroot", sdk_path]) - env.Append( - LINKFLAGS=["-arch", env["ios_arch"], "-Wl,-undefined,dynamic_lookup", "-isysroot", sdk_path, "-F" + sdk_path] - ) - - if env["target"] == "debug": - env.Append(CCFLAGS=["-Og", "-g"]) - elif env["target"] == "release": - env.Append(CCFLAGS=["-O3"]) - - -elif target_platform == "android": - # Verify NDK root - if not "ANDROID_NDK_ROOT" in env: - raise ValueError( - "To build for Android, ANDROID_NDK_ROOT must be defined. Please set ANDROID_NDK_ROOT to the root folder of your Android NDK installation." - ) - - # Validate API level - api_level = int(env["android_api_level"]) - if target_arch in ["arm64v8", "x86_64"] 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 - - # Setup toolchain - toolchain = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" - if host_platform == "Windows": - toolchain += "windows" - import platform as pltfm - - if pltfm.machine().endswith("64"): - toolchain += "-x86_64" - elif host_platform == "Linux": - toolchain += "linux-x86_64" - elif host_platform == "Darwin": - toolchain += "darwin-x86_64" - - # Get architecture info - arch_info_table = { - "armv7": { - "march": "armv7-a", - "target": "armv7a-linux-androideabi", - "tool_path": "arm-linux-androideabi", - "compiler_path": "armv7a-linux-androideabi", - "ccflags": ["-mfpu=neon"], - }, - "arm64v8": { - "march": "armv8-a", - "target": "aarch64-linux-android", - "tool_path": "aarch64-linux-android", - "compiler_path": "aarch64-linux-android", - "ccflags": [], - }, - "x86": { - "march": "i686", - "target": "i686-linux-android", - "tool_path": "i686-linux-android", - "compiler_path": "i686-linux-android", - "ccflags": ["-mstackrealign"], - }, - "x86_64": { - "march": "x86-64", - "target": "x86_64-linux-android", - "tool_path": "x86_64-linux-android", - "compiler_path": "x86_64-linux-android", - "ccflags": [], - }, - } - arch_info = arch_info_table[target_arch] - - # Setup tools - env["CC"] = toolchain + "/bin/clang" - env["CXX"] = toolchain + "/bin/clang++" - - env.Append( - CCFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"], "-fPIC"] - ) - env.Append(CCFLAGS=arch_info["ccflags"]) - env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]]) - - if env["target"] == "debug": - env.Append(CCFLAGS=["-Og", "-g"]) - elif env["target"] == "release": - env.Append(CCFLAGS=["-O3"]) - + env.Append(CPPDEFINES=["DEBUG_ENABLED"]) + + if env["platform"] == "windows" and env["use_mingw"]: + env.Append(LINKFLAGS=["-static-libgcc"]) + + # Normalize suffix + if env["platform"] in ["windows", "linux"]: + env["arch"] = "x86_32" if env["bits"] == "32" else "x86_64" + env["arch_suffix"] = env["arch"] + elif env["platform"] == "osx": + env["arch"] = env["macos_arch"] + env["arch_suffix"] = env["arch"] + elif env["platform"] == "ios": + env["arch"] = "arm32" if env["ios_arch"] == "armv7" else env["ios_arch"] + env["arch_suffix"] = env["ios_arch"] + (".simulator" if env["ios_simulator"] else "") + elif env["platform"] == "android": + env["arch"] = { + "armv7": "arm32", + "arm64v8": "arm64", + "x86": "x86_32", + "x86_64": "x86_64", + }[env["android_arch"]] + env["arch_suffix"] = env["arch"] else: - print("No valid target platform selected.") - sys.exit(1) - -# Godot CPP bindings -env.Append(CPPPATH=[godot_headers]) -env.Append(CPPPATH=[godot_cpp_headers, godot_cpp_headers + "/core", godot_cpp_headers + "/gen"]) -env.Append(LIBPATH=[godot_cpp_lib_dir]) -env.Append( - LIBS=[ - "%sgodot-cpp.%s.%s.%s%s" - % (lib_prefix, target_platform, target, target_arch, ".simulator" if env["ios_simulator"] else "") - ] -) - -# WebRTC stuff -webrtc_dir = "webrtc" -lib_name = "libwebrtc_full" -lib_path = os.path.join(webrtc_dir, target_platform) + env = SConscript("godot-cpp/SConstruct") + replace_flags(env["CCFLAGS"], { + "-mios-simulator-version-min=10.0": "-mios-simulator-version-min=11.0", + "-miphoneos-version-min=10.0": "-miphoneos-version-min=11.0", + }) + env = env.Clone() -lib_path += { - "32": "/x86", - "64": "/x64", - "armv7": "/arm", - "arm64v8": "/arm64", - "arm64": "/arm64", - "x86": "/x86", - "x86_64": "/x64", -}[target_arch] - -if target == "debug": - lib_path += "/Debug" -else: - lib_path += "/Release" - -env.Append(CPPPATH=[webrtc_dir + "/include", webrtc_dir + "/include/third_party/abseil-cpp"]) +opts.Update(env) -if target_platform == "linux": - env.Append(LIBS=[lib_name, "atomic"]) - env.Append(LIBPATH=[lib_path]) - # env.Append(CCFLAGS=["-std=c++11"]) - env.Append(CCFLAGS=["-DWEBRTC_POSIX", "-DWEBRTC_LINUX"]) - env.Append(CCFLAGS=["-DRTC_UNUSED=''", "-DNO_RETURN=''"]) +target = env["target"] +result_path = os.path.join("bin", "gdnative" if env["godot_version"] == "3" else "extension", "webrtc" if env["target"] == "release" else "webrtc_debug") -elif target_platform == "windows": - # Mostly VisualStudio - if env["CC"] == "cl": - env.Append(CCFLAGS=["/DWEBRTC_WIN", "/DWIN32_LEAN_AND_MEAN", "/DNOMINMAX", "/DRTC_UNUSED=", "/DNO_RETURN="]) - env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in ["secur32", "advapi32", "winmm", lib_name]]) - env.Append(LIBPATH=[lib_path]) - # Mostly "gcc" - else: - env.Append( - CCFLAGS=[ - "-DWINVER=0x0603", - "-D_WIN32_WINNT=0x0603", - "-DWEBRTC_WIN", - "-DWIN32_LEAN_AND_MEAN", - "-DNOMINMAX", - "-DRTC_UNUSED=", - "-DNO_RETURN=", - ] - ) - env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in ["secur32", "advapi32", "winmm", lib_name]]) - env.Append(LIBPATH=[lib_path]) +# Dependencies +deps_source_dir = "deps" +env.Append(BUILDERS={ + "BuildOpenSSL": env.Builder(action=builders.ssl_action, emitter=builders.ssl_emitter), + "BuildLibDataChannel": env.Builder(action=builders.rtc_action, emitter=builders.rtc_emitter), +}) -elif target_platform == "osx": - env.Append(LIBS=[lib_name]) - env.Append(LIBPATH=[lib_path]) - env.Append(CCFLAGS=["-DWEBRTC_POSIX", "-DWEBRTC_MAC"]) - env.Append(CCFLAGS=["-DRTC_UNUSED=''", "-DNO_RETURN=''"]) +# SSL +ssl = env.BuildOpenSSL(env.Dir(builders.get_ssl_build_dir(env)), env.Dir(builders.get_ssl_source_dir(env))) -elif target_platform == "ios": - env.Append(LIBS=[lib_name]) - env.Append(LIBPATH=[lib_path]) - env.Append(CCFLAGS=["-DWEBRTC_POSIX", "-DWEBRTC_MAC", "-DWEBRTC_IOS"]) - env.Append(CCFLAGS=["-DRTC_UNUSED=''", "-DNO_RETURN=''"]) +env.Prepend(CPPPATH=[builders.get_ssl_include_dir(env)]) +env.Prepend(LIBPATH=[builders.get_ssl_build_dir(env)]) +env.Append(LIBS=[ssl]) -elif target_platform == "android": - env.Append(LIBS=["log"]) - env.Append(LIBS=[lib_name]) - env.Append(LIBPATH=[lib_path]) - env.Append(CCFLAGS=["-DWEBRTC_POSIX", "-DWEBRTC_LINUX", "-DWEBRTC_ANDROID"]) - env.Append(CCFLAGS=["-DRTC_UNUSED=''", "-DNO_RETURN=''"]) +# RTC +rtc = env.BuildLibDataChannel(env.Dir(builders.get_rtc_build_dir(env)), [env.Dir(builders.get_rtc_source_dir(env))] + ssl) - if target_arch == "arm64v8": - env.Append(CCFLAGS=["-DWEBRTC_ARCH_ARM64", "-DWEBRTC_HAS_NEON"]) - elif target_arch == "armv7": - env.Append(CCFLAGS=["-DWEBRTC_ARCH_ARM", "-DWEBRTC_ARCH_ARM_V7", "-DWEBRTC_HAS_NEON"]) +env.Append(LIBPATH=[builders.get_rtc_build_dir(env)]) +env.Append(CPPPATH=[builders.get_rtc_include_dir(env)]) +env.Prepend(LIBS=[rtc]) # Our includes and sources env.Append(CPPPATH=["src/"]) sources = [] -add_sources(sources, "src/", "cpp") -add_sources(sources, "src/net/", "cpp") +sources.append( + [ + "src/WebRTCLibDataChannel.cpp", + "src/WebRTCLibPeerConnection.cpp", + ] +) +if env["godot_version"] == "4": + sources.append("src/init_gdextension.cpp") +else: + env.Append(CPPDEFINES=["GDNATIVE_WEBRTC"]) + sources.append("src/init_gdnative.cpp") + add_sources(sources, "src/net/", "cpp") -# Suffix -suffix = ".%s.%s" % (target, target_arch) -env["SHOBJSUFFIX"] = suffix + env["SHOBJSUFFIX"] +env.Depends(sources, [ssl, rtc]) # Make the shared library -result_name = "webrtc_native.%s.%s.%s" % (target_platform, target, target_arch) + env["SHLIBSUFFIX"] +result_name = "webrtc_native.{}.{}.{}{}".format(env["platform"], env["target"], env["arch_suffix"], env["SHLIBSUFFIX"]) +env.Depends(sources, ssl) + +if env["platform"] == "windows" and env["use_mingw"]: + env.Append(LIBS=["iphlpapi", "ws2_32", "bcrypt"]) -library = env.SharedLibrary(target=os.path.join(result_path, result_name), source=sources) +library = env.SharedLibrary(target=os.path.join(result_path, "lib", result_name), source=sources) Default(library) # GDNativeLibrary gdnlib = "webrtc" if target != "release": gdnlib += "_debug" -Default(env.GDNativeLibBuilder([os.path.join("bin", gdnlib, gdnlib + ".tres")], ["misc/gdnlib.tres"])) +ext = ".tres" if env["godot_version"] == "3" else ".gdextension" +extfile = env.Substfile(os.path.join(result_path, gdnlib + ext), "misc/webrtc" + ext, SUBST_DICT={ + "{GDNATIVE_PATH}": gdnlib, + "{TARGET}": env["target"], +}) +Default(extfile) |