Compare commits

...

36 Commits

Author SHA1 Message Date
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
Fabio Alessandrelli
bf8f6e4581 Merge pull request #144 from Faless/build/custom_godotcpp
Allow building using a custom godot-cpp verison
2024-04-13 15:06:56 +02:00
Fabio Alessandrelli
1443d02c8d Allow building using a custom godot-cpp verison
You can use it with:

scons godot_cpp=/path/to/godot-cpp

This commit also forces the new "disable_exceptions" godot cpp option to
false since exceptions are needed by libdatachannel, and makes sure to
always compile/link with dynamic runtime when using MSVC.
2024-04-13 13:36:22 +02:00
Fabio Alessandrelli
431df320c4 Merge pull request #142 from Faless/bump/libdatachannel_0.20.2
Update to libdatachannel 0.20.2
2024-04-12 19:36:37 +02:00
Fabio Alessandrelli
762f7cc5d2 Update to libdatachannel 0.20.2 2024-04-12 15:43:37 +02:00
Fabio Alessandrelli
66a9c6bab3 Merge pull request #141 from Ughuuu/logging-in-godot
Use Godot primitives for logging, change default log level
2024-04-12 15:39:06 +02:00
Dragos Daian
e391109df2 Use Godot primitives for logging, change default log level 2024-04-12 15:09:32 +02:00
Fabio Alessandrelli
762365d20a Merge pull request #138 from Faless/linux/arms
[Linux] Add arm32/arm64 linux builds support
2024-02-16 00:24:31 +01:00
Fabio Alessandrelli
34ef1043ee [Linux] Add arm32/arm64 linux builds support
Fix arch detection in GDNative builds (3.x) and add a small patch to
avoid warnings spam on ARM.

Make CMake march flags explicit for Linux arm32/arm64.

Add new platforms to CI.
2024-02-15 22:57:03 +01:00
Fabio Alessandrelli
7141bc487e Merge pull request #137 from Faless/ci/bump_actions
[CI] Update actions, use local copy of godot-cache
2024-02-10 04:57:31 +01:00
Fabio Alessandrelli
9520b23a4c [CI] Update actions, use local copy of godot-cache 2024-02-10 02:01:48 +01:00
Fabio Alessandrelli
cdb4673f48 Merge pull request #135 from Faless/bump/deps
Update to libdatachannel 0.20.1, OpenSSL 3.0.13
2024-02-01 17:01:31 +01:00
Fabio Alessandrelli
5b4221462b Update to libdatachannel 0.20.1, OpenSSL 3.0.13
Replace deprecated options with the (new) standard ones.
2024-01-30 16:33:25 +01:00
Fabio Alessandrelli
86d080b328 Merge pull request #134 from Faless/fix/mingw_only_export_init_symbol
[Windows/MinGW] Only export extension init symbol
2023-12-22 12:47:24 +01:00
Fabio Alessandrelli
1831677f63 [Windows/MinGW] Only export extension init symbol
When building for Windows using MinGW GCC we need to apply the same
workaround we use on Linux to only export the necessary symbols so we
can safely statically link libstdc++
2023-12-22 12:12:01 +01:00
Fabio Alessandrelli
fa28efa51d Merge pull request #133 from Faless/bump/openssl_3.0.12_libdatachannel_0.19.4
Update to OpenSSL 3.0.12, libdatachannel 0.19.4
2023-12-22 02:43:24 +01:00
Fabio Alessandrelli
6e33e43f36 Update to OpenSSL 3.0.12, libdatachannel 0.19.4 2023-12-22 02:13:41 +01:00
Fabio Alessandrelli
81239d820d Merge pull request #131 from Faless/fix/linux_only_export_init_symbol
[Linux] Only export extension init symbol
2023-12-22 02:10:20 +01:00
Fabio Alessandrelli
b0efc17d3b [Linux] Only export extension init symbol
Since we link with static libstdc++ we need to tell gcc to only export
the necessary symbols.
Using "-fvisibility=hidden" will not work, since libstdc++ explicitly
exports its symbols.
2023-12-22 01:30:01 +01:00
Fabio Alessandrelli
ec0ededcde Merge pull request #132 from Faless/fix/force_cleanup_on_unload
Call rtc::Cleanup when unloading the library
2023-12-22 01:14:07 +01:00
Fabio Alessandrelli
308db19120 Call rtc::Cleanup when unloading the library
Avoid potential crash at exit.
2023-12-21 21:39:53 +01:00
Fabio Alessandrelli
724910c734 Merge pull request #130 from Faless/spike/macos_framework
[MacOS] Use framekwork to package GDExtension
2023-12-21 18:48:23 +01:00
Fabio Alessandrelli
7a4e27e5f0 [MacOS] Use framekwork to package GDExtension
This allows it to be code-signed as a bundle so gatekeeper won't
complain when loaded by the editor.
2023-12-20 12:55:43 +01:00
Fabio Alessandrelli
d768508435 Merge pull request #129 from Faless/spike/to_string
Add _to_string method to extension classes.
2023-12-19 19:43:42 +01:00
Fabio Alessandrelli
fb2c9c3687 Add _to_string method to extension classes.
So printing them in Godot shows the proper class name instead of
"Wrapped".
2023-12-19 12:01:54 +01:00
Fabio Alessandrelli
cf23e5e740 Merge pull request #123 from Faless/bump/libdatachannel_0.19.3
Update libdatachannel to version 0.19.3
2023-10-22 11:51:14 +02:00
Fabio Alessandrelli
668d0250a7 Bump libdatachannel to version 0.19.3 2023-10-22 11:02:04 +02:00
Fabio Alessandrelli
121ed5664d Merge pull request #122 from Faless/bump/openssl_3.0.11
Update to  OpenSSL 3.0.11
2023-10-22 10:46:21 +02:00
Fabio Alessandrelli
67a378a667 Bump OpenSSL to version 3.0.11 2023-10-22 10:21:31 +02:00
Fabio Alessandrelli
023c42d3b3 Merge pull request #121 from Faless/fix/use_relative_paths
Use relative paths in webrtc.gdextension
2023-10-21 20:25:17 +02:00
Fabio Alessandrelli
6d96092f88 Use relative paths in webrtc.gdextension
Allows renaming the extension folder.
2023-10-21 18:14:09 +02:00
25 changed files with 954 additions and 96 deletions

22
.github/actions/godot-cache/action.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: Setup Godot build cache
description: Setup Godot build cache.
inputs:
cache-name:
description: The cache base name (job name by default).
default: "${{github.job}}"
scons-cache:
description: The scons cache path.
default: "${{github.workspace}}/.scons-cache/"
runs:
using: "composite"
steps:
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
uses: actions/cache@v4
with:
path: ${{inputs.scons-cache}}
key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install dependencies
run: |
@@ -64,37 +64,51 @@ jobs:
arch: 'x86_64'
gdnative_flags: 'ios_arch=x86_64'
sconsflags: 'ios_simulator=true'
os: 'macos-11'
os: 'macos-12'
cache-name: ios-x86_64-simulator
- platform: ios
arch: 'arm64'
gdnative_flags: 'ios_arch=arm64'
sconsflags: ''
os: 'macos-11'
os: 'macos-12'
cache-name: ios-arm64
# Linux
- platform: linux
arch: 'x86_32'
buildroot: 'i686'
buildroot: 'i686-godot-linux-gnu_sdk-buildroot'
gdnative_flags: 'bits=32'
sconsflags: ''
os: 'ubuntu-20.04'
cache-name: linux-x86_32
- platform: linux
arch: 'x86_64'
buildroot: 'x86_64'
buildroot: 'x86_64-godot-linux-gnu_sdk-buildroot'
gdnative_flags: 'bits=64'
sconsflags: ''
os: 'ubuntu-20.04'
cache-name: linux-x86_64
- platform: linux
arch: 'arm32'
buildroot: 'arm-godot-linux-gnueabihf_sdk-buildroot'
gdnative_flags: 'bits=32'
sconsflags: ''
os: 'ubuntu-20.04'
cache-name: linux-arm32
- platform: linux
arch: 'arm64'
buildroot: 'aarch64-godot-linux-gnu_sdk-buildroot'
gdnative_flags: 'bits=64'
sconsflags: ''
os: 'ubuntu-20.04'
cache-name: linux-arm64
# macOS
- platform: macos
arch: 'universal'
gdnative_flags: 'macos_arch=universal bits=64'
sconsflags: ''
os: 'macos-11'
os: 'macos-12'
cache-name: macos-universal
# Windows
@@ -115,19 +129,19 @@ 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:
shell: bash
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Godot build cache
uses: ./godot-cpp/.github/actions/godot-cache
uses: ./.github/actions/godot-cache
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
@@ -144,28 +158,22 @@ jobs:
dpkg -l | grep ii | grep mingw
update-alternatives --get-selections | grep mingw
- name: Setup Linux buildroot toolchain cache
if: ${{ matrix.platform == 'linux' }}
uses: actions/cache@v3
with:
path: |
${{ matrix.buildroot }}-godot-linux-gnu_sdk-buildroot.tar.bz2
key: linux-${{ matrix.buildroot }}-buildroot
- name: Install Linux build dependencies
if: ${{ matrix.platform == 'linux' }}
run: |
sudo apt-get update
sudo apt-get install build-essential gcc-multilib g++-multilib wget
if [ ! -f ${{ matrix.buildroot }}-godot-linux-gnu_sdk-buildroot.tar.bz2 ]; then
wget https://downloads.tuxfamily.org/godotengine/toolchains/linux/${{ matrix.buildroot }}-godot-linux-gnu_sdk-buildroot.tar.bz2
fi
tar -xjf ${{ matrix.buildroot }}-godot-linux-gnu_sdk-buildroot.tar.bz2
echo "$GITHUB_WORKSPACE/${{ matrix.buildroot }}-godot-linux-gnu_sdk-buildroot/bin" >> $GITHUB_PATH
patch -p1 < misc/patches/scons_path.diff
- name: Setup Linux buildroot toolchain cache
if: ${{ matrix.platform == 'linux' }}
uses: actions/cache@v4
with:
path: |
${{ matrix.buildroot }}.tar.bz2
key: linux-${{ matrix.buildroot }}-buildroot
- name: Set up Python 3.x
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x'
architecture: 'x64'
@@ -174,6 +182,28 @@ jobs:
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
- name: Setup Linux toolchains
if: ${{ matrix.platform == 'linux' }}
run: |
if [ ! -f ${{ matrix.buildroot }}.tar.bz2 ]; then
wget https://downloads.tuxfamily.org/godotengine/toolchains/linux/${{ matrix.buildroot }}.tar.bz2
fi
tar -xjf ${{ matrix.buildroot }}.tar.bz2
${{ matrix.buildroot }}/relocate-sdk.sh
echo "$GITHUB_WORKSPACE/${{ matrix.buildroot }}/bin" >> $GITHUB_PATH
echo "PKG_CONFIG=$GITHUB_WORKSPACE/${{ matrix.buildroot }}/share/pkgconfig/" >> $GITHUB_ENV
patch -p1 < misc/patches/scons_path.diff
patch -p1 < misc/patches/gdnantive_arm_warnings.diff
- name: Patch godot-cpp to support build profile.
run: |
patch -p1 < misc/patches/build_profile.diff
patch -p1 < misc/patches/build_profile_4.0.diff
patch -p1 < misc/patches/build_profile_3.x.diff
- name: Print tools versions
run: |
python --version
scons --version
cmake --version
@@ -198,7 +228,7 @@ jobs:
run: |
scons target=release generate_bindings=yes ${{ matrix.gdnative_flags }} godot_version=3
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: ${{ github.job }}-${{ matrix.platform }}-${{ matrix.arch }}
path: |
@@ -210,11 +240,11 @@ jobs:
needs: build
runs-on: "ubuntu-latest"
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
path: artifacts
@@ -241,17 +271,17 @@ jobs:
ls -R release
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: godot-webrtc-extension-4.1
path: release/*-extension-4.1-*.zip
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: godot-webrtc-extension-4.0
path: release/*-extension-4.0-*.zip
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: godot-webrtc-gdnative
path: release/*-gdnative-*.zip

View File

@@ -12,13 +12,31 @@ def add_sources(sources, dirpath, extension):
def replace_flags(flags, replaces):
for k, v in replaces.items():
if k in flags:
if k not in flags:
continue
if v is None:
flags.remove(k)
else:
flags[flags.index(k)] = v
def validate_godotcpp_dir(key, val, env):
normalized = val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)
if not os.path.isdir(normalized):
raise UserError("GDExtension directory ('%s') does not exist: %s" % (key, val))
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(
PathVariable(
"godot_cpp",
"Path to the directory containing Godot CPP folder",
None,
validate_godotcpp_dir,
)
)
opts.Update(env)
# Minimum target platform versions.
@@ -29,15 +47,19 @@ if "macos_deployment_target" not in ARGUMENTS:
if "android_api_level" not in ARGUMENTS:
ARGUMENTS["android_api_level"] = "28"
# Recent godot-cpp versions disables exceptions by default, but libdatachannel requires them.
ARGUMENTS["disable_exceptions"] = "no"
if env["godot_version"] == "3":
if "platform" in ARGUMENTS and ARGUMENTS["platform"] == "macos":
ARGUMENTS["platform"] = "osx" # compatibility with old osx name
env = SConscript("godot-cpp-3.x/SConstruct")
sconstruct = env.get("godot_cpp", "godot-cpp-3.x") + "/SConstruct"
cpp_env = SConscript(sconstruct)
# Patch base env
replace_flags(
env["CCFLAGS"],
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",
@@ -46,7 +68,7 @@ if env["godot_version"] == "3":
},
)
env = env.Clone()
env = cpp_env.Clone()
if env["target"] == "debug":
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
@@ -64,7 +86,7 @@ if env["godot_version"] == "3":
# Normalize suffix
if env["platform"] in ["windows", "linux"]:
env["arch"] = "x86_32" if env["bits"] == "32" else "x86_64"
env["arch"] = ARGUMENTS.get("arch", "x86_32" if env["bits"] == "32" else "x86_64")
env["arch_suffix"] = env["arch"]
elif env["platform"] == "macos":
env["arch"] = env["macos_arch"]
@@ -96,10 +118,23 @@ if env["godot_version"] == "3":
elif not env["use_mingw"]:
# Mark as MSVC build (would have failed to build the library otherwise).
env["is_msvc"] = True
# Some linux specific hacks to allow cross-compiling for non-x86 machines.
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":
env = SConscript("godot-cpp-4.0/SConstruct").Clone()
sconstruct = env.get("godot_cpp", "godot-cpp-4.0") + "/SConstruct"
cpp_env = SConscript(sconstruct)
env = cpp_env.Clone()
else:
env = SConscript("godot-cpp/SConstruct").Clone()
sconstruct = env.get("godot_cpp", "godot-cpp") + "/SConstruct"
cpp_env = SConscript(sconstruct)
env = cpp_env.Clone()
if cpp_env.get("is_msvc", False):
# Make sure we don't build with static cpp on MSVC (default in recent godot-cpp versions).
replace_flags(env["CCFLAGS"], {"/MT": "/MD"})
replace_flags(cpp_env["CCFLAGS"], {"/MT": "/MD"})
# Should probably go to upstream godot-cpp.
# We let SCons build its default ENV as it includes OS-specific things which we don't
@@ -120,18 +155,6 @@ if env["platform"] == "macos" and os.environ.get("OSXCROSS_ROOT", ""):
if env["macos_deployment_target"] != "default":
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = env["macos_deployment_target"]
# Patch linux flags to statically link libgcc and libstdc++
if env["platform"] == "linux":
env.Append(
LINKFLAGS=[
"-Wl,--no-undefined",
"-static-libgcc",
"-static-libstdc++",
]
)
# And add some linux dependencies.
env.Append(LIBS=["pthread", "dl"])
opts.Update(env)
target = env["target"]
@@ -175,9 +198,42 @@ rtc = env.BuildLibDataChannel(ssl)
# but it's better to be safe in case of indirect inclusions by one of our other dependencies.
env.Depends(sources, ssl + rtc)
# We want to statically link against libstdc++ on Linux to maximize compatibility, but we must restrict the exported
# symbols using a GCC version script, or we might end up overriding symbols from other libraries.
# Using "-fvisibility=hidden" will not work, since libstdc++ explicitly exports its symbols.
symbols_file = None
if env["platform"] == "linux" or (
env["platform"] == "windows" and env.get("use_mingw", False) and not env.get("use_llvm", False)
):
if env["godot_version"] == "3":
symbols_file = env.File("misc/gcc/symbols-gdnative.map")
else:
symbols_file = env.File("misc/gcc/symbols-extension.map")
env.Append(
LINKFLAGS=[
"-Wl,--no-undefined,--version-script=" + symbols_file.abspath,
"-static-libgcc",
"-static-libstdc++",
]
)
env.Depends(sources, symbols_file)
# Make the shared library
result_name = "libwebrtc_native{}{}".format(env["suffix"], env["SHLIBSUFFIX"])
library = env.SharedLibrary(target=os.path.join(result_path, "lib", result_name), source=sources)
if env["godot_version"] != "3" and env["platform"] == "macos":
framework_path = os.path.join(
result_path, "lib", "libwebrtc_native.macos.{}.{}.framework".format(env["target"], env["arch"])
)
library_file = env.SharedLibrary(target=os.path.join(framework_path, result_name), source=sources)
plist_file = env.Substfile(
os.path.join(framework_path, "Resources", "Info.plist"),
"misc/dist/macos/Info.plist",
SUBST_DICT={"{LIBRARY_NAME}": result_name, "{DISPLAY_NAME}": "libwebrtc_native" + env["suffix"]},
)
library = [library_file, plist_file]
else:
library = env.SharedLibrary(target=os.path.join(result_path, "lib", result_name), source=sources)
Default(library)
# GDNativeLibrary

11
build_profile.json Normal file
View File

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

28
misc/dist/macos/Info.plist vendored Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>{LIBRARY_NAME}</string>
<key>CFBundleIdentifier</key>
<string>org.godotengine.webrtc-native</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDisplayName</key>
<string>{DISPLAY_NAME}</string>
<key>CFBundleName</key>
<string>webrtc_native</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>1.0.0</string>
<key>LSMinimumSystemVersion</key>
<string>11.0</string>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
{
global:
webrtc_extension_init;
local:
*;
};

View File

@@ -0,0 +1,9 @@
{
global:
godot_gdnative_singleton;
godot_gdnative_init;
godot_gdnative_terminate;
godot_nativescript_init;
local:
*;
};

View File

@@ -0,0 +1,238 @@
diff --git a/godot-cpp/SConstruct b/godot-cpp/SConstruct
index 42f8fc0..9d59d1f 100644
--- a/godot-cpp/SConstruct
+++ b/godot-cpp/SConstruct
@@ -121,6 +121,14 @@ opts.Add(
BoolVariable("generate_bindings", "Force GDExtension API bindings generation. Auto-detected by default.", False)
)
opts.Add(BoolVariable("generate_template_get_node", "Generate a template version of the Node class's get_node.", 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))
opts.Add(EnumVariable("precision", "Set the floating-point precision level", "single", ("single", "double")))
diff --git a/godot-cpp/binding_generator.py b/godot-cpp/binding_generator.py
index d04c698..41cf29b 100644
--- a/godot-cpp/binding_generator.py
+++ b/godot-cpp/binding_generator.py
@@ -70,12 +70,14 @@ def generate_wrappers(target):
f.write(txt)
-def get_file_list(api_filepath, output_dir, headers=False, sources=False):
+def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
api = {}
files = []
with open(api_filepath, encoding="utf-8") as api_file:
api = json.load(api_file)
+ build_profile = parse_build_profile(profile_filepath, api)
+
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
source_gen_folder = Path(output_dir) / "gen" / "src"
@@ -104,7 +106,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
if headers:
files.append(str(header_filename.as_posix()))
- if sources:
+ if sources and is_class_included(engine_class["name"], build_profile):
files.append(str(source_filename.as_posix()))
for native_struct in api["native_structures"]:
@@ -134,14 +136,107 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
return files
-def print_file_list(api_filepath, output_dir, headers=False, sources=False):
+def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
end = ";"
- for f in get_file_list(api_filepath, output_dir, headers, sources):
+ for f in get_file_list(api_filepath, output_dir, headers, sources, profile_filepath):
print(f, end=end)
+def parse_build_profile(profile_filepath, api):
+ if profile_filepath == "":
+ return {}
+ print("Using feature build profile: " + profile_filepath)
+
+ 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)
+
+ # Parse methods dependencies
+ deps = {}
+ reverse_deps = {}
+ for name, engine_class in api_dict.items():
+ ref_cls = set()
+ for method in engine_class.get("methods", []):
+ rtype = method.get("return_value", {}).get("type", "")
+ args = [a["type"] for a in method.get("arguments", [])]
+ if rtype in api_dict:
+ ref_cls.add(rtype)
+ elif is_enum(rtype) and get_enum_class(rtype) in api_dict:
+ ref_cls.add(get_enum_class(rtype))
+ for arg in args:
+ if arg in api_dict:
+ ref_cls.add(arg)
+ elif is_enum(arg) and get_enum_class(arg) in api_dict:
+ ref_cls.add(get_enum_class(arg))
+ deps[engine_class["name"]] = set(filter(lambda x: x != name, ref_cls))
+ for acls in ref_cls:
+ if acls == name:
+ continue
+ reverse_deps[acls] = reverse_deps.get(acls, set())
+ reverse_deps[acls].add(name)
+
+ included = []
+ front = list(profile.get("enabled_classes", []))
+ if front:
+ # These must always be included
+ front.append("WorkerThreadPool")
+ front.append("ClassDB")
+ front.append("ClassDBSingleton")
+ while front:
+ cls = front.pop()
+ if cls in included:
+ continue
+ included.append(cls)
+ parent = parents.get(cls, "")
+ if parent:
+ front.append(parent)
+ for rcls in deps.get(cls, set()):
+ if rcls in included or rcls in front:
+ continue
+ front.append(rcls)
+
+ excluded = []
+ front = list(profile.get("disabled_classes", []))
+ while front:
+ cls = front.pop()
+ if cls in excluded:
+ continue
+ excluded.append(cls)
+ front += children.get(cls, [])
+ for rcls in reverse_deps.get(cls, set()):
+ if rcls in excluded or rcls in front:
+ continue
+ front.append(rcls)
+
+ 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 scons_emit_files(target, source, env):
- files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath and not Path(profile_filepath).is_absolute():
+ profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
+
+ files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
env.Clean(target, files)
env["godot_cpp_gen_dir"] = target[0].abspath
return files, source
@@ -154,11 +249,12 @@ def scons_generate_bindings(target, source, env):
"32" if "32" in env["arch"] else "64",
env["precision"],
env["godot_cpp_gen_dir"],
+ env.get("build_profile", ""),
)
return None
-def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
+def generate_bindings(api_filepath, use_template_get_node, bits="64", precision="single", output_dir=".", profile_filepath=""):
api = None
target_dir = Path(output_dir) / "gen"
@@ -175,7 +271,7 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
generate_global_constants(api, target_dir)
generate_global_constant_binds(api, target_dir)
generate_builtin_bindings(api, target_dir, real_t + "_" + bits)
- generate_engine_classes_bindings(api, target_dir, use_template_get_node)
+ generate_engine_classes_bindings(api, target_dir, use_template_get_node, profile_filepath)
generate_utility_functions(api, target_dir)
@@ -1023,7 +1119,7 @@ def generate_builtin_class_source(builtin_api, size, used_classes, fully_used_cl
return "\n".join(result)
-def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
+def generate_engine_classes_bindings(api, output_dir, use_template_get_node, profile_filepath=""):
global engine_classes
global singletons
global native_structures
@@ -1161,7 +1257,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
register_engine_classes_filename = Path(output_dir) / "src" / "register_engine_classes.cpp"
with register_engine_classes_filename.open("w+", encoding="utf-8") as source_file:
- source_file.write(generate_register_engine_classes_source(api))
+ source_file.write(generate_register_engine_classes_source(api, profile_filepath))
for native_struct in api["native_structures"]:
struct_name = native_struct["name"]
@@ -1585,12 +1681,14 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
return "\n".join(result)
-def generate_register_engine_classes_source(api):
+def generate_register_engine_classes_source(api, profile_filepath=""):
includes = []
registrations = []
+ build_profile = parse_build_profile(profile_filepath, api)
+
for class_api in api["classes"]:
- if class_api["name"] == "ClassDB":
+ if class_api["name"] == "ClassDB" or not is_class_included(class_api["name"], build_profile):
continue
class_name = class_api["name"]
@@ -2066,6 +2164,20 @@ def is_pod_type(type_name):
]
+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_included_type(type_name):
# Types which we already have implemented.
return is_included_struct_type(type_name) or type_name in ["ObjectID"]

View File

@@ -0,0 +1,196 @@
diff --git a/godot-cpp-3.x/SConstruct b/godot-cpp-3.x/SConstruct
index f653d54..44f66a5 100644
--- a/godot-cpp-3.x/SConstruct
+++ b/godot-cpp-3.x/SConstruct
@@ -170,6 +170,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: val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, 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..e5bd040 100644
--- a/godot-cpp-3.x/binding_generator.py
+++ b/godot-cpp-3.x/binding_generator.py
@@ -12,14 +12,115 @@ def correct_method_name(method_list):
method["name"] = "get_node_internal"
+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 parse_build_profile(profile_filepath, api):
+ if profile_filepath == "":
+ return {}
+ print("Using feature build profile: " + profile_filepath)
+
+ 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)
+
+ # Parse methods dependencies
+ deps = {}
+ reverse_deps = {}
+ for name, engine_class in api_dict.items():
+ ref_cls = set()
+ for method in engine_class.get("methods", []):
+ rtype = method.get("return_value", {}).get("type", "")
+ args = [a["type"] for a in method.get("arguments", [])]
+ if rtype in api_dict:
+ ref_cls.add(rtype)
+ for arg in args:
+ if arg in api_dict:
+ ref_cls.add(arg)
+ deps[engine_class["name"]] = set(filter(lambda x: x != name, ref_cls))
+ for acls in ref_cls:
+ if acls == name:
+ continue
+ reverse_deps[acls] = reverse_deps.get(acls, set())
+ reverse_deps[acls].add(name)
+
+ included = []
+ front = list(profile.get("enabled_classes", []))
+ if front:
+ # These must always be included
+ front.append("ConfigFile")
+ front.append("ClassDB")
+ while front:
+ cls = front.pop()
+ if cls in included:
+ continue
+ included.append(cls)
+ parent = parents.get(cls, "")
+ if parent:
+ front.append(parent)
+ for rcls in deps.get(cls, set()):
+ if rcls in included or rcls in front:
+ continue
+ front.append(rcls)
+
+ excluded = []
+ front = list(profile.get("disabled_classes", []))
+ while front:
+ cls = front.pop()
+ if cls in excluded:
+ continue
+ excluded.append(cls)
+ front += children.get(cls, [])
+ for rcls in reverse_deps.get(cls, set()):
+ if rcls in excluded or rcls in front:
+ continue
+ front.append(rcls)
+
+ 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,
+ }
+
+
classes = []
-def get_file_list(api_filepath, output_dir, headers=False, sources=False):
+def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
global classes
+
files = []
with open(api_filepath) as api_file:
classes = json.load(api_file)
+ build_profile = parse_build_profile(profile_filepath, classes)
+
include_gen_folder = Path(output_dir) / "include" / "gen"
source_gen_folder = Path(output_dir) / "src" / "gen"
for _class in classes:
@@ -27,7 +128,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
source_filename = source_gen_folder / (strip_name(_class["name"]) + ".cpp")
if headers:
files.append(str(header_filename.as_posix()))
- if sources:
+ if sources and is_class_included(_class["name"], build_profile):
files.append(str(source_filename.as_posix()))
icall_header_filename = include_gen_folder / "__icalls.hpp"
register_types_filename = source_gen_folder / "__register_types.cpp"
@@ -40,27 +141,32 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
return files
-def print_file_list(api_filepath, output_dir, headers=False, sources=False):
- for f in get_file_list(api_filepath, output_dir, headers, sources):
+def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
+ for f in get_file_list(api_filepath, output_dir, headers, sources, profile_filepath):
print(f, end=";")
def scons_emit_files(target, source, env):
- files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath and not Path(profile_filepath).is_absolute():
+ profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
+
+ files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
env.Clean(target, files)
env["godot_cpp_gen_dir"] = target[0].abspath
return files, source
def scons_generate_bindings(target, source, env):
- generate_bindings(str(source[0]), env["generate_template_get_node"], env["godot_cpp_gen_dir"])
+ generate_bindings(str(source[0]), env["generate_template_get_node"], env["godot_cpp_gen_dir"], env["build_profile"])
return None
-def generate_bindings(api_filepath, use_template_get_node, output_dir="."):
+def generate_bindings(api_filepath, use_template_get_node, output_dir=".", profile_filepath=""):
global classes
with open(api_filepath) as api_file:
classes = json.load(api_file)
+ build_profile = parse_build_profile(profile_filepath, classes)
icalls = set()
include_gen_folder = Path(output_dir) / "include" / "gen"
@@ -97,7 +203,7 @@ def generate_bindings(api_filepath, use_template_get_node, output_dir="."):
init_method_bindings_filename = source_gen_folder / "__init_method_bindings.cpp"
with init_method_bindings_filename.open("w+") as init_method_bindings_file:
- init_method_bindings_file.write(generate_init_method_bindings(classes))
+ init_method_bindings_file.write(generate_init_method_bindings(list(filter(lambda x: is_class_included(x["name"], build_profile), classes))))
def is_reference_type(t):

View File

@@ -0,0 +1,180 @@
diff --git a/godot-cpp-4.0/SConstruct b/godot-cpp-4.0/SConstruct
index 27ee137..ec2af72 100644
--- a/godot-cpp-4.0/SConstruct
+++ b/godot-cpp-4.0/SConstruct
@@ -119,6 +119,14 @@ opts.Add(
opts.Add(
BoolVariable("generate_bindings", "Force GDExtension API bindings generation. Auto-detected by default.", False)
)
+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("generate_template_get_node", "Generate a template version of the Node class's get_node.", True))
opts.Add(BoolVariable("build_library", "Build the godot-cpp library.", True))
diff --git a/godot-cpp-4.0/binding_generator.py b/godot-cpp-4.0/binding_generator.py
index 7634942..7ab51a5 100644
--- a/godot-cpp-4.0/binding_generator.py
+++ b/godot-cpp-4.0/binding_generator.py
@@ -70,12 +70,14 @@ def generate_wrappers(target):
f.write(txt)
-def get_file_list(api_filepath, output_dir, headers=False, sources=False):
+def get_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
api = {}
files = []
with open(api_filepath) as api_file:
api = json.load(api_file)
+ build_profile = parse_build_profile(profile_filepath, api)
+
core_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp" / "core"
include_gen_folder = Path(output_dir) / "gen" / "include" / "godot_cpp"
source_gen_folder = Path(output_dir) / "gen" / "src"
@@ -104,7 +106,7 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
source_filename = source_gen_folder / "classes" / (camel_to_snake(engine_class["name"]) + ".cpp")
if headers:
files.append(str(header_filename.as_posix()))
- if sources:
+ if sources and is_class_included(engine_class["name"], build_profile):
files.append(str(source_filename.as_posix()))
for native_struct in api["native_structures"]:
@@ -132,14 +134,107 @@ def get_file_list(api_filepath, output_dir, headers=False, sources=False):
return files
-def print_file_list(api_filepath, output_dir, headers=False, sources=False):
+def print_file_list(api_filepath, output_dir, headers=False, sources=False, profile_filepath=""):
end = ";"
- for f in get_file_list(api_filepath, output_dir, headers, sources):
+ for f in get_file_list(api_filepath, output_dir, headers, sources, profile_filepath):
print(f, end=end)
+def parse_build_profile(profile_filepath, api):
+ if profile_filepath == "":
+ return {}
+ print("Using feature build profile: " + profile_filepath)
+
+ 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)
+
+ # Parse methods dependencies
+ deps = {}
+ reverse_deps = {}
+ for name, engine_class in api_dict.items():
+ ref_cls = set()
+ for method in engine_class.get("methods", []):
+ rtype = method.get("return_value", {}).get("type", "")
+ args = [a["type"] for a in method.get("arguments", [])]
+ if rtype in api_dict:
+ ref_cls.add(rtype)
+ elif is_enum(rtype) and get_enum_class(rtype) in api_dict:
+ ref_cls.add(get_enum_class(rtype))
+ for arg in args:
+ if arg in api_dict:
+ ref_cls.add(arg)
+ elif is_enum(arg) and get_enum_class(arg) in api_dict:
+ ref_cls.add(get_enum_class(arg))
+ deps[engine_class["name"]] = set(filter(lambda x: x != name, ref_cls))
+ for acls in ref_cls:
+ if acls == name:
+ continue
+ reverse_deps[acls] = reverse_deps.get(acls, set())
+ reverse_deps[acls].add(name)
+
+ included = []
+ front = list(profile.get("enabled_classes", []))
+ if front:
+ # These must always be included
+ front.append("WorkerThreadPool")
+ front.append("ClassDB")
+ front.append("ClassDBSingleton")
+ while front:
+ cls = front.pop()
+ if cls in included:
+ continue
+ included.append(cls)
+ parent = parents.get(cls, "")
+ if parent:
+ front.append(parent)
+ for rcls in deps.get(cls, set()):
+ if rcls in included or rcls in front:
+ continue
+ front.append(rcls)
+
+ excluded = []
+ front = list(profile.get("disabled_classes", []))
+ while front:
+ cls = front.pop()
+ if cls in excluded:
+ continue
+ excluded.append(cls)
+ front += children.get(cls, [])
+ for rcls in reverse_deps.get(cls, set()):
+ if rcls in excluded or rcls in front:
+ continue
+ front.append(rcls)
+
+ 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 scons_emit_files(target, source, env):
- files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True)]
+ profile_filepath = env.get("build_profile", "")
+ if profile_filepath and not Path(profile_filepath).is_absolute():
+ profile_filepath = str((Path(env.Dir("#").abspath) / profile_filepath).as_posix())
+
+ files = [env.File(f) for f in get_file_list(str(source[0]), target[0].abspath, True, True, profile_filepath)]
env.Clean(target, files)
env["godot_cpp_gen_dir"] = target[0].abspath
return files, source
@@ -1997,6 +2092,20 @@ def is_pod_type(type_name):
]
+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_included_type(type_name):
# Types which we already have implemented.
return is_included_struct_type(type_name) or type_name in ["ObjectID"]

View File

@@ -0,0 +1,34 @@
diff --git a/godot-cpp-3.x/godot-headers/gdnative/gdnative.h b/godot-cpp-3.x/godot-headers/gdnative/gdnative.h
index c0573d21b5d7a..ec95c4c4ebfcc 100644
--- a/godot-cpp-3.x/godot-headers/gdnative/gdnative.h
+++ b/godot-cpp-3.x/godot-headers/gdnative/gdnative.h
@@ -37,20 +37,24 @@ extern "C" {
#if defined(_WIN32) || defined(__ANDROID__)
#define GDCALLINGCONV
-#define GDAPI GDCALLINGCONV
+
#elif defined(__APPLE__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE
#define GDCALLINGCONV __attribute__((visibility("default")))
-#define GDAPI GDCALLINGCONV
#elif TARGET_OS_MAC
#define GDCALLINGCONV __attribute__((sysv_abi))
-#define GDAPI GDCALLINGCONV
#endif
-#else // !_WIN32 && !__APPLE__
+
+#else // Linux/BSD/Web
+#if defined(__aarch64__) || defined(__arm__)
+#define GDCALLINGCONV
+#else
#define GDCALLINGCONV __attribute__((sysv_abi))
-#define GDAPI GDCALLINGCONV
#endif
+#endif
+
+#define GDAPI GDCALLINGCONV
// This is for libraries *using* the header, NOT GODOT EXPOSING STUFF!!
#if !defined(GDN_EXPORT)

View File

@@ -39,6 +39,8 @@ for f in "${files[@]}"; do
continue
elif [[ "$f" == "thirdparty/"* ]]; then
continue
elif [[ "$f" == "misc/patches/"* ]]; then
continue
elif [[ "$f" == *"/thirdparty/"* ]]; then
continue
elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then

View File

@@ -16,7 +16,7 @@ DESTDIR="${DESTINATION}/${VERSION}/${TYPE}"
mkdir -p ${DESTDIR}/lib
find "${ARTIFACTS}" -wholename "*/${VERSION}/${TYPE}/lib/*" | xargs cp -t "${DESTDIR}/lib/"
find "${ARTIFACTS}" -maxdepth 5 -wholename "*/${VERSION}/${TYPE}/lib/*" | xargs cp -r -t "${DESTDIR}/lib/"
find "${ARTIFACTS}" -wholename "*/LICENSE*" | xargs cp -t "${DESTDIR}/"
if [ $VERSION = "gdnative" ]; then

View File

@@ -5,26 +5,26 @@ compatibility_minimum = {GODOT_VERSION}
[libraries]
linux.debug.x86_64 = "res://webrtc/lib/libwebrtc_native.linux.template_debug.x86_64.so"
linux.debug.x86_32 = "res://webrtc/lib/libwebrtc_native.linux.template_debug.x86_32.so"
linux.debug.arm64 = "res://webrtc/lib/libwebrtc_native.linux.template_debug.arm64.so"
linux.debug.arm32 = "res://webrtc/lib/libwebrtc_native.linux.template_debug.arm32.so"
macos.debug = "res://webrtc/lib/libwebrtc_native.macos.template_debug.universal.dylib"
windows.debug.x86_64 = "res://webrtc/lib/libwebrtc_native.windows.template_debug.x86_64.dll"
windows.debug.x86_32 = "res://webrtc/lib/libwebrtc_native.windows.template_debug.x86_32.dll"
android.debug.arm64 = "res://webrtc/lib/libwebrtc_native.android.template_debug.arm64.so"
android.debug.x86_64 = "res://webrtc/lib/libwebrtc_native.android.template_debug.x86_64.so"
ios.debug.arm64 = "res://webrtc/lib/libwebrtc_native.ios.template_debug.arm64.dylib"
ios.debug.x86_64 = "res://webrtc/lib/libwebrtc_native.ios.template_debug.x86_64.simulator.dylib"
linux.debug.x86_64 = "lib/libwebrtc_native.linux.template_debug.x86_64.so"
linux.debug.x86_32 = "lib/libwebrtc_native.linux.template_debug.x86_32.so"
linux.debug.arm64 = "lib/libwebrtc_native.linux.template_debug.arm64.so"
linux.debug.arm32 = "lib/libwebrtc_native.linux.template_debug.arm32.so"
macos.debug = "lib/libwebrtc_native.macos.template_debug.universal.framework"
windows.debug.x86_64 = "lib/libwebrtc_native.windows.template_debug.x86_64.dll"
windows.debug.x86_32 = "lib/libwebrtc_native.windows.template_debug.x86_32.dll"
android.debug.arm64 = "lib/libwebrtc_native.android.template_debug.arm64.so"
android.debug.x86_64 = "lib/libwebrtc_native.android.template_debug.x86_64.so"
ios.debug.arm64 = "lib/libwebrtc_native.ios.template_debug.arm64.dylib"
ios.debug.x86_64 = "lib/libwebrtc_native.ios.template_debug.x86_64.simulator.dylib"
linux.release.x86_64 = "res://webrtc/lib/libwebrtc_native.linux.template_release.x86_64.so"
linux.release.x86_32 = "res://webrtc/lib/libwebrtc_native.linux.template_release.x86_32.so"
linux.release.arm64 = "res://webrtc/lib/libwebrtc_native.linux.template_release.arm64.so"
linux.release.arm32 = "res://webrtc/lib/libwebrtc_native.linux.template_release.arm32.so"
macos.release = "res://webrtc/lib/libwebrtc_native.macos.template_release.universal.dylib"
windows.release.x86_64 = "res://webrtc/lib/libwebrtc_native.windows.template_release.x86_64.dll"
windows.release.x86_32 = "res://webrtc/lib/libwebrtc_native.windows.template_release.x86_32.dll"
android.release.arm64 = "res://webrtc/lib/libwebrtc_native.android.template_release.arm64.so"
android.release.x86_64 = "res://webrtc/lib/libwebrtc_native.android.template_release.x86_64.so"
ios.release.arm64 = "res://webrtc/lib/libwebrtc_native.ios.template_release.arm64.dylib"
ios.release.x86_64 = "res://webrtc/lib/libwebrtc_native.ios.template_release.x86_64.simulator.dylib"
linux.release.x86_64 = "lib/libwebrtc_native.linux.template_release.x86_64.so"
linux.release.x86_32 = "lib/libwebrtc_native.linux.template_release.x86_32.so"
linux.release.arm64 = "lib/libwebrtc_native.linux.template_release.arm64.so"
linux.release.arm32 = "lib/libwebrtc_native.linux.template_release.arm32.so"
macos.release = "lib/libwebrtc_native.macos.template_release.universal.framework"
windows.release.x86_64 = "lib/libwebrtc_native.windows.template_release.x86_64.dll"
windows.release.x86_32 = "lib/libwebrtc_native.windows.template_release.x86_32.dll"
android.release.arm64 = "lib/libwebrtc_native.android.template_release.arm64.so"
android.release.x86_64 = "lib/libwebrtc_native.android.template_release.x86_64.so"
ios.release.arm64 = "lib/libwebrtc_native.ios.template_release.arm64.dylib"
ios.release.x86_64 = "lib/libwebrtc_native.ios.template_release.x86_64.simulator.dylib"

View File

@@ -6,10 +6,14 @@ reloadable = false
entry/OSX.64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.macos.{TARGET}.universal.dylib"
entry/Windows.64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.windows.{TARGET}.x86_64.dll"
entry/Windows.32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.windows.{TARGET}.x86_32.dll"
entry/X11.64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_64.so"
entry/X11.32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_32.so"
entry/Server.64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_64.so"
entry/Server.32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_32.so"
entry/X11.64.x86_64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_64.so"
entry/X11.32.x86_32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_32.so"
entry/X11.64.arm64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.arm64.so"
entry/X11.32.arm32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.arm32.so"
entry/Server.64.x86_64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_64.so"
entry/Server.32.x86_32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.x86_32.so"
entry/Server.64.arm64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.arm64.so"
entry/Server.32.arm32 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.linux.{TARGET}.arm32.so"
entry/Android.arm64-v8a = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.android.{TARGET}.arm64.so"
entry/Android.x64 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.android.{TARGET}.x86_64.so"
entry/iOS.armv7 = "res://{GDNATIVE_PATH}/lib/libwebrtc_native.ios.{TARGET}.armv32.dylib"

View File

@@ -143,12 +143,12 @@ int32_t WebRTCLibDataChannel::_get_id() const {
int32_t WebRTCLibDataChannel::_get_max_packet_life_time() const {
ERR_FAIL_COND_V(!channel, 0);
return channel->reliability().type == rtc::Reliability::Type::Timed ? std::get<std::chrono::milliseconds>(channel->reliability().rexmit).count() : -1;
return channel->reliability().maxPacketLifeTime.has_value() ? channel->reliability().maxPacketLifeTime.value().count() : -1;
}
int32_t WebRTCLibDataChannel::_get_max_retransmits() const {
ERR_FAIL_COND_V(!channel, 0);
return channel->reliability().type == rtc::Reliability::Type::Rexmit ? std::get<int>(channel->reliability().rexmit) : -1;
return channel->reliability().maxRetransmits.value_or(-1);
}
String WebRTCLibDataChannel::_get_protocol() const {

View File

@@ -74,6 +74,10 @@ private:
protected:
static void _bind_methods() {}
godot::String _to_string() const {
return "WebRTCLibDataChannel";
}
public:
static WebRTCLibDataChannel *new_data_channel(std::shared_ptr<rtc::DataChannel> p_channel, bool p_negotiated);

View File

@@ -39,15 +39,36 @@ using namespace godot_webrtc;
#define FAILED Error::FAILED
#define ERR_UNCONFIGURED Error::ERR_UNCONFIGURED
#define ERR_INVALID_PARAMETER Error::ERR_INVALID_PARAMETER
#define VERBOSE_PRINT(str) Godot::print(str)
#else
#include <godot_cpp/variant/utility_functions.hpp>
#define VERBOSE_PRINT(str) UtilityFunctions::print_verbose(str)
#endif
void LogCallback(rtc::LogLevel level, std::string message) {
switch (level) {
case rtc::LogLevel::Fatal:
case rtc::LogLevel::Error:
ERR_PRINT(message.c_str());
return;
case rtc::LogLevel::Warning:
WARN_PRINT(message.c_str());
return;
default:
VERBOSE_PRINT(message.c_str());
return;
}
}
void WebRTCLibPeerConnection::initialize_signaling() {
#ifdef DEBUG_ENABLED
rtc::InitLogger(rtc::LogLevel::Debug);
rtc::InitLogger(rtc::LogLevel::Debug, LogCallback);
#else
rtc::InitLogger(rtc::LogLevel::Warning, LogCallback);
#endif
}
void WebRTCLibPeerConnection::deinitialize_signaling() {
rtc::Cleanup();
}
Error WebRTCLibPeerConnection::_parse_ice_server(rtc::Configuration &r_config, Dictionary p_server) {
@@ -95,11 +116,9 @@ Error WebRTCLibPeerConnection::_parse_channel_config(rtc::DataChannelInit &r_con
// Channels cannot be both time-constrained and retry-constrained.
ERR_FAIL_COND_V(p_dict.has("maxPacketLifeTime") && p_dict.has("maxRetransmits"), ERR_INVALID_PARAMETER);
if (p_dict.has("maxPacketLifeTime")) {
r_config.reliability.type = rtc::Reliability::Type::Timed;
r_config.reliability.rexmit = std::chrono::milliseconds(p_dict["maxPacketLifeTime"].operator int32_t());
r_config.reliability.maxPacketLifeTime = std::chrono::milliseconds(p_dict["maxPacketLifeTime"].operator int32_t());
} else if (p_dict.has("maxRetransmits")) {
r_config.reliability.type = rtc::Reliability::Type::Rexmit;
r_config.reliability.rexmit = p_dict["maxRetransmits"].operator int32_t();
r_config.reliability.maxRetransmits = p_dict["maxRetransmits"].operator int32_t();
}
if (p_dict.has("ordered") && p_dict["ordered"].operator bool() == false) {
r_config.reliability.unordered = true;

View File

@@ -67,6 +67,10 @@ private:
protected:
static void _bind_methods() {}
godot::String _to_string() const {
return "WebRTCLibPeerConnection";
}
public:
static void _register_methods() {}
static void initialize_signaling();

14
thirdparty/README.md vendored
View File

@@ -8,7 +8,7 @@ readability.
## json
- Upstream: https://github.com/nlohmann/json
- Version: 3.10.5 (4f8fba14066156b73f1189a2b8bd568bde5284c5, 2022)
- Version: 3.11.3 (9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03, 2023)
- License: MIT
Module location:
@@ -19,7 +19,7 @@ Module location:
## libdatachannel
- Upstream: https://github.com/paullouisageneau/libdatachannel
- Version: 0.18.6 (bf8d8bd86afaffed89ba763107bcd8957c8cc319, 2023)
- Version: 0.22.1 (f8ffbe37e6c06e4838b41c2c018ccc3a8028a1c8, 2024)
- License: MPL 2.0
Module location:
@@ -30,7 +30,7 @@ Module location:
# libjuice
- Upstream: https://github.com/paullouisageneau/libjuice
- Version: 1.2.3 (8c23cc88c6d41e5ccbc44ea0ad3d79b22cf02361, 2023)
- 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.10 (245cb0291e0db99d9ccf3692fa76f440b2b054c2, 2023)
- Version: 3.4.0 (98acb6b02839c609ef5b837794e08d906d965335, 2024)
- License: Apache 2.0
Module location:
@@ -63,8 +63,8 @@ Module location:
## plog
- Upstream: https://github.com/SergiusTheBest/plog
- Version: git (d8461e9d473e59fbcc1f79eee021550dcf81e618, 2021)
- License: MPL 2.0
- Version: 1.1.10 (e21baecd4753f14da64ede979c5a19302618b752, 2023)
- License: MIT
Module location:
@@ -74,7 +74,7 @@ Module location:
## usrsctp
- Upstream: https://github.com/sctplab/usrsctp
- Version: git (7c31bd35c79ba67084ce029511193a19ceb97447, 2021)
- Version: git (ebb18adac6501bad4501b1f6dccb67a1c85cc299, 2023)
- License: BSD-3-Clause
Module location:

View File

@@ -37,6 +37,8 @@ def cmake_default_flags(env):
linux_flags = {
"x86_64": "-m64",
"x86_32": "-m32",
"arm32": "-march=armv7-a",
"arm64": "-march=armv8-a",
}.get(env["arch"], "")
if linux_flags:
config["CMAKE_C_FLAGS"] = linux_flags
@@ -47,10 +49,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

@@ -79,7 +79,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"]:
@@ -125,6 +133,8 @@ def build_openssl(env, jobs=None):
env.Prepend(LIBPATH=[env["SSL_BUILD"]])
if env["platform"] == "windows":
env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"])
if env["platform"] == "linux":
env.PrependUnique(LIBS=["pthread", "dl"])
env.Prepend(LIBS=env["SSL_LIBS"])
return [env["SSL_CRYPTO_LIBRARY"], env["SSL_LIBRARY"]]
@@ -169,6 +179,8 @@ def build_openssl(env, jobs=None):
env.Prepend(LIBPATH=[env["SSL_BUILD"]])
if env["platform"] == "windows":
env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"])
if env["platform"] == "linux":
env.PrependUnique(LIBS=["pthread", "dl"])
env.Prepend(LIBS=env["SSL_LIBS"])
return ssl

View File

@@ -37,6 +37,8 @@ def build_library(env, ssl):
# Configure env.
if env["platform"] == "windows":
env.PrependUnique(LIBS=["iphlpapi", "bcrypt"])
if env["platform"] == "linux":
env.PrependUnique(LIBS=["pthread"])
env.Prepend(LIBS=list(filter(lambda f: str(f).endswith(lib_ext), rtc)))
env.Append(CPPPATH=["#thirdparty/libdatachannel/include"])