diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2651e0d..3e50ecfa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,30 +5,57 @@ on: [push, pull_request] env: # Only used for the cache key. Increment version to force clean build. GODOT_BASE_BRANCH: master + SCONSFLAGS: target=editor build_profile=build_profile.json api_version=4.3 SCONS_CACHE: ${{ github.workspace }}/.scons-cache/ jobs: linux-x64: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 + env: + BUILDROOT: x86_64-godot-linux-gnu_sdk-buildroot steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: recursive - - name: Setup Godot build cache - uses: ./godot-cpp/.github/actions/godot-cache + - name: Restore Godot build cache + uses: ./godot-cpp/.github/actions/godot-cache-restore with: cache-name: linux-x86_64 + scons-cache: ${{ env.SCONS_CACHE }} continue-on-error: true + - name: Setup Linux buildroot toolchain cache + uses: actions/cache@v5 + with: + path: | + ${{ env.BUILDROOT }}.tar.bz2 + key: linux-${{ env.BUILDROOT }}-buildroot + continue-on-error: true + - name: Setup Linux toolchains + run: | + if [ ! -f ${{ env.BUILDROOT }}.tar.bz2 ]; then + wget https://github.com/godotengine/buildroot/releases/download/godot-2026.05.x-1/${{ env.BUILDROOT }}.tar.bz2 + fi + tar -xjf ${{ env.BUILDROOT }}.tar.bz2 + ${{ env.BUILDROOT }}/relocate-sdk.sh + rm ${{ env.BUILDROOT }}/bin/cmake + echo "$GITHUB_WORKSPACE/${{ env.BUILDROOT }}/bin" >> $GITHUB_PATH + echo "PKG_CONFIG=$GITHUB_WORKSPACE/${{ env.BUILDROOT }}/share/pkgconfig/" >> $GITHUB_ENV - name: Build for Linux editor x86_64 run: | pip3 install scons - scons platform=linux arch=x86_64 target=editor generate_bindings=yes + scons platform=linux arch=x86_64 ldd addons/godot-git-plugin/linux/*.so + - name: Save Godot build cache + uses: ./godot-cpp/.github/actions/godot-cache-save + with: + cache-name: linux-x86_64 + scons-cache: ${{ env.SCONS_CACHE }} + continue-on-error: true - name: Prepare artifact run: | mkdir out mv addons out/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: libgit_plugin.linux.x86_64.editor.so-${{ github.sha }} if-no-files-found: error @@ -38,21 +65,29 @@ jobs: windows-x64: runs-on: windows-2022 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: recursive - - name: Setup Godot build cache - uses: ./godot-cpp/.github/actions/godot-cache + - name: Restore Godot build cache + uses: ./godot-cpp/.github/actions/godot-cache-restore with: cache-name: windows-x86_64 + scons-cache: ${{ env.SCONS_CACHE }} + continue-on-error: true - uses: ilammy/msvc-dev-cmd@v1 # For dumpbin. - uses: ilammy/setup-nasm@v1 - name: Build for Windows editor x86_64 shell: powershell run: | pip3 install scons - scons platform=windows arch=x86_64 target=editor generate_bindings=yes + scons platform=windows arch=x86_64 dumpbin /dependents .\addons\godot-git-plugin\windows\*.dll + - name: Save Godot build cache + uses: ./godot-cpp/.github/actions/godot-cache-save + with: + cache-name: windows-x86_64 + scons-cache: ${{ env.SCONS_CACHE }} + continue-on-error: true - name: Prepare artifact shell: bash run: | @@ -60,7 +95,7 @@ jobs: rm -f addons/godot-git-plugin/windows/*.{exp,lib} mkdir out mv addons out/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: libgit_plugin.windows.x86_64.editor.dll-${{ github.sha }} if-no-files-found: error @@ -68,29 +103,33 @@ jobs: out/ macos-universal: - runs-on: macos-15 + runs-on: macos-latest steps: - - name: Setup Xcode 16.2 (16.3+ incompatible with libgit2's zlib) - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '16.2' - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: submodules: recursive - - name: Setup Godot build cache - uses: ./godot-cpp/.github/actions/godot-cache + - name: Restore Godot build cache + uses: ./godot-cpp/.github/actions/godot-cache-restore with: cache-name: macos-universal + scons-cache: ${{ env.SCONS_CACHE }} + continue-on-error: true - name: Build for macOS editor universal run: | pip install scons - scons platform=macos arch=universal target=editor generate_bindings=yes macos_deployment_target=10.13 + scons platform=macos arch=universal macos_deployment_target=10.13 otool -L addons/godot-git-plugin/macos/*.dylib + - name: Save Godot build cache + uses: ./godot-cpp/.github/actions/godot-cache-save + with: + cache-name: macos-universal + scons-cache: ${{ env.SCONS_CACHE }} + continue-on-error: true - name: Prepare artifact run: | mkdir out mv addons out/ - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: libgit_plugin.macos.universal.editor.dylib-${{ github.sha }} if-no-files-found: error diff --git a/.gitignore b/.gitignore index f46add85..7debfddd 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ build/ bin/ macos/ linux/ -win64/ +windows/ *.lib *.a *.obj diff --git a/SConstruct b/SConstruct index ad759fe0..78454694 100644 --- a/SConstruct +++ b/SConstruct @@ -23,7 +23,7 @@ if ARGUMENTS.get("custom_api_file", "") != "": ARGUMENTS["target"] = "editor" env = SConscript("godot-cpp/SConstruct").Clone() -env.PrependENVPath("PATH", os.getenv("PATH")) # Prepend PATH, done upstream in recent godot-cpp verions. +env.__class__.msvc = env.get("is_msvc", False) # Force linking with LTO on windows MSVC, silence the linker complaining that libgit uses LTO but we are not linking with it. if env["platform"] == "windows" and env.get("is_msvc", False): diff --git a/THIRDPARTY.md b/THIRDPARTY.md index 7b72b272..da3654f8 100644 --- a/THIRDPARTY.md +++ b/THIRDPARTY.md @@ -2,10 +2,10 @@ The Godot Git Plugin source code uses the following third-party source code: -1. godotengine/godot-cpp - MIT License - https://github.com/godotengine/godot-cpp/tree/02336831735fd6affbe0a6fa252ec98d3e78120c -2. libgit2/libgit2 - GPLv2 with a special Linking Exception - https://github.com/libgit2/libgit2/tree/b7bad55e4bb0a285b073ba5e02b01d3f522fc95d +1. godotengine/godot-cpp - MIT License - https://github.com/godotengine/godot-cpp/tree/58d1de720b8ffe9f8ffcdfe3a85148582cfd2e74 +2. libgit2/libgit2 - GPLv2 with a special Linking Exception - https://github.com/libgit2/libgit2/tree/26055f5af74ab1cf636d272e8a34315496d3f06f 3. libssh2/libssh2 - BSD-3-Clause License - https://github.com/libssh2/libssh2/tree/635caa90787220ac3773c1d5ba11f1236c22eae8 -4. openssl - OpenSSL License - https://github.com/openssl/openssl/tree/26baecb28ce461696966dac9ac889629db0b3b96 +4. openssl - OpenSSL License - https://github.com/openssl/openssl/tree/aae016bfd52fcad2bc9657c2c782cfdf73b1ed5f ## License Texts diff --git a/addons/godot-git-plugin/git_plugin.gdextension b/addons/godot-git-plugin/git_plugin.gdextension index 62cf890a..c936df92 100644 --- a/addons/godot-git-plugin/git_plugin.gdextension +++ b/addons/godot-git-plugin/git_plugin.gdextension @@ -1,7 +1,7 @@ [configuration] entry_symbol = "git_plugin_init" -compatibility_minimum = "4.2.0" +compatibility_minimum = "4.3" [libraries] diff --git a/build_profile.json b/build_profile.json new file mode 100644 index 00000000..ffec6070 --- /dev/null +++ b/build_profile.json @@ -0,0 +1,7 @@ +{ + "enabled_classes": [ + "OS", + "EditorVCSInterface", + "Window" + ] +} diff --git a/godot-cpp b/godot-cpp index 54136ee8..58d1de72 160000 --- a/godot-cpp +++ b/godot-cpp @@ -1 +1 @@ -Subproject commit 54136ee8357c5140a3775c54f08db5f7deda2058 +Subproject commit 58d1de720b8ffe9f8ffcdfe3a85148582cfd2e74 diff --git a/godot-git-plugin/src/git_plugin.h b/godot-git-plugin/src/git_plugin.h index eb2a7dd9..1ec17dac 100644 --- a/godot-git-plugin/src/git_plugin.h +++ b/godot-git-plugin/src/git_plugin.h @@ -8,6 +8,8 @@ #include "godot_cpp/classes/editor_vcs_interface.hpp" #include "git2.h" +#include + struct Credentials { godot::String username; godot::String password; diff --git a/thirdparty/git2/libgit2 b/thirdparty/git2/libgit2 index 3e2baa6d..26055f5a 160000 --- a/thirdparty/git2/libgit2 +++ b/thirdparty/git2/libgit2 @@ -1 +1 @@ -Subproject commit 3e2baa6d0bfb42f9016e24cba1733a6ae26a8ae6 +Subproject commit 26055f5af74ab1cf636d272e8a34315496d3f06f diff --git a/thirdparty/openssl b/thirdparty/openssl index 17a2c511..aae016bf 160000 --- a/thirdparty/openssl +++ b/thirdparty/openssl @@ -1 +1 @@ -Subproject commit 17a2c5111864d8e016c5f2d29c40a3746b559e9d +Subproject commit aae016bfd52fcad2bc9657c2c782cfdf73b1ed5f diff --git a/thirdparty/ssh2/libssh2_config.h b/thirdparty/ssh2/libssh2_config.h deleted file mode 100644 index e69de29b..00000000 diff --git a/tools/cmake.py b/tools/cmake.py index 9aa54cad..52edf15f 100644 --- a/tools/cmake.py +++ b/tools/cmake.py @@ -8,20 +8,30 @@ # 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 get_ndk_version(env): + return env["ndk_version"] def cmake_default_flags(env): if env.get("cmake_default_flags", ""): return shlex.split(env["cmake_default_flags"]) - config = {} + opt_level = env.get("optimize", "") + config = { + "CMAKE_BUILD_TYPE": "RELWITHDEBINFO" + if env.get("debug_symbols", True) + else ("MINSIZEREL" if opt_level == "size" else "RELEASE") + } + + if env.get("lto", "none") != "none": + config["CMAKE_INTERPROCEDURAL_OPTIMIZATION"] = "1" if "CC" in env: - config["CMAKE_C_COMPILER"] = env["CC"] + config["CMAKE_C_COMPILER"] = env["CC"] if os.name != "nt" else env.subst("$CC").replace("\\", "/") + ".exe" if "CXX" in env: - config["CMAKE_CXX_COMPILER"] = env["CXX"] + config["CMAKE_CXX_COMPILER"] = env["CXX"] if os.name != "nt" else env.subst("$CXX").replace("\\", "/") + ".exe" + if "RC" in env: + config["CMAKE_RC_COMPILER"] = env["RC"] if os.name != "nt" else env.subst("$RC").replace("\\", "/") + ".exe" if env["platform"] == "android": api = env["android_api_level"] @@ -35,7 +45,7 @@ def cmake_default_flags(env): config["CMAKE_SYSTEM_VERSION"] = api config["CMAKE_ANDROID_ARCH_ABI"] = abi config["ANDROID_ABI"] = abi - ndk_root = os.environ.get("ANDROID_NDK_ROOT", env.get("ANDROID_HOME", "") + "/ndk/" + get_ndk_version()) + ndk_root = os.environ.get("ANDROID_NDK_ROOT", env.get("ANDROID_HOME", "") + "/ndk/" + get_ndk_version(env)) config["CMAKE_TOOLCHAIN_FILE"] = "%s/build/cmake/android.toolchain.cmake" % ndk_root config["CMAKE_ANDROID_STL_TYPE"] = "c++_static" @@ -81,7 +91,7 @@ def cmake_default_flags(env): elif env["platform"] == "windows": config["CMAKE_SYSTEM_NAME"] = "Windows" - if env.get("is_msvc", False): + if env.msvc: config["CMAKE_POLICY_DEFAULT_CMP0091"] = "NEW" if env.get("debug_crt", False): config["CMAKE_MSVC_RUNTIME_LIBRARY"] = "MultiThreadedDebugDLL" @@ -95,6 +105,7 @@ def cmake_default_flags(env): def cmake_emitter(target, source, env): + env.SideEffect(env["CMAKELOCK"], target) return [str(target[0]) + "/CMakeCache.txt"] + target[1:], [str(source[0]) + "/CMakeLists.txt"] + source[1:] @@ -130,7 +141,10 @@ def cmake_build( else: f = df[2:].split("=")[0] if f in cmake_options: - df += " " + cmake_options[f] + if f == "CMAKE_BUILD_TYPE": + df = "-DCMAKE_BUILD_TYPE=" + cmake_options[f] + else: + df += " " + cmake_options[f] cmake_options.pop(f) flags.append(df) for opt in cmake_options: @@ -140,7 +154,7 @@ def cmake_build( if env["cmake_generator"]: flags.extend(["-G", env["cmake_generator"]]) elif env["platform"] == "windows": - if env.get("is_msvc", False): + if env.msvc: flags.extend(["-G", "NMake Makefiles"]) elif sys.platform in ["win32", "msys", "cygwin"]: flags.extend(["-G", "Ninja"]) @@ -158,6 +172,7 @@ def options(opts): opts.Add("cmake_default_flags", "Default CMake platform flags override, will be autodetected if not specified.", "") opts.Add("cmake_generator", "CMake generator override, will be autodetected from platform if not specified.", "") opts.Add("cmake", "CMake binary to use", "cmake") + opts.Add("emcmake", "Emscripten's cmake configuration helper to use (only in web builds)", "emcmake") def exists(env): @@ -166,12 +181,17 @@ def exists(env): def generate(env): env["CMAKE"] = env["cmake"] + env["EMCMAKE"] = env["emcmake"] env["CMAKECONFFLAGS"] = SCons.Util.CLVar("") env["CMAKECONFCOM"] = "$CMAKE -B ${TARGET.dir} $CMAKECONFFLAGS ${SOURCE.dir}" + if env.get("platform", "") == "web": + env["CMAKECONFCOM"] = "$EMCMAKE " + env["CMAKECONFCOM"] + env["CMAKEBUILDJOBS"] = "${__env__.GetOption('num_jobs')}" env["CMAKEBUILDFLAGS"] = SCons.Util.CLVar("") env["CMAKEINSTALLFLAGS"] = SCons.Util.CLVar("") env["CMAKEBUILDCOM"] = "$CMAKE --build ${TARGET.dir} $CMAKEBUILDFLAGS -j$CMAKEBUILDJOBS" env["CMAKEINSTALLCOM"] = "$CMAKE --install ${TARGET.dir} $CMAKEINSTALLFLAGS" env["BUILDERS"]["CMake"] = SCons.Builder.Builder(generator=cmake_generator, emitter=cmake_emitter) + env["CMAKELOCK"] = "#bin/cmake.lock" env.AddMethod(cmake_build, "CMakeBuild") diff --git a/tools/git2.py b/tools/git2.py index 92f1a982..39654584 100644 --- a/tools/git2.py +++ b/tools/git2.py @@ -9,26 +9,25 @@ def build_library(env, deps): "OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"], "OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"], "OPENSSL_ROOT_DIR": env["SSL_INSTALL"], - "BUILD_TESTS": 0, - "BUILD_CLI": 0, - "BUILD_EXAMPLES": 0, - "BUILD_FUZZERS": 0, - "USE_SSH": 1, - "USE_HTTPS": 1, - "USE_SHA1": 1, - "USE_BUNDLED_ZLIB": 1, + "BUILD_TESTS": "OFF", + "BUILD_CLI": "OFF", + "BUILD_EXAMPLES": "OFF", + "BUILD_FUZZERS": "OFF", + "USE_SSH": "ON", + "USE_HTTPS": "OpenSSL", + "USE_SHA1": "CollisionDetection", + "USE_BUNDLED_ZLIB": "ON", "USE_HTTP_PARSER": "builtin", "REGEX_BACKEND": "builtin", - "USE_HTTPS": "OpenSSL", - "USE_SHA1": "OpenSSL", "BUILD_SHARED_LIBS": 0, "LINK_WITH_STATIC_LIBRARIES": 1, - "LIBSSH2_INCLUDE_DIR": env.Dir("#thirdparty/ssh2/libssh2/include").abspath, - "LIBSSH2_LIBRARY": deps[-1], + "LIBSSH2_INCLUDE_DIRS": env.Dir("#thirdparty/ssh2/libssh2/include").abspath, + "LIBSSH2_RESOLVED": deps[-1].abspath, + "LIBSSH2_LIBRARIES": "LIBSSH2", + "LIBSSH2_FOUND": 1, "USE_WINHTTP": 0, "STATIC_CRT": env.get("use_static_cpp", True), "CMAKE_DISABLE_FIND_PACKAGE_ZLIB": 1, - "CMAKE_DISABLE_FIND_PACKAGE_OPENSSL": 1, } if env["platform"] != "windows": @@ -57,6 +56,8 @@ def build_library(env, deps): env.Prepend(LIBS=git2[1:]) if env["platform"] == "windows": env.PrependUnique(LIBS=["secur32"]) + elif env["platform"] == "macos": + env.Append(LIBS=["iconv"]) return git2 diff --git a/tools/openssl.py b/tools/openssl.py index 99a2426e..900f5e04 100644 --- a/tools/openssl.py +++ b/tools/openssl.py @@ -1,9 +1,11 @@ -import os, sys -import SCons.Util -import SCons.Builder +import os +import sys + import SCons.Action +import SCons.Builder +import SCons.Util from SCons.Defaults import Mkdir -from SCons.Variables import PathVariable, BoolVariable +from SCons.Variables import PathVariable def ssl_platform_target(env): @@ -79,8 +81,14 @@ 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["macos_deployment_target"] != "default": + 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: @@ -127,6 +135,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"]] @@ -171,6 +181,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 @@ -229,7 +241,10 @@ def generate(env): # Check if the user specified infos about external OpenSSL files. external_opts = ["openssl_external_crypto", "openssl_external_ssl", "openssl_external_include"] - is_set = lambda k: env.get(k, "") != "" + + def is_set(k): + return env.get(k, "") != "" + if any(map(is_set, external_opts)): # Need provide the whole (crypto, ssl, include) triple to proceed. if not all(map(is_set, external_opts)): diff --git a/tools/ssh2.py b/tools/ssh2.py index 9380728a..6bffaad3 100644 --- a/tools/ssh2.py +++ b/tools/ssh2.py @@ -13,7 +13,6 @@ def build_library(env, deps): "BUILD_TESTING": 0, "BUILD_SHARED_LIBS": 0, "CMAKE_DISABLE_FIND_PACKAGE_ZLIB": 1, - "CMAKE_DISABLE_FIND_PACKAGE_OPENSSL": 1, "CRYPTO_BACKEND": "OpenSSL", "CMAKE_POLICY_VERSION_MINIMUM": 3.5, }