Compare commits

...

44 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
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
29 changed files with 937 additions and 140 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

@@ -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:
@@ -11,7 +13,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install dependencies
run: |
@@ -64,37 +66,51 @@ 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
- 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-latest'
cache-name: macos-universal
# Windows
@@ -115,19 +131,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 +160,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,31 +184,51 @@ 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://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
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: 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
scons --version
cmake --version
- 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: |
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
@@ -235,23 +265,17 @@ 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@v3
- uses: actions/upload-artifact@v4
with:
name: godot-webrtc-extension-4.1
path: release/*-extension-4.1-*.zip
name: godot-webrtc-extension
path: release/*-extension-*.zip
- uses: actions/upload-artifact@v3
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

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

@@ -12,41 +12,63 @@ 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(EnumVariable("godot_version", "The Godot target version", "4", ["3", "4"], {"4.1+": "4", "4.1": "4"}))
opts.Add(
PathVariable(
"godot_cpp",
"Path to the directory containing Godot CPP folder",
None,
validate_godotcpp_dir,
)
)
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:
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",
"-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",
},
)
env = env.Clone()
env = cpp_env.Clone()
if env["target"] == "debug":
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
@@ -60,11 +82,11 @@ 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"]:
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,19 @@ 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
elif env["godot_version"] == "4.0":
env = SConscript("godot-cpp-4.0/SConstruct").Clone()
# 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})
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,27 +151,13 @@ 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"]
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/"])
@@ -158,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"]:
@@ -175,9 +190,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
@@ -193,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

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,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

@@ -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

@@ -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

@@ -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

@@ -1,7 +1,7 @@
[configuration]
entry_symbol = "webrtc_extension_init"
compatibility_minimum = {GODOT_VERSION}
compatibility_minimum = 4.1
[libraries]
@@ -9,7 +9,7 @@ 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.dylib"
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"
@@ -21,7 +21,7 @@ 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.dylib"
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"

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;
@@ -180,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

@@ -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();
@@ -79,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);

10
thirdparty/README.md vendored
View File

@@ -8,7 +8,7 @@ readability.
## json
- Upstream: https://github.com/nlohmann/json
- Version: 3.11.2 (bc889afb4c5bf1c0d8ee29ef35eaaf4c8bef8a5d, 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.19.3 (2cea8358c7d8381c9af2caf06cee0f72ebb91b1b, 2023)
- 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.3 (5f753cad49059cea4eb492eb5c11a3bbb4dd6324, 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.11 (6ba3884c3235e1bb474b379026087f8216afacf4, 2023)
- Version: 3.4.0 (98acb6b02839c609ef5b837794e08d906d965335, 2024)
- License: Apache 2.0
Module location:
@@ -74,7 +74,7 @@ Module location:
## usrsctp
- Upstream: https://github.com/sctplab/usrsctp
- Version: git (5ca29ac7d8055802c7657191325c06386640ac24, 2023)
- Version: git (ebb18adac6501bad4501b1f6dccb67a1c85cc299, 2023)
- License: BSD-3-Clause
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,15 +33,16 @@ 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":
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 +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"]:
@@ -125,6 +138,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 +184,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
@@ -252,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

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"])