Compare commits

...

20 Commits

Author SHA1 Message Date
Fabio Alessandrelli
13a934298a Merge pull request #165 from Faless/bump/godot-cpp_4.1.3
[godot-cpp] Update versions and patches
2025-01-08 12:45:59 +01:00
Fabio Alessandrelli
68338ed576 [godot-cpp] Update versions and patches
Update godot-cpp to 4.1.3

Update build profile patches to latest iteration
2025-01-08 10:51:59 +01:00
Fabio Alessandrelli
f149f97815 Merge pull request #163 from Faless/fix/compat_min_version
[Build] Fix gdextension file after dropping 4.0
2025-01-07 12:35:15 +01:00
Fabio Alessandrelli
cf038b2788 [Build] Fix gdextension file after dropping 4.0
Renaming the godot version to "4" resulted in the GDExtension file
incorrectly setting "compatibility_minimum = 4" (instead of "4.1")
2025-01-07 11:13:44 +01:00
Fabio Alessandrelli
1992779387 Merge pull request #157 from Faless/bump/libdatachannel_0.22.3
Update to libdatachannel 0.22.3
2024-12-04 17:50:11 +01:00
Fabio Alessandrelli
25bb44730e Update to libdatachannel 0.22.3 2024-12-04 15:19:14 +01:00
Fabio Alessandrelli
79bae8e0d5 Merge pull request #156 from Faless/fix/ci_toolchain_urls
[CI] Update toolchain URLs to use github releases
2024-12-04 15:18:50 +01:00
Fabio Alessandrelli
355fdd9051 [CI] Update toolchain URLs to use github releases 2024-12-04 15:01:55 +01:00
Fabio Alessandrelli
49de259a08 Merge pull request #154 from Faless/drop_4.0
Drop Godot 4.0 support
2024-12-04 14:53:04 +01:00
Fabio Alessandrelli
9afa5c3a48 Drop Godot 4.0 support
It's been unsupported by upstream for a while now, everyone should
upgrade to a newer version (4.1/4.2/4.3).
2024-10-26 18:57:38 +02:00
Fabio Alessandrelli
93e11a7343 Merge pull request #155 from Faless/bump/libdatachannel_0.22.2
Update to libdatachannel 0.22.2
2024-10-26 16:07:22 +02:00
Fabio Alessandrelli
ba46b25c00 Update to libdatachannel 0.22.2 2024-10-26 12:57:45 +02:00
Fabio Alessandrelli
31fd88dbf5 Merge pull request #153 from Faless/build/ci_macos_latest
[CI] Update macos runners to macos-latest
2024-10-25 17:25:31 +02:00
Fabio Alessandrelli
ea8b37fe29 [CI] Update macos runners to macos-latest 2024-10-25 17:03:29 +02:00
Fabio Alessandrelli
cb1ef2e59c Merge pull request #152 from Faless/bump/libdatachannel_0.22.1_openssl_3.4.0
Update to libdatachannel 0.22.2 OpenSSL 3.4.0
2024-10-25 11:13:01 +02:00
Fabio Alessandrelli
038bac82d6 Update to libdatachannel 0.22.2 OpenSSL 3.4.0 2024-10-25 10:47:44 +02:00
Fabio Alessandrelli
effada6b45 Merge pull request #148 from Faless/build/better_macos_ios_targets
[SCons] Improve CMake and OpenSSL macOS/iOS targets
2024-06-17 18:21:10 +02:00
Fabio Alessandrelli
26bc56f934 [SCons] Improve CMake and OpenSSL macOS/iOS targets
Update CI to macos-12 (since macos-11 is not longer available.
2024-06-17 18:01:57 +02:00
Fabio Alessandrelli
44ee53715d Merge pull request #147 from Faless/build/build_profile
[CI] Add patches to use build profile and speed up builds
2024-06-17 17:55:38 +02:00
Fabio Alessandrelli
0b89ed885d [CI] Add patches to use build profile and speed up builds 2024-06-15 18:37:40 +02:00
18 changed files with 660 additions and 83 deletions

View File

@@ -4,6 +4,8 @@ on: [push, pull_request]
env:
# Only used for the cache key. Increment version to force clean build.
GODOT_BASE_BRANCH: master
# Hardcoding this seem to be the only way
ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/23.2.8568313/
jobs:
static-checks:
@@ -64,13 +66,13 @@ jobs:
arch: 'x86_64'
gdnative_flags: 'ios_arch=x86_64'
sconsflags: 'ios_simulator=true'
os: 'macos-11'
os: 'macos-latest'
cache-name: ios-x86_64-simulator
- platform: ios
arch: 'arm64'
gdnative_flags: 'ios_arch=arm64'
sconsflags: ''
os: 'macos-11'
os: 'macos-latest'
cache-name: ios-arm64
# Linux
@@ -108,7 +110,7 @@ jobs:
arch: 'universal'
gdnative_flags: 'macos_arch=universal bits=64'
sconsflags: ''
os: 'macos-11'
os: 'macos-latest'
cache-name: macos-universal
# Windows
@@ -129,7 +131,7 @@ jobs:
env:
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
SCONSFLAGS: ${{ matrix.sconsflags }} platform=${{ matrix.platform }} arch=${{ matrix.arch }} --jobs=2
SCONSFLAGS: ${{ matrix.sconsflags }} platform=${{ matrix.platform }} arch=${{ matrix.arch }} build_profile=build_profile.json --jobs=2
defaults:
run:
@@ -187,7 +189,7 @@ jobs:
if: ${{ matrix.platform == 'linux' }}
run: |
if [ ! -f ${{ matrix.buildroot }}.tar.bz2 ]; then
wget https://downloads.tuxfamily.org/godotengine/toolchains/linux/${{ matrix.buildroot }}.tar.bz2
wget https://github.com/godotengine/buildroot/releases/download/godot-2023.08.x-4/${{ matrix.buildroot }}.tar.bz2
fi
tar -xjf ${{ matrix.buildroot }}.tar.bz2
${{ matrix.buildroot }}/relocate-sdk.sh
@@ -196,6 +198,18 @@ jobs:
patch -p1 < misc/patches/scons_path.diff
patch -p1 < misc/patches/gdnantive_arm_warnings.diff
- name: Setup Android dependencies
if: ${{ matrix.platform == 'android' }}
uses: nttld/setup-ndk@v1
with:
ndk-version: r23c
link-to-sdk: true
- name: Patch godot-cpp to support build profile.
run: |
patch -p1 < misc/patches/build_profile.diff
patch -p1 < misc/patches/build_profile_3.x.diff
- name: Print tools versions
run: |
python --version
@@ -204,19 +218,11 @@ jobs:
- name: Compile Extension (4.1+) - template_debug - ${{ matrix.platform }} - ${{ matrix.arch }}
run: |
scons target=template_debug godot_version=4.1
scons target=template_debug godot_version=4
- name: Compile Extension (4.1+) - template_release - ${{ matrix.platform }} - ${{ matrix.arch }}
run: |
scons target=template_release godot_version=4.1
- name: Compile Extension (4.0) - template_debug - ${{ matrix.platform }} - ${{ matrix.arch }}
run: |
scons target=template_debug godot_version=4.0
- name: Compile Extension (4.0) - template_release - ${{ matrix.platform }} - ${{ matrix.arch }}
run: |
scons target=template_release godot_version=4.0
scons target=template_release godot_version=4
- name: Compile GDNative (3.5+) - release ${{ matrix.platform }} - ${{ matrix.arch }}
run: |
@@ -259,21 +265,15 @@ jobs:
run: |
mkdir release
VERSION="extension-4.1" TYPE="webrtc" ./misc/scripts/package_release.sh
VERSION="extension-4.0" TYPE="webrtc" ./misc/scripts/package_release.sh
VERSION="extension" TYPE="webrtc" ./misc/scripts/package_release.sh
VERSION="gdnative" TYPE="webrtc" ./misc/scripts/package_release.sh
ls -R release
- uses: actions/upload-artifact@v4
with:
name: godot-webrtc-extension-4.1
path: release/*-extension-4.1-*.zip
- uses: actions/upload-artifact@v4
with:
name: godot-webrtc-extension-4.0
path: release/*-extension-4.0-*.zip
name: godot-webrtc-extension
path: release/*-extension-*.zip
- uses: actions/upload-artifact@v4
with:

3
.gitmodules vendored
View File

@@ -1,9 +1,6 @@
[submodule "godot-cpp"]
path = godot-cpp
url = https://github.com/godotengine/godot-cpp.git
[submodule "godot-cpp-4.0"]
path = godot-cpp-4.0
url = https://github.com/godotengine/godot-cpp.git
[submodule "godot-cpp-3.x"]
path = godot-cpp-3.x
url = https://github.com/godotengine/godot-cpp.git

View File

@@ -28,7 +28,7 @@ def validate_godotcpp_dir(key, val, env):
env = Environment()
opts = Variables(["customs.py"], ARGUMENTS)
opts.Add(EnumVariable("godot_version", "The Godot target version", "4.1", ["3", "4.0", "4.1"]))
opts.Add(EnumVariable("godot_version", "The Godot target version", "4", ["3", "4"], {"4.1+": "4", "4.1": "4"}))
opts.Add(
PathVariable(
"godot_cpp",
@@ -41,7 +41,7 @@ opts.Update(env)
# Minimum target platform versions.
if "ios_min_version" not in ARGUMENTS:
ARGUMENTS["ios_min_version"] = "11.0"
ARGUMENTS["ios_min_version"] = "12.0"
if "macos_deployment_target" not in ARGUMENTS:
ARGUMENTS["macos_deployment_target"] = "11.0"
if "android_api_level" not in ARGUMENTS:
@@ -61,8 +61,8 @@ if env["godot_version"] == "3":
replace_flags(
cpp_env["CCFLAGS"],
{
"-mios-simulator-version-min=10.0": "-mios-simulator-version-min=11.0",
"-miphoneos-version-min=10.0": "-miphoneos-version-min=11.0",
"-mios-simulator-version-min=10.0": "-mios-simulator-version-min=12.0",
"-miphoneos-version-min=10.0": "-miphoneos-version-min=12.0",
"/std:c++14": "/std:c++17",
"-std=c++14": "-std=c++17",
},
@@ -82,7 +82,7 @@ if env["godot_version"] == "3":
env["CC"] = "clang" # CC is not set in 3.x and can result in it being "gcc".
if env["platform"] == "ios":
env["ios_min_version"] = "11.0"
env["ios_min_version"] = "12.0"
# Normalize suffix
if env["platform"] in ["windows", "linux"]:
@@ -122,10 +122,6 @@ if env["godot_version"] == "3":
if env["platform"] == "linux" and env["arch"] not in ("x86_32", "x86_64"):
for flags in (env["CCFLAGS"], env["LINKFLAGS"], cpp_env["CCFLAGS"], cpp_env["LINKFLAGS"]):
replace_flags(flags, {"-m32": None, "-m64": None})
elif env["godot_version"] == "4.0":
sconstruct = env.get("godot_cpp", "godot-cpp-4.0") + "/SConstruct"
cpp_env = SConscript(sconstruct)
env = cpp_env.Clone()
else:
sconstruct = env.get("godot_cpp", "godot-cpp") + "/SConstruct"
cpp_env = SConscript(sconstruct)
@@ -160,10 +156,8 @@ opts.Update(env)
target = env["target"]
if env["godot_version"] == "3":
result_path = os.path.join("bin", "gdnative", "webrtc" if env["target"] == "release" else "webrtc_debug")
elif env["godot_version"] == "4.0":
result_path = os.path.join("bin", "extension-4.0", "webrtc")
else:
result_path = os.path.join("bin", "extension-4.1", "webrtc")
result_path = os.path.join("bin", "extension", "webrtc")
# Our includes and sources
env.Append(CPPPATH=["src/"])
@@ -181,8 +175,6 @@ if env["godot_version"] == "3":
add_sources(sources, "src/net/", "cpp")
else:
sources.append("src/init_gdextension.cpp")
if env["godot_version"] == "4.0":
env.Append(CPPDEFINES=["GDEXTENSION_WEBRTC_40"])
# Add our build tools
for tool in ["openssl", "cmake", "rtc"]:
@@ -249,10 +241,6 @@ if env["godot_version"] == "3":
},
)
else:
extfile = env.Substfile(
os.path.join(result_path, "webrtc.gdextension"),
"misc/webrtc.gdextension",
SUBST_DICT={"{GODOT_VERSION}": env["godot_version"]},
)
extfile = env.InstallAs(os.path.join(result_path, "webrtc.gdextension"), "misc/webrtc.gdextension")
Default(extfile)

11
build_profile.json Normal file
View File

@@ -0,0 +1,11 @@
{
"enabled_classes": [
"WebRTCDataChannelExtension",
"WebRTCPeerConnectionExtension",
"WebRTCDataChannelGDNative",
"WebRTCPeerConnectionGDNative",
"NativeScript",
"GDNativeLibrary",
"Window"
]
}

Submodule godot-cpp-4.0 deleted from 9d1c396c54

View File

@@ -0,0 +1,297 @@
diff --git a/godot-cpp/binding_generator.py b/godot-cpp/binding_generator.py
index 18db9fd..e0c8caf 100644
--- a/godot-cpp/binding_generator.py
+++ b/godot-cpp/binding_generator.py
@@ -72,9 +72,13 @@ def generate_wrappers(target):
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
api = {}
- files = []
with open(api_filepath, encoding="utf-8") as api_file:
api = json.load(api_file)
+ return _get_file_list(api, output_dir, headers, sources)
+
+
+def _get_file_list(api, output_dir, headers=False, sources=False):
+ files = []
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
@@ -158,13 +162,15 @@ def scons_generate_bindings(target, source, env):
return None
-def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
- api = None
-
- target_dir = Path(output_dir) / "gen"
-
+def _generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
+ api = {}
with open(api_filepath, encoding="utf-8") as api_file:
api = json.load(api_file)
+ _generate_bindings(api, use_template_get_node, bits, precision, output_dir)
+
+
+def _generate_bindings(api, use_template_get_node, bits="64", precision="single", output_dir="."):
+ target_dir = Path(output_dir) / "gen"
shutil.rmtree(target_dir, ignore_errors=True)
target_dir.mkdir(parents=True)
diff --git a/godot-cpp/build_profile.py b/godot-cpp/build_profile.py
new file mode 100644
index 0000000..b4d19de
--- /dev/null
+++ b/godot-cpp/build_profile.py
@@ -0,0 +1,183 @@
+import json
+import sys
+
+
+def parse_build_profile(profile_filepath, api):
+ if profile_filepath == "":
+ return {}
+
+ with open(profile_filepath, encoding="utf-8") as profile_file:
+ profile = json.load(profile_file)
+
+ api_dict = {}
+ parents = {}
+ children = {}
+ for engine_class in api["classes"]:
+ api_dict[engine_class["name"]] = engine_class
+ parent = engine_class.get("inherits", "")
+ child = engine_class["name"]
+ parents[child] = parent
+ if parent == "":
+ continue
+ children[parent] = children.get(parent, [])
+ children[parent].append(child)
+
+ included = []
+ front = list(profile.get("enabled_classes", []))
+ if front:
+ # These must always be included
+ front.append("WorkerThreadPool")
+ front.append("ClassDB")
+ front.append("ClassDBSingleton")
+ # In src/classes/low_level.cpp
+ front.append("FileAccess")
+ front.append("Image")
+ front.append("XMLParser")
+ # In include/godot_cpp/templates/thread_work_pool.hpp
+ front.append("Semaphore")
+ while front:
+ cls = front.pop()
+ if cls in included:
+ continue
+ included.append(cls)
+ parent = parents.get(cls, "")
+ if parent:
+ front.append(parent)
+
+ excluded = []
+ front = list(profile.get("disabled_classes", []))
+ while front:
+ cls = front.pop()
+ if cls in excluded:
+ continue
+ excluded.append(cls)
+ front += children.get(cls, [])
+
+ if included and excluded:
+ print(
+ "WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
+ )
+
+ return {
+ "enabled_classes": included,
+ "disabled_classes": excluded,
+ }
+
+
+def generate_trimmed_api(source_api_filepath, profile_filepath):
+ with open(source_api_filepath, encoding="utf-8") as api_file:
+ api = json.load(api_file)
+
+ if profile_filepath == "":
+ return api
+
+ build_profile = parse_build_profile(profile_filepath, api)
+
+ engine_classes = {}
+ for class_api in api["classes"]:
+ engine_classes[class_api["name"]] = class_api["is_refcounted"]
+ for native_struct in api["native_structures"]:
+ if native_struct["name"] == "ObjectID":
+ continue
+ engine_classes[native_struct["name"]] = False
+
+ classes = []
+ for class_api in api["classes"]:
+ if not is_class_included(class_api["name"], build_profile):
+ continue
+ if "methods" in class_api:
+ methods = []
+ for method in class_api["methods"]:
+ if not is_method_included(method, build_profile, engine_classes):
+ continue
+ methods.append(method)
+ class_api["methods"] = methods
+ classes.append(class_api)
+ api["classes"] = classes
+
+ return api
+
+
+def is_class_included(class_name, build_profile):
+ """
+ Check if an engine class should be included.
+ This removes classes according to a build profile of enabled or disabled classes.
+ """
+ included = build_profile.get("enabled_classes", [])
+ excluded = build_profile.get("disabled_classes", [])
+ if included:
+ return class_name in included
+ if excluded:
+ return class_name not in excluded
+ return True
+
+
+def is_method_included(method, build_profile, engine_classes):
+ """
+ Check if an engine class method should be included.
+ This removes methods according to a build profile of enabled or disabled classes.
+ """
+ included = build_profile.get("enabled_classes", [])
+ excluded = build_profile.get("disabled_classes", [])
+ ref_cls = set()
+ rtype = get_base_type(method.get("return_value", {}).get("type", ""))
+ args = [get_base_type(a["type"]) for a in method.get("arguments", [])]
+ if rtype in engine_classes:
+ ref_cls.add(rtype)
+ elif is_enum(rtype) and get_enum_class(rtype) in engine_classes:
+ ref_cls.add(get_enum_class(rtype))
+ for arg in args:
+ if arg in engine_classes:
+ ref_cls.add(arg)
+ elif is_enum(arg) and get_enum_class(arg) in engine_classes:
+ ref_cls.add(get_enum_class(arg))
+ for acls in ref_cls:
+ if len(included) > 0 and acls not in included:
+ return False
+ elif len(excluded) > 0 and acls in excluded:
+ return False
+ return True
+
+
+def is_enum(type_name):
+ return type_name.startswith("enum::") or type_name.startswith("bitfield::")
+
+
+def get_enum_class(enum_name: str):
+ if "." in enum_name:
+ if is_bitfield(enum_name):
+ return enum_name.replace("bitfield::", "").split(".")[0]
+ else:
+ return enum_name.replace("enum::", "").split(".")[0]
+ else:
+ return "GlobalConstants"
+
+
+def get_base_type(type_name):
+ if type_name.startswith("const "):
+ type_name = type_name[6:]
+ if type_name.endswith("*"):
+ type_name = type_name[:-1]
+ if type_name.startswith("typedarray::"):
+ type_name = type_name.replace("typedarray::", "")
+ return type_name
+
+
+def is_bitfield(type_name):
+ return type_name.startswith("bitfield::")
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 3 or len(sys.argv) > 4:
+ print("Usage: %s BUILD_PROFILE INPUT_JSON [OUTPUT_JSON]" % (sys.argv[0]))
+ sys.exit(1)
+ profile = sys.argv[1]
+ infile = sys.argv[2]
+ outfile = sys.argv[3] if len(sys.argv) > 3 else ""
+ api = generate_trimmed_api(infile, profile)
+
+ if outfile:
+ with open(outfile, "w", encoding="utf-8") as f:
+ json.dump(api, f)
+ else:
+ json.dump(api, sys.stdout)
diff --git a/godot-cpp/tools/godotcpp.py b/godot-cpp/tools/godotcpp.py
index efe632a..993aa81 100644
--- a/godot-cpp/tools/godotcpp.py
+++ b/godot-cpp/tools/godotcpp.py
@@ -5,7 +5,8 @@ from SCons.Tool import Tool
from SCons.Builder import Builder
from SCons.Errors import UserError
-from binding_generator import scons_generate_bindings, scons_emit_files
+from binding_generator import _generate_bindings, _get_file_list, get_file_list
+from build_profile import generate_trimmed_api
def add_sources(sources, dir, extension):
@@ -14,6 +15,37 @@ def add_sources(sources, dir, extension):
sources.append(dir + "/" + f)
+def scons_emit_files(target, source, env):
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath:
+ profile_filepath = normalize_path(profile_filepath, env)
+
+ # Always clean all files
+ env.Clean(target, [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)])
+
+ api = generate_trimmed_api(str(source[0]), profile_filepath)
+ files = [env.File(f) for f in _get_file_list(api, target[0].abspath, True, True)]
+ env["godot_cpp_gen_dir"] = target[0].abspath
+ return files, source
+
+
+def scons_generate_bindings(target, source, env):
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath:
+ profile_filepath = normalize_path(profile_filepath, env)
+
+ api = generate_trimmed_api(str(source[0]), profile_filepath)
+
+ _generate_bindings(
+ api,
+ env["generate_template_get_node"],
+ "32" if "32" in env["arch"] else "64",
+ env["precision"],
+ env["godot_cpp_gen_dir"],
+ )
+ return None
+
+
def normalize_path(val, env):
return val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)
@@ -175,6 +207,15 @@ def options(opts, env):
)
)
+ opts.Add(
+ PathVariable(
+ "build_profile",
+ "Path to a file containing a feature build profile",
+ default=env.get("build_profile", None),
+ validator=validate_file,
+ )
+ )
+
opts.Add(
BoolVariable(
"disable_exceptions",

View File

@@ -0,0 +1,286 @@
diff --git a/godot-cpp-3.x/SConstruct b/godot-cpp-3.x/SConstruct
index f653d54..483f190 100644
--- a/godot-cpp-3.x/SConstruct
+++ b/godot-cpp-3.x/SConstruct
@@ -3,7 +3,42 @@
import os
import sys
import subprocess
-from binding_generator import scons_generate_bindings, scons_emit_files
+from binding_generator import _generate_bindings, _get_file_list, get_file_list
+from build_profile import generate_trimmed_api
+
+
+def normalize_path(val):
+ return val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)
+
+
+def scons_emit_files(target, source, env):
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath:
+ profile_filepath = normalize_path(profile_filepath)
+
+ # Always clean all files
+ env.Clean(target, [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)])
+
+ api = generate_trimmed_api(str(source[0]), profile_filepath)
+ files = [env.File(f) for f in _get_file_list(api, target[0].abspath, True, True)]
+ env["godot_cpp_gen_dir"] = target[0].abspath
+ return files, source
+
+
+def scons_generate_bindings(target, source, env):
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath:
+ profile_filepath = normalize_path(profile_filepath)
+
+ api = generate_trimmed_api(str(source[0]), profile_filepath)
+
+ _generate_bindings(
+ api,
+ env["generate_template_get_node"],
+ env["godot_cpp_gen_dir"],
+ )
+ return None
+
if sys.version_info < (3,):
@@ -170,6 +205,14 @@ opts.Add(
True,
)
)
+opts.Add(
+ PathVariable(
+ "build_profile",
+ "Path to a file containing a feature build profile",
+ default=env.get("build_profile", None),
+ validator=lambda key, val, env: os.path.isfile(normalize_path(val)),
+ )
+)
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
diff --git a/godot-cpp-3.x/binding_generator.py b/godot-cpp-3.x/binding_generator.py
index da4bb61..1348a51 100644
--- a/godot-cpp-3.x/binding_generator.py
+++ b/godot-cpp-3.x/binding_generator.py
@@ -16,10 +16,16 @@ classes = []
def get_file_list(api_filepath, output_dir, headers=False, sources=False):
- global classes
- files = []
+ api = {}
with open(api_filepath) as api_file:
classes = json.load(api_file)
+ return _get_file_list(classes, output_dir, headers, sources)
+
+
+def _get_file_list(api, output_dir, headers=False, sources=False):
+ global classes
+ classes = api
+ files = []
include_gen_folder = Path(output_dir) / "include" / "gen"
source_gen_folder = Path(output_dir) / "src" / "gen"
for _class in classes:
@@ -58,9 +64,15 @@ def scons_generate_bindings(target, source, env):
def generate_bindings(api_filepath, use_template_get_node, output_dir="."):
- global classes
+ classes = {}
with open(api_filepath) as api_file:
classes = json.load(api_file)
+ _generate_bindings(classes, use_template_get_node, output_dir)
+
+
+def _generate_bindings(api, use_template_get_node, output_dir="."):
+ global classes
+ classes = api
icalls = set()
include_gen_folder = Path(output_dir) / "include" / "gen"
diff --git a/godot-cpp-3.x/build_profile.py b/godot-cpp-3.x/build_profile.py
new file mode 100644
index 0000000..5518f64
--- /dev/null
+++ b/godot-cpp-3.x/build_profile.py
@@ -0,0 +1,177 @@
+import json
+import sys
+
+
+def parse_build_profile(profile_filepath, api):
+ if profile_filepath == "":
+ return {}
+
+ with open(profile_filepath, encoding="utf-8") as profile_file:
+ profile = json.load(profile_file)
+
+ api_dict = {}
+ parents = {}
+ children = {}
+ for engine_class in api:
+ api_dict[engine_class["name"]] = engine_class
+ parent = engine_class.get("base_class", "")
+ child = engine_class["name"]
+ parents[child] = parent
+ if parent == "":
+ continue
+ children[parent] = children.get(parent, [])
+ children[parent].append(child)
+
+ included = []
+ front = list(profile.get("enabled_classes", []))
+ if front:
+ # These must always be included
+ front.append("WorkerThreadPool")
+ front.append("ClassDB")
+ front.append("ClassDBSingleton")
+ # In src/classes/low_level.cpp
+ front.append("FileAccess")
+ front.append("Image")
+ front.append("XMLParser")
+ # In include/godot_cpp/templates/thread_work_pool.hpp
+ front.append("Semaphore")
+ while front:
+ cls = front.pop()
+ if cls in included:
+ continue
+ included.append(cls)
+ parent = parents.get(cls, "")
+ if parent:
+ front.append(parent)
+
+ excluded = []
+ front = list(profile.get("disabled_classes", []))
+ while front:
+ cls = front.pop()
+ if cls in excluded:
+ continue
+ excluded.append(cls)
+ front += children.get(cls, [])
+
+ if included and excluded:
+ print(
+ "WARNING: Cannot specify both 'enabled_classes' and 'disabled_classes' in build profile. 'disabled_classes' will be ignored."
+ )
+
+ return {
+ "enabled_classes": included,
+ "disabled_classes": excluded,
+ }
+
+
+def generate_trimmed_api(source_api_filepath, profile_filepath):
+ with open(source_api_filepath, encoding="utf-8") as api_file:
+ api = json.load(api_file)
+
+ if profile_filepath == "":
+ return api
+
+ build_profile = parse_build_profile(profile_filepath, api)
+
+ engine_classes = {}
+ for class_api in api:
+ engine_classes[class_api["name"]] = class_api["is_reference"]
+
+ classes = []
+ for class_api in api:
+ if not is_class_included(class_api["name"], build_profile):
+ continue
+ if "methods" in class_api:
+ methods = []
+ for method in class_api["methods"]:
+ if not is_method_included(method, build_profile, engine_classes):
+ continue
+ methods.append(method)
+ class_api["methods"] = methods
+ classes.append(class_api)
+ return classes
+
+
+def is_class_included(class_name, build_profile):
+ """
+ Check if an engine class should be included.
+ This removes classes according to a build profile of enabled or disabled classes.
+ """
+ included = build_profile.get("enabled_classes", [])
+ excluded = build_profile.get("disabled_classes", [])
+ if included:
+ return class_name in included
+ if excluded:
+ return class_name not in excluded
+ return True
+
+
+def is_method_included(method, build_profile, engine_classes):
+ """
+ Check if an engine class method should be included.
+ This removes methods according to a build profile of enabled or disabled classes.
+ """
+ included = build_profile.get("enabled_classes", [])
+ excluded = build_profile.get("disabled_classes", [])
+ ref_cls = set()
+ rtype = get_base_type(method.get("return_type", ""))
+ args = [get_base_type(a["type"]) for a in method.get("arguments", [])]
+ if rtype in engine_classes:
+ ref_cls.add(rtype)
+ elif is_enum(rtype) and get_enum_class(rtype) in engine_classes:
+ ref_cls.add(get_enum_class(rtype))
+ for arg in args:
+ if arg in engine_classes:
+ ref_cls.add(arg)
+ elif is_enum(arg) and get_enum_class(arg) in engine_classes:
+ ref_cls.add(get_enum_class(arg))
+ for acls in ref_cls:
+ if len(included) > 0 and acls not in included:
+ return False
+ elif len(excluded) > 0 and acls in excluded:
+ return False
+ return True
+
+
+def is_enum(type_name):
+ return type_name.startswith("enum::") or type_name.startswith("bitfield::")
+
+
+def get_enum_class(enum_name: str):
+ if "." in enum_name:
+ if is_bitfield(enum_name):
+ return enum_name.replace("bitfield::", "").split(".")[0]
+ else:
+ return enum_name.replace("enum::", "").split(".")[0]
+ else:
+ return "GlobalConstants"
+
+
+def get_base_type(type_name):
+ if type_name.startswith("const "):
+ type_name = type_name[6:]
+ if type_name.endswith("*"):
+ type_name = type_name[:-1]
+ if type_name.startswith("typedarray::"):
+ type_name = type_name.replace("typedarray::", "")
+ return type_name
+
+
+def is_bitfield(type_name):
+ return type_name.startswith("bitfield::")
+
+
+if __name__ == "__main__":
+ if len(sys.argv) < 3 or len(sys.argv) > 4:
+ print("Usage: %s BUILD_PROFILE INPUT_JSON [OUTPUT_JSON]" % (sys.argv[0]))
+ sys.exit(1)
+ profile = sys.argv[1]
+ infile = sys.argv[2]
+ outfile = sys.argv[3] if len(sys.argv) > 3 else ""
+ api = generate_trimmed_api(infile, profile)
+
+ if outfile:
+ with open(outfile, "w", encoding="utf-8") as f:
+ json.dump(api, f)
+ else:
+ json.dump(api, sys.stdout)

View File

@@ -1,17 +1,3 @@
diff --git a/godot-cpp-4.0/SConstruct b/godot-cpp-4.0/SConstruct
index 27ee137..32b425e 100644
--- a/godot-cpp-4.0/SConstruct
+++ b/godot-cpp-4.0/SConstruct
@@ -54,6 +54,8 @@ else:
# Default tools with no platform defaults to gnu toolchain.
# We apply platform specific toolchains via our custom tools.
env = Environment(tools=["default"], PLATFORM="")
+# Allows us to use Godot buildroot toolchain
+env.PrependENVPath("PATH", os.getenv("PATH"))
# Default num_jobs to local cpu count if not user specified.
# SCons has a peculiarity where user-specified options won't be overridden
diff --git a/godot-cpp-3.x/SConstruct b/godot-cpp-3.x/SConstruct
index f653d54..6f40377 100644
--- a/godot-cpp-3.x/SConstruct

View File

@@ -1,7 +1,7 @@
[configuration]
entry_symbol = "webrtc_extension_init"
compatibility_minimum = {GODOT_VERSION}
compatibility_minimum = 4.1
[libraries]

View File

@@ -199,7 +199,7 @@ Error WebRTCLibPeerConnection::_initialize(const Dictionary &p_config) {
return _create_pc(config);
}
#if defined(GDNATIVE_WEBRTC) || defined(GDEXTENSION_WEBRTC_40)
#if defined(GDNATIVE_WEBRTC)
Object *WebRTCLibPeerConnection::_create_data_channel(const String &p_channel, const Dictionary &p_channel_config) try {
#else
Ref<WebRTCDataChannel> WebRTCLibPeerConnection::_create_data_channel(const String &p_channel, const Dictionary &p_channel_config) try {

View File

@@ -83,7 +83,7 @@ public:
SignalingState _get_signaling_state() const override;
godot::Error _initialize(const godot::Dictionary &p_config) override;
#if defined(GDNATIVE_WEBRTC) || defined(GDEXTENSION_WEBRTC_40)
#if defined(GDNATIVE_WEBRTC)
godot::Object *_create_data_channel(const godot::String &p_channel, const godot::Dictionary &p_channel_config) override;
#else
godot::Ref<godot::WebRTCDataChannel> _create_data_channel(const godot::String &p_channel, const godot::Dictionary &p_channel_config) override;

View File

@@ -66,11 +66,7 @@ void unregister_webrtc_extension_types(ModuleInitializationLevel p_level) {
}
extern "C" {
#ifdef GDEXTENSION_WEBRTC_40
GDExtensionBool GDE_EXPORT webrtc_extension_init(const GDExtensionInterface *p_interface, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
#else
GDExtensionBool GDE_EXPORT webrtc_extension_init(const GDExtensionInterfaceGetProcAddress p_interface, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
#endif
GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
init_obj.register_initializer(register_webrtc_extension_types);

View File

@@ -19,7 +19,7 @@ Module location:
## libdatachannel
- Upstream: https://github.com/paullouisageneau/libdatachannel
- Version: 0.20.2 (0b1074a9effeb8d9d3f4eca704d3fe3d2f9bc7e5, 2024)
- Version: 0.22.3 (d74748fd46f75cee5090d187841c6921820eb9d0, 2024)
- License: MPL 2.0
Module location:
@@ -30,7 +30,7 @@ Module location:
# libjuice
- Upstream: https://github.com/paullouisageneau/libjuice
- Version: 1.3.4 (0b6f958baba55e1a4eb31ec2137f62b2e07382ae, 2024)
- Version: 1.5.7 (70ba50cce33350b64404557ea63658e925758ce6, 2024)
- License: MPL 2.0
Module location:
@@ -52,7 +52,7 @@ Module location:
## openssl
- Upstream: git://git.openssl.org/openssl.git
- Version: 3.0.13 (85cf92f55d9e2ac5aacf92bedd33fb890b9f8b4c, 2024)
- Version: 3.4.0 (98acb6b02839c609ef5b837794e08d906d965335, 2024)
- License: Apache 2.0
Module location:

View File

@@ -5,6 +5,11 @@ import SCons.Builder
import SCons.Action
# This must be kept in sync with the value in https://github.com/godotengine/godot/blob/master/platform/android/detect.py#L58.
def get_ndk_version():
return "23.2.8568313"
def cmake_default_flags(env):
if env.get("cmake_default_flags", ""):
return SCons.Util.CLVar(env["cmake_default_flags"])
@@ -28,9 +33,8 @@ def cmake_default_flags(env):
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" % env.get(
"ANDROID_NDK_ROOT", os.environ.get("ANDROID_NDK_ROOT", "")
)
ndk_root = os.environ.get("ANDROID_NDK_ROOT", env.get("ANDROID_HOME", "") + "/ndk/" + get_ndk_version())
config["CMAKE_TOOLCHAIN_FILE"] = "%s/build/cmake/android.toolchain.cmake" % ndk_root
config["CMAKE_ANDROID_STL_TYPE"] = "c++_static"
elif env["platform"] == "linux":
@@ -49,10 +53,9 @@ def cmake_default_flags(env):
config["CMAKE_OSX_ARCHITECTURES"] = '"x86_64;arm64"'
else:
config["CMAKE_OSX_ARCHITECTURES"] = env["arch"]
if env["macos_deployment_target"] != "default":
if env.get("macos_deployment_target", "default") != "default":
config["CMAKE_OSX_DEPLOYMENT_TARGET"] = env["macos_deployment_target"]
if env["platform"] == "macos" and sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ:
if sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ:
config["CMAKE_AR"] = env["AR"]
config["CMAKE_RANLIB"] = env["RANLIB"]
if env["arch"] == "universal":

View File

@@ -6,6 +6,11 @@ from SCons.Defaults import Mkdir
from SCons.Variables import PathVariable, BoolVariable
# This must be kept in sync with the value in https://github.com/godotengine/godot/blob/master/platform/android/detect.py#L58.
def get_ndk_version():
return "23.2.8568313"
def ssl_platform_target(env):
targets = {}
platform = env["platform"]
@@ -32,8 +37,8 @@ def ssl_platform_target(env):
elif platform == "ios":
if env["ios_simulator"]:
targets = {
"x86_64": "iossimulator-xcrun",
"arm64": "iossimulator-xcrun",
"x86_64": "iossimulator-x86_64-xcrun",
"arm64": "iossimulator-arm64-xcrun",
}
else:
targets = {
@@ -79,7 +84,15 @@ def ssl_platform_flags(env):
if env.get("android_api_level", ""):
api = int(env["android_api_level"])
args.append("-D__ANDROID_API__=%s" % api)
elif env["platform"] == "ios":
if env.get("ios_min_version", "default") != "default":
if env.get("ios_simulator", False):
args.append("-mios-simulator-version-min=%s" % env["ios_min_version"])
else:
args.append("-miphoneos-version-min=%s" % env["ios_min_version"])
elif env["platform"] == "macos":
if env.get("macos_deployment_target", "default") != "default":
args.append("-mmacosx-version-min=%s" % env["macos_deployment_target"])
# OSXCross toolchain setup.
if sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ:
for k in ["CC", "CXX", "AR", "AS", "RANLIB"]:
@@ -256,7 +269,8 @@ def generate(env):
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", ""))
ndk_root = os.environ.get("ANDROID_NDK_ROOT", env.get("ANDROID_HOME", "") + "/ndk/" + get_ndk_version())
env["ENV"]["ANDROID_NDK_ROOT"] = ndk_root
env["SSL_SOURCE"] = env.Dir(env["openssl_source"]).abspath
env["SSL_BUILD"] = env.Dir(env["openssl_build"] + "/{}/{}".format(env["platform"], env["arch"])).abspath