51 Commits

Author SHA1 Message Date
Hugo Locurcio
b26312f1c1 Bump to version 3.2.1 2025-09-17 16:51:12 +02:00
Rémi Verschelde
d427b556e2 Merge pull request #305 from akien-mga/libssh2-cmake-4.0
CI: Fix build on macOS 15 runner with CMake 4.0 and Xcode 16.4
2025-09-17 12:57:31 +02:00
Rémi Verschelde
77fdf78793 CI: Fix build on macOS 15 runner with CMake 4.0 and Xcode 16.4
- Enforce min CMake version targeted for libssh2
- Downgrade Xcode to 16.2 as that's the last version before upgrading to LLVM 19
  which seems to break building libgit2's bundled zlib
2025-09-17 12:42:53 +02:00
Rémi Verschelde
1a851f221b Merge pull request #292 from Calinou/add-issue-templates
Add issue templates
2025-09-17 11:08:48 +02:00
Nikita
182f2f7146 Update OpenSSL to 3.1.2 (#298) 2025-07-25 17:30:51 +02:00
Hugo Locurcio
27c1152cb0 Add issue templates
These issue templates are inspired by the ones from godot-vscode-plugin.
2025-06-03 19:01:26 +02:00
Rémi Verschelde
b51e8ee42a Merge pull request #290 from Faless/fix/disable_zlib_detection
ssh2: Disable zlib detection
2025-05-31 00:58:30 +02:00
Fabio Alessandrelli
94db3a7c36 ssh2: Disable zlib detection
This seems to only be used with the OpenSSL backend (which we plan to
drop).

libgit2 already use builtin ZLIB, I'm not even sure we if it would be
used in libssh2 (we only use libssh2 to provide git ssh access, and git
already compress objects.
2025-05-31 00:43:58 +02:00
Rémi Verschelde
179e3ddb00 Merge pull request #289 from akien-mga/misc-fixes
Misc fixes and cleanup
2025-05-28 23:03:10 +02:00
Rémi Verschelde
2a4c781e86 Misc fixes and cleanup
- Remove the `demo` project which isn't really useful.
  * Instead the `addons` subfolder is made top-level and that's where stuff gets written.
- Update the README following recent PRs (#191, #199) as OpenSSL is now compiled from source for all platforms.
  * Also remove obsolete `build_openssl_universal_macos.sh` script.
- Remove the bogus `plugin.cfg` which isn't necessary, and was confusing users who tried to enable it.
  * Fixes #267.
- Bump min SCons version to 3.1.2 and Python to 3.6.
- Bump `compatibility_minimum` to `4.2.0` following #196.
- Remove some code in `godot-git-plugin/SCsub` that seems redundant with `godot-cpp` config.
- Remove unnecessary `.exp` and `.lib` files in Windows artifact, rename its folder to `windows`.
- Remove `export-ignore`s in `.gitattributes`, they're incomplete and not actually doing anything usable.
- Fix artifacts URL handling in `release.sh`, make it executable.
- CI: Update clang-format check to version 18.
2025-05-28 22:52:21 +02:00
Rémi Verschelde
fd85a8ef39 Merge pull request #288 from akien-mga/ci-cleanup
CI: Don't install openssl for macOS + misc cleanup
2025-05-27 17:29:49 +02:00
Rémi Verschelde
f322436f66 CI: Don't install openssl for macOS + misc cleanup 2025-05-27 17:18:41 +02:00
Rémi Verschelde
78d6464745 Merge pull request #286 from Faless/build/force_msvc_lto
Force LTO on windows MSVC as libgit2 requires it
2025-05-27 15:38:05 +02:00
Rémi Verschelde
91bb644dd4 Merge pull request #287 from Faless/build/fix_macos_deployment_target
Force macOS deployment target for OpenSSL when specified
2025-05-27 14:17:09 +02:00
Rémi Verschelde
1e346f89fa Merge pull request #285 from Faless/build/fix_libgit_tool
Properly specify the `STATIC_CRT` libgit2 flag
2025-05-27 14:01:19 +02:00
Fabio Alessandrelli
9a43d562c0 Force macOS deployment target for OpenSSL when specified 2025-05-27 12:24:54 +02:00
Fabio Alessandrelli
f6f2db53a9 Force LTO on windows MSVC
This silences the linker complaining that libgit uses LTO but we are not
linking with it.
2025-05-27 12:20:59 +02:00
Fabio Alessandrelli
c7c7822191 Properly specify the STATIC_CRT libgit2 flag
libgit2 CMake configuration uses a custom flag `STATIC_CRT` and not the
new CMake policy CMP0091.

When forcing the CMake policy (as we do in our cmake tool), we need to
also set the custom `STATIC_CRT` to avoid compiler warning about the /MD
and /MT flag being overridden.
2025-05-27 11:53:22 +02:00
Rémi Verschelde
392b3d6697 Merge pull request #283 from akien-mga/ci-windows-fail-on-error
CI: Ensure Windows job fails on error
2025-05-27 10:38:58 +02:00
Rémi Verschelde
51dcc3c455 CI: Ensure Windows job fails on error
Default `pwsh` is apparently not properly configured to fail fast,
but `powershell` is, whatever is the difference.

Minor tweaks to CI setup.
2025-05-27 10:27:17 +02:00
Rémi Verschelde
4fdf03d471 Merge pull request #284 from Faless/fix/win_build
Fix Windows MSVC build
2025-05-27 09:36:25 +02:00
Fabio Alessandrelli
1442ac5f0b Fix Windows MSVC build
Update the CMake tool so it respects the use_static_cpp godot-cpp option
compiling with the proper CRT.

Fix inclusion of secur32 in git2 tool.
2025-05-27 01:24:04 +02:00
Rémi Verschelde
3ab9d035e7 Merge pull request #199 from Faless/build/openssl_and_cmake
Use OpenSSL on windows too, build libgit2, ssh2 with cmake.
2025-05-26 18:02:46 +02:00
Fabio Alessandrelli
0d0c30784d Use OpenSSL on windows too, build libgit2, ssh2 with cmake.
And update the libraries.
2025-05-26 17:17:29 +02:00
Rémi Verschelde
ef24a3673d Merge pull request #191 from Faless/build/openssl
[SCons] Build OpenSSL from source.
2025-05-26 17:02:24 +02:00
Fabio Alessandrelli
955ec02503 [SCons] Build OpenSSL from source by default
Remove prebuilt static libraries for macOS.

Can optionally still use external (static) libraries by supplying the
`openssl_external_*` parameters to scons.
2025-05-26 16:57:27 +02:00
Rémi Verschelde
b8d79c3fc9 Merge pull request #246 from dsnopek/godot-cpp-41-branch
Update godot-cpp to `godot-4.2-stable`
2025-05-26 16:14:24 +02:00
David Snopek
900e95db82 Update godot-cpp to the latest on the 4.2 branch 2025-05-26 09:02:51 -05:00
Rémi Verschelde
9544fb84ec Merge pull request #272 from dsnopek/update-ci-versions
Update various out-dated versions in CI
2025-05-25 15:41:03 +02:00
David Snopek
edcfc47af0 Update various out-dated versions in CI
Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
2025-05-25 15:29:15 +02:00
Joel Croteau
e86106b8c2 Stop progress_cb from generating spurious warnings (#243)
`progress_cb` is used to give progress updates on pushes and pulls. There is
no reason for it to pollute the logs by logging its updates as warnings.
Changed these to plain print statements.
2024-07-07 05:15:37 +02:00
Hugo Locurcio
f6002fab42 Bump to version 3.1.1 (#231) 2024-04-08 18:29:04 +02:00
markeel
d6582fa939 Use UTF-8 conversion when dealing with Git repository data (#229)
This fixes issues with non-ASCII characters not displaying correctly
throughout the editor.
2024-04-08 17:46:50 +02:00
Hugo Locurcio
259ae989f4 Merge pull request #195 from Faless/ci/cache
[CI] Add scons cache.
2024-02-02 17:11:02 +01:00
Twarit Waikar
2f160a2b79 Merge pull request #189 from fries1234/fix-comparison-bug
fix a comparision bug with renamed git statuses
2023-10-03 20:09:42 +05:30
Hugo Locurcio
55b09bf0f7 Merge pull request #198 from jokoho48/gd4_1 2023-09-22 21:47:26 +02:00
Jonas Hoffmann
ae2f2d3826 Add Godot 4.1 Support
- Update godot-cpp
- Fix Entry Point that changed within Godot 4.1
- Add compatibility_minimum to gdextension required for 4.1 support
- Bump version in plugin.cfg
- Upgrade demo project to 4.1
2023-07-12 22:12:15 +02:00
Fabio Alessandrelli
3ab28b1d33 [CI] Add scons cache. 2023-06-24 18:39:14 +02:00
Twarit Waikar
3fc541feb8 Merge pull request #173 from markeel/master
Address issue #172, to use public key path if present in preference to using password.
2023-05-25 12:58:09 +05:30
markeel
04602dc5dc Merge pull request #1 from markeel/workflow-error
Update build.yml
2023-05-24 14:14:41 -07:00
markeel
bb5da70aa4 Update build.yml
Fix ubuntu version to match godot-cpp
2023-05-24 13:30:47 -07:00
Fries
4cb6ec0edd fix a comparision bug with renamed git statuses
there is a bug where if you have a entry->status with GIT_STATUS_INDEX_RENAMED but with another flag like GIT_STATUS_INDEX_MODIFIED, godot-git-plugin will crash as it cant find the proper map for 2 flags. so i changed it to do a logical and so it can execute the proper renamed logic.
2023-05-18 23:28:08 -07:00
mendrak
34850841fc Updated to remove extra line and pass clang format check 2023-03-26 20:44:58 -07:00
mendrak
74342b298e Address issue #172, to use public key path if present in preference
to using password.
2023-03-25 09:36:43 -07:00
Rémi Verschelde
3c50df7af0 Merge pull request #165 from godotengine/update-4.0-stable
Update extension API to Godot 4.0-stable
2023-03-01 15:58:22 +01:00
Rémi Verschelde
65a643c8d8 Update extension API to Godot 4.0-stable 2023-03-01 15:36:13 +01:00
Twarit Waikar
6a4b23a2c0 Merge pull request #149 from ianling/ian/update-libssh2 2023-02-26 17:01:17 +05:30
Rémi Verschelde
63d72ffc21 Merge pull request #161 from godotengine/update-4.0-rc4
Update extension API to Godot 4.0-rc4
2023-02-23 23:04:30 +01:00
Rémi Verschelde
6a6f7d1810 Update extension API to Godot 4.0-rc4
Remove `ci/` directory, everything is included in godot-cpp.
2023-02-23 18:57:58 +01:00
Ian Ling
f22b2e6bf5 Update libssh2 to HEAD of master 2023-01-04 17:04:45 -08:00
Twarit Waikar
820c623912 Happy new year! 2023-01-02 13:56:26 +05:30
41 changed files with 906 additions and 267450 deletions

12
.gitattributes vendored
View File

@@ -1,14 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf
# Ignore some files when exporting to a ZIP.
/.github/ export-ignore
/godot-cpp/ export-ignore
/godot-git-plugin/ export-ignore
/thirdparty/ export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.gitmodules export-ignore
/api.ci.json export-ignore
/build_openssl_universal_oxs.sh export-ignore
/SConstruct export-ignore

59
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: Bug report
description: Report a bug in Godot Git Plugin
labels:
- bug
body:
- type: markdown
attributes:
value: |
- Write a descriptive issue title above.
- Search [open](https://github.com/godotengine/godot-git-plugin/issues) and [closed](https://github.com/godotengine/godot-git-plugin/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported.
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html).
- This repository only contains the Git integration. Issues pertaining to the Godot editor itself or the general version control UI should be reported on the [main Godot repository](https://github.com/godotengine/godot/issues).
- type: input
attributes:
label: Godot version
description: >
Specify the Git commit hash if using a development or non-official build.
If you use a custom build, please test if your issue is reproducible in official builds too.
placeholder: 4.4.1.stable, 4.5.dev4 (209a446e3)
validations:
required: true
- type: input
attributes:
label: Godot Git Plugin version
description: >
Specify the Git commit hash if using a development or non-official build.
If you use a custom build, please test if your issue is reproducible in official builds too.
placeholder: "3.2.1"
validations:
required: true
- type: input
attributes:
label: System information
description: |
Specify the OS version, and when relevant hardware information.
placeholder: Windows 10
validations:
required: true
- type: textarea
attributes:
label: Issue description
description: |
Describe your issue briefly. What doesn't work, and how do you expect it to work instead?
You can include images or videos with drag and drop, and format code blocks or logs with <code>```</code> tags.
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: |
List of steps or sample code that reproduces the issue. Having reproducible issues is a prerequisite for contributors to be able to solve them.
validations:
required: true

6
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: Godot community channels
url: https://godotengine.org/community
about: Please ask for technical support on one of the other community channels, not here.

View File

@@ -0,0 +1,59 @@
name: Feature request
description: Request a new feature to be added or improved in Godot Git Plugin
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
- Write a descriptive issue title above.
- Search [open](https://github.com/godotengine/godot-git-plugin/issues) and [closed](https://github.com/godotengine/godot-git-plugin/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported.
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html).
- This repository only contains the Git integration. Issues pertaining to the Godot editor itself or the general version control UI should be reported on the [main Godot repository](https://github.com/godotengine/godot/issues).
- type: input
attributes:
label: Godot version
description: >
Specify the Git commit hash if using a development or non-official build.
If you use a custom build, please test if your issue is reproducible in official builds too.
placeholder: 4.4.1.stable, 4.5.dev4 (209a446e3)
validations:
required: true
- type: input
attributes:
label: Godot Git Plugin version
description: >
Specify the Git commit hash if using a development or non-official build.
If you use a custom build, please test if your issue is reproducible in official builds too.
placeholder: "3.2.1"
validations:
required: true
- type: input
attributes:
label: System information
description: |
Specify the OS version, and when relevant hardware information.
placeholder: Windows 10
validations:
required: true
- type: textarea
attributes:
label: Problem statement
description: |
Describe the problem or limitation you're currently facing with the Godot Git Plugin.
validations:
required: true
- type: textarea
attributes:
label: Proposed solution
description: |
Describe your proposed solution and how it resolves the problem or limitation mentioned above.
You can include images or videos with drag and drop, and format code blocks or logs with <code>```</code> tags.
validations:
required: true

View File

@@ -2,59 +2,97 @@ name: C/C++ CI
on: [push, pull_request]
env:
# Only used for the cache key. Increment version to force clean build.
GODOT_BASE_BRANCH: master
SCONS_CACHE: ${{ github.workspace }}/.scons-cache/
jobs:
linux-x64:
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- name: build-linux-editor-x64
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Godot build cache
uses: ./godot-cpp/.github/actions/godot-cache
with:
cache-name: linux-x86_64
continue-on-error: true
- name: Build for Linux editor x86_64
run: |
git submodule update --init --recursive
pip3 install --user scons
scons platform=linux target=editor generate_bindings=yes gdextension_dir="../ci/" -j $(nproc)
ldd demo/addons/godot-git-plugin/linux/*.so
- uses: actions/upload-artifact@v2
pip3 install scons
scons platform=linux arch=x86_64 target=editor generate_bindings=yes
ldd addons/godot-git-plugin/linux/*.so
- name: Prepare artifact
run: |
mkdir out
mv addons out/
- uses: actions/upload-artifact@v4
with:
name: libgit_plugin.linux.x86_64.editor.so-${{ github.sha }}
if-no-files-found: error
path: |
demo/
out/
windows-x64:
runs-on: windows-2019
runs-on: windows-2022
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v4
with:
python-version: "3.x"
architecture: "x64"
- uses: ilammy/msvc-dev-cmd@v1
- name: build-windows-editor-x64
submodules: recursive
- name: Setup Godot build cache
uses: ./godot-cpp/.github/actions/godot-cache
with:
cache-name: windows-x86_64
- uses: ilammy/msvc-dev-cmd@v1 # For dumpbin.
- uses: ilammy/setup-nasm@v1
- name: Build for Windows editor x86_64
shell: powershell
run: |
git submodule update --init --recursive
pip3 install --user scons
scons platform=windows target=editor generate_bindings=yes gdextension_dir="../ci/" -j $env:NUMBER_OF_PROCESSORS
dumpbin /dependents .\demo\addons\godot-git-plugin\win64\*.dll
- uses: actions/upload-artifact@v2
pip3 install scons
scons platform=windows arch=x86_64 target=editor generate_bindings=yes
dumpbin /dependents .\addons\godot-git-plugin\windows\*.dll
- name: Prepare artifact
shell: bash
run: |
# Not needed to use the plugin.
rm -f addons/godot-git-plugin/windows/*.{exp,lib}
mkdir out
mv addons out/
- uses: actions/upload-artifact@v4
with:
name: libgit_plugin.windows.x86_64.editor.dll-${{ github.sha }}
if-no-files-found: error
path: |
demo/
out/
macos-universal:
runs-on: macos-11
runs-on: macos-15
steps:
- uses: actions/checkout@v2
- name: build-macos-editor-universal
- 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
with:
submodules: recursive
- name: Setup Godot build cache
uses: ./godot-cpp/.github/actions/godot-cache
with:
cache-name: macos-universal
- name: Build for macOS editor universal
run: |
git submodule update --init --recursive
brew install scons
scons platform=macos target=editor generate_bindings=yes gdextension_dir="../ci/" macos_arch=universal use_llvm=yes macos_deployment_target=10.13 -j $(sysctl -n hw.logicalcpu)
otool -L demo/addons/godot-git-plugin/macos/*.dylib
- uses: actions/upload-artifact@v2
pip install scons
scons platform=macos arch=universal target=editor generate_bindings=yes macos_deployment_target=10.13
otool -L addons/godot-git-plugin/macos/*.dylib
- name: Prepare artifact
run: |
mkdir out
mv addons out/
- uses: actions/upload-artifact@v4
with:
name: libgit_plugin.macos.universal.editor.dylib-${{ github.sha }}
if-no-files-found: error
path: |
demo/
out/

View File

@@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: DoozyX/clang-format-lint-action@v0.11
- uses: actions/checkout@v4
- uses: DoozyX/clang-format-lint-action@v0.18.2
with:
source: "godot-git-plugin/src"
extensions: "h,cpp"
clangFormatVersion: 11
clangFormatVersion: 18

13
.gitignore vendored
View File

@@ -1,9 +1,6 @@
# SConstruct db
*.dblite
# Godot ignores
demo/.godot/
# Godot Serialisations
extension_api.json
!/ci/extension_api.json
@@ -17,7 +14,11 @@ extension_api.json
# Mac stuff
.DS_Store
# Vim
*.swp
# Binaries
__pycache__/
build/
bin/
macos/
@@ -29,4 +30,8 @@ win64/
*.os
*.ilk
*.pdb
!thirdparty/openssl/*
*.pyc
*.zip
# Misc
*.log

6
.gitmodules vendored
View File

@@ -2,9 +2,13 @@
path = godot-cpp
url = https://github.com/godotengine/godot-cpp
branch = 3.x
[submodule "libgit2"]
[submodule "thirdparty/git2/libgit2"]
path = thirdparty/git2/libgit2
url = https://github.com/libgit2/libgit2
ignore = untracked
[submodule "thirdparty/ssh2/libssh2"]
path = thirdparty/ssh2/libssh2
url = https://github.com/libssh2/libssh2
[submodule "thirdparty/openssl"]
path = thirdparty/openssl
url = https://github.com/openssl/openssl

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2016-2022 The Godot Engine community
Copyright (c) 2016-2023 The Godot Engine community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -6,37 +6,28 @@
Git implementation of the Godot Engine VCS interface in Godot. We use [libgit2](https://libgit2.org) as our backend to simulate Git in code.
> Planned for the upcoming version of Godot. Look for other branches for support in other Godot releases.
## Installation
## Installation Instructions
1. Grab the platform binaries here: <https://github.com/godotengine/godot-git-plugin/releases>
1. Grab the platform binaries here: https://github.com/godotengine/godot-git-plugin/releases
2. Then read the installation instructions: https://github.com/godotengine/godot-git-plugin/wiki
## Build Instructions
## Build
This section onwards is only meant to be used if you intend to compile the plugin from source.
### Required Tools
### Required tools
- Full copy of the source code. Remember to use `git clone --recursive`.
- [SCons](https://scons.org/pages/download.html) (v3.0.1+)
- Full copy of the source code. Remember to use `git clone --recursive`, or initialize submodules with `git submodule update --init`.
- [SCons](https://scons.org/pages/download.html) (v3.1.2+), CMake, and Perl.
- C++17 and C90 compilers detectable by SCons and present in `PATH`.
- Platforms Specific Setup
- Windows
- No extra steps required other than setting up the compilers.
- MacOS
- For making universal builds targeting both Apple Silicon and x86_64, you can optionally run `build_openssl_universal_macos.sh` to build OpenSSL yourself and replace the already prebuilt libraries provided inside `thirdparty/openssl/`, otherwise, just run `brew install openssl@1.1` to use the prebuilt libraries provided in this repository.
- Linux
- Run `sudo apt-get install libssl-dev`, or your local package manager's equivalent.
### Release Build
### Release build
```
scons platform=<platform> target=editor gdextension_dir="../path/to/gdextension/dump/" -j 6
scons platform=<platform> target=editor
```
> You may get the gdextension dump yourself from Godot using the instructions in the next section, or use the ones provided in `godot-cpp/gdextension` or `ci/`.
> You may get the GDExtension dump yourself from Godot using the instructions in the next section, or use the ones provided in `godot-cpp`.
For more build options, run `scons platform=<platform> -h`
@@ -49,19 +40,18 @@ If you need to use a custom GDExtension API:
1. Dump the new bindings from the custom Godot build.
```shell
cd local/copy/of/godot/source
.\bin\godot.xxx --headless --dump-gdextension-interface --dump-extension-api
./path/to/godot/bin/godot.<platform>.editor.<arch> --headless --dump-gdextension-interface --dump-extension-api
```
2. Build the plugin along with the godot-cpp library.
```
scons platform=<platform> target=editor generate_bindings=yes dev_build=yes gdextension_dir="path/to/gdextension/dump" -j 6
scons platform=<platform> target=editor generate_bindings=yes dev_build=yes
```
> You only need to build godot-cpp once every change in the GDExtension API, hence, `generate_bindings=yes` should only be passed in during the first time after generating a new GDExtension API dump.
3. Open the project provided inside `demo/` in the custom Godot build.
3. To test the plugin, set up a testing project with Godot, and copy or symlink the `addons` folder.
To view more options available while recompiling godot-git-plugin, run `scons platform=<platform> -h`.

View File

@@ -2,8 +2,8 @@
import os
EnsureSConsVersion(3, 0, 0)
EnsurePythonVersion(3, 5)
EnsureSConsVersion(3, 1, 2)
EnsurePythonVersion(3, 6)
opts = Variables([], ARGUMENTS)
@@ -11,19 +11,9 @@ env = Environment(ENV=os.environ)
# Define our options
opts.Add(PathVariable("target_path",
"The path where the lib is installed.", "demo/addons/godot-git-plugin/"))
"The path where the lib is installed.", "addons/godot-git-plugin/"))
opts.Add(PathVariable("target_name", "The library name.",
"libgit_plugin", PathVariable.PathAccept))
opts.Add(PathVariable("macos_openssl", "Path to OpenSSL library root - only used in macOS builds.",
"/usr/local/opt/openssl@1.1/", PathVariable.PathAccept)) # TODO: Find a way to configure this to use the cloned OpenSSL source code, based on `macos_arch`.
opts.Add(PathVariable("macos_openssl_static_ssl", "Path to OpenSSL libssl.a library - only used in macOS builds.",
os.path.join(os.path.abspath(os.getcwd()), "thirdparty/openssl/libssl.a"), PathVariable.PathAccept))
opts.Add(PathVariable("macos_openssl_static_crypto", "Path to OpenSSL libcrypto.a library - only used in macOS builds.",
os.path.join(os.path.abspath(os.getcwd()), "thirdparty/openssl/libcrypto.a"), PathVariable.PathAccept))
opts.Add(PathVariable("linux_openssl_static_ssl", "Path to OpenSSL libssl.a library - only used in Linux builds.",
"/usr/lib/x86_64-linux-gnu/libssl.a", PathVariable.PathAccept))
opts.Add(PathVariable("linux_openssl_static_crypto", "Path to OpenSSL libcrypto.a library - only used in Linux builds.",
"/usr/lib/x86_64-linux-gnu/libcrypto.a", PathVariable.PathAccept))
# Updates the environment with the option variables.
opts.Update(env)
@@ -33,11 +23,29 @@ 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.
# 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):
env.AppendUnique(LINKFLAGS=["/LTCG"])
# OpenSSL Builder
env.Tool("openssl", toolpath=["tools"])
# SSH2 Builder
env.Tool("cmake", toolpath=["tools"])
env.Tool("ssh2", toolpath=["tools"])
env.Tool("git2", toolpath=["tools"])
opts.Update(env)
Export("env")
ssl = env.OpenSSL()
ssh2 = env.BuildSSH2(ssl)
ssl += ssh2
git2 = env.BuildGIT2(ssl)
SConscript("thirdparty/SCsub")
Export("ssl")
Export("env")
SConscript("godot-git-plugin/SCsub")

View File

@@ -5,10 +5,7 @@ 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
3. libssh2/libssh2 - BSD-3-Clause License - https://github.com/libssh2/libssh2/tree/635caa90787220ac3773c1d5ba11f1236c22eae8
We also link to these third-party libraries (only in the compiled binary form):
1. OpenSSL - Only on Linux and MacOS - OpenSSL License - http://www.openssl.org/source/openssl-1.1.1s.tar.gz
4. openssl - OpenSSL License - https://github.com/openssl/openssl/tree/26baecb28ce461696966dac9ac889629db0b3b96
## License Texts

View File

@@ -1,11 +1,10 @@
[configuration]
entry_symbol = "git_plugin_init"
compatibility_minimum = "4.2.0"
[libraries]
macos.editor = "macos/libgit_plugin.macos.editor.universal.dylib"
windows.editor.x86_64 = "win64/libgit_plugin.windows.editor.x86_64.dll"
linux.editor.x86_64 = "linux/libgit_plugin.linux.editor.x86_64.so"
linux.editor.arm64 = "linux/libgit_plugin.linux.editor.arm64.so"
linux.editor.rv64 = ""
macos.editor = "macos/libgit_plugin.macos.editor.universal.dylib"
windows.editor.x86_64 = "windows/libgit_plugin.windows.editor.x86_64.dll"

View File

@@ -1,20 +0,0 @@
#!/bin/bash
OPENSSL_VERSION="1.1.1s"
curl -OL http://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz
tar -xzvf openssl-$OPENSSL_VERSION.tar.gz
mv openssl-$OPENSSL_VERSION openssl_arm64
tar -xzvf openssl-$OPENSSL_VERSION.tar.gz
mv openssl-$OPENSSL_VERSION openssl_x86_64
cd openssl_arm64
./Configure darwin64-arm64-cc
make
cd ../
cd openssl_x86_64
./Configure darwin64-x86_64-cc -mmacosx-version-min=10.13
make
cd ../
lipo -create openssl_arm64/libcrypto.a openssl_x86_64/libcrypto.a -output thirdparty/openssl/libcrypto.a
lipo -create openssl_arm64/libssl.a openssl_x86_64/libssl.a -output thirdparty/openssl/libssl.a
rm openssl-$OPENSSL_VERSION.tar.gz

File diff suppressed because it is too large Load Diff

View File

@@ -1,619 +0,0 @@
/*************************************************************************/
/* gdextension_interface.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef GDEXTENSION_INTERFACE_H
#define GDEXTENSION_INTERFACE_H
/* This is a C class header, you can copy it and use it directly in your own binders.
* Together with the JSON file, you should be able to generate any binder.
*/
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#ifndef __cplusplus
typedef uint32_t char32_t;
typedef uint16_t char16_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* VARIANT TYPES */
typedef enum {
GDEXTENSION_VARIANT_TYPE_NIL,
/* atomic types */
GDEXTENSION_VARIANT_TYPE_BOOL,
GDEXTENSION_VARIANT_TYPE_INT,
GDEXTENSION_VARIANT_TYPE_FLOAT,
GDEXTENSION_VARIANT_TYPE_STRING,
/* math types */
GDEXTENSION_VARIANT_TYPE_VECTOR2,
GDEXTENSION_VARIANT_TYPE_VECTOR2I,
GDEXTENSION_VARIANT_TYPE_RECT2,
GDEXTENSION_VARIANT_TYPE_RECT2I,
GDEXTENSION_VARIANT_TYPE_VECTOR3,
GDEXTENSION_VARIANT_TYPE_VECTOR3I,
GDEXTENSION_VARIANT_TYPE_TRANSFORM2D,
GDEXTENSION_VARIANT_TYPE_VECTOR4,
GDEXTENSION_VARIANT_TYPE_VECTOR4I,
GDEXTENSION_VARIANT_TYPE_PLANE,
GDEXTENSION_VARIANT_TYPE_QUATERNION,
GDEXTENSION_VARIANT_TYPE_AABB,
GDEXTENSION_VARIANT_TYPE_BASIS,
GDEXTENSION_VARIANT_TYPE_TRANSFORM3D,
GDEXTENSION_VARIANT_TYPE_PROJECTION,
/* misc types */
GDEXTENSION_VARIANT_TYPE_COLOR,
GDEXTENSION_VARIANT_TYPE_STRING_NAME,
GDEXTENSION_VARIANT_TYPE_NODE_PATH,
GDEXTENSION_VARIANT_TYPE_RID,
GDEXTENSION_VARIANT_TYPE_OBJECT,
GDEXTENSION_VARIANT_TYPE_CALLABLE,
GDEXTENSION_VARIANT_TYPE_SIGNAL,
GDEXTENSION_VARIANT_TYPE_DICTIONARY,
GDEXTENSION_VARIANT_TYPE_ARRAY,
/* typed arrays */
GDEXTENSION_VARIANT_TYPE_PACKED_BYTE_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_INT32_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_INT64_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT32_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_FLOAT64_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_STRING_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR2_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_VECTOR3_ARRAY,
GDEXTENSION_VARIANT_TYPE_PACKED_COLOR_ARRAY,
GDEXTENSION_VARIANT_TYPE_VARIANT_MAX
} GDExtensionVariantType;
typedef enum {
/* comparison */
GDEXTENSION_VARIANT_OP_EQUAL,
GDEXTENSION_VARIANT_OP_NOT_EQUAL,
GDEXTENSION_VARIANT_OP_LESS,
GDEXTENSION_VARIANT_OP_LESS_EQUAL,
GDEXTENSION_VARIANT_OP_GREATER,
GDEXTENSION_VARIANT_OP_GREATER_EQUAL,
/* mathematic */
GDEXTENSION_VARIANT_OP_ADD,
GDEXTENSION_VARIANT_OP_SUBTRACT,
GDEXTENSION_VARIANT_OP_MULTIPLY,
GDEXTENSION_VARIANT_OP_DIVIDE,
GDEXTENSION_VARIANT_OP_NEGATE,
GDEXTENSION_VARIANT_OP_POSITIVE,
GDEXTENSION_VARIANT_OP_MODULE,
GDEXTENSION_VARIANT_OP_POWER,
/* bitwise */
GDEXTENSION_VARIANT_OP_SHIFT_LEFT,
GDEXTENSION_VARIANT_OP_SHIFT_RIGHT,
GDEXTENSION_VARIANT_OP_BIT_AND,
GDEXTENSION_VARIANT_OP_BIT_OR,
GDEXTENSION_VARIANT_OP_BIT_XOR,
GDEXTENSION_VARIANT_OP_BIT_NEGATE,
/* logic */
GDEXTENSION_VARIANT_OP_AND,
GDEXTENSION_VARIANT_OP_OR,
GDEXTENSION_VARIANT_OP_XOR,
GDEXTENSION_VARIANT_OP_NOT,
/* containment */
GDEXTENSION_VARIANT_OP_IN,
GDEXTENSION_VARIANT_OP_MAX
} GDExtensionVariantOperator;
typedef void *GDExtensionVariantPtr;
typedef const void *GDExtensionConstVariantPtr;
typedef void *GDExtensionStringNamePtr;
typedef const void *GDExtensionConstStringNamePtr;
typedef void *GDExtensionStringPtr;
typedef const void *GDExtensionConstStringPtr;
typedef void *GDExtensionObjectPtr;
typedef const void *GDExtensionConstObjectPtr;
typedef void *GDExtensionTypePtr;
typedef const void *GDExtensionConstTypePtr;
typedef const void *GDExtensionMethodBindPtr;
typedef int64_t GDExtensionInt;
typedef uint8_t GDExtensionBool;
typedef uint64_t GDObjectInstanceID;
typedef void *GDExtensionRefPtr;
typedef const void *GDExtensionConstRefPtr;
/* VARIANT DATA I/O */
typedef enum {
GDEXTENSION_CALL_OK,
GDEXTENSION_CALL_ERROR_INVALID_METHOD,
GDEXTENSION_CALL_ERROR_INVALID_ARGUMENT, // Expected a different variant type.
GDEXTENSION_CALL_ERROR_TOO_MANY_ARGUMENTS, // Expected lower number of arguments.
GDEXTENSION_CALL_ERROR_TOO_FEW_ARGUMENTS, // Expected higher number of arguments.
GDEXTENSION_CALL_ERROR_INSTANCE_IS_NULL,
GDEXTENSION_CALL_ERROR_METHOD_NOT_CONST, // Used for const call.
} GDExtensionCallErrorType;
typedef struct {
GDExtensionCallErrorType error;
int32_t argument;
int32_t expected;
} GDExtensionCallError;
typedef void (*GDExtensionVariantFromTypeConstructorFunc)(GDExtensionVariantPtr, GDExtensionTypePtr);
typedef void (*GDExtensionTypeFromVariantConstructorFunc)(GDExtensionTypePtr, GDExtensionVariantPtr);
typedef void (*GDExtensionPtrOperatorEvaluator)(GDExtensionConstTypePtr p_left, GDExtensionConstTypePtr p_right, GDExtensionTypePtr r_result);
typedef void (*GDExtensionPtrBuiltInMethod)(GDExtensionTypePtr p_base, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_return, int p_argument_count);
typedef void (*GDExtensionPtrConstructor)(GDExtensionTypePtr p_base, const GDExtensionConstTypePtr *p_args);
typedef void (*GDExtensionPtrDestructor)(GDExtensionTypePtr p_base);
typedef void (*GDExtensionPtrSetter)(GDExtensionTypePtr p_base, GDExtensionConstTypePtr p_value);
typedef void (*GDExtensionPtrGetter)(GDExtensionConstTypePtr p_base, GDExtensionTypePtr r_value);
typedef void (*GDExtensionPtrIndexedSetter)(GDExtensionTypePtr p_base, GDExtensionInt p_index, GDExtensionConstTypePtr p_value);
typedef void (*GDExtensionPtrIndexedGetter)(GDExtensionConstTypePtr p_base, GDExtensionInt p_index, GDExtensionTypePtr r_value);
typedef void (*GDExtensionPtrKeyedSetter)(GDExtensionTypePtr p_base, GDExtensionConstTypePtr p_key, GDExtensionConstTypePtr p_value);
typedef void (*GDExtensionPtrKeyedGetter)(GDExtensionConstTypePtr p_base, GDExtensionConstTypePtr p_key, GDExtensionTypePtr r_value);
typedef uint32_t (*GDExtensionPtrKeyedChecker)(GDExtensionConstVariantPtr p_base, GDExtensionConstVariantPtr p_key);
typedef void (*GDExtensionPtrUtilityFunction)(GDExtensionTypePtr r_return, const GDExtensionConstTypePtr *p_args, int p_argument_count);
typedef GDExtensionObjectPtr (*GDExtensionClassConstructor)();
typedef void *(*GDExtensionInstanceBindingCreateCallback)(void *p_token, void *p_instance);
typedef void (*GDExtensionInstanceBindingFreeCallback)(void *p_token, void *p_instance, void *p_binding);
typedef GDExtensionBool (*GDExtensionInstanceBindingReferenceCallback)(void *p_token, void *p_binding, GDExtensionBool p_reference);
typedef struct {
GDExtensionInstanceBindingCreateCallback create_callback;
GDExtensionInstanceBindingFreeCallback free_callback;
GDExtensionInstanceBindingReferenceCallback reference_callback;
} GDExtensionInstanceBindingCallbacks;
/* EXTENSION CLASSES */
typedef void *GDExtensionClassInstancePtr;
typedef GDExtensionBool (*GDExtensionClassSet)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value);
typedef GDExtensionBool (*GDExtensionClassGet)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef uint64_t (*GDExtensionClassGetRID)(GDExtensionClassInstancePtr p_instance);
typedef struct {
GDExtensionVariantType type;
GDExtensionStringNamePtr name;
GDExtensionStringNamePtr class_name;
uint32_t hint; // Bitfield of `PropertyHint` (defined in `extension_api.json`).
GDExtensionStringPtr hint_string;
uint32_t usage; // Bitfield of `PropertyUsageFlags` (defined in `extension_api.json`).
} GDExtensionPropertyInfo;
typedef struct {
GDExtensionStringNamePtr name;
GDExtensionPropertyInfo return_value;
uint32_t flags; // Bitfield of `GDExtensionClassMethodFlags`.
int32_t id;
/* Arguments: `default_arguments` is an array of size `argument_count`. */
uint32_t argument_count;
GDExtensionPropertyInfo *arguments;
/* Default arguments: `default_arguments` is an array of size `default_argument_count`. */
uint32_t default_argument_count;
GDExtensionVariantPtr *default_arguments;
} GDExtensionMethodInfo;
typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef void (*GDExtensionClassNotification)(GDExtensionClassInstancePtr p_instance, int32_t p_what);
typedef void (*GDExtensionClassToString)(GDExtensionClassInstancePtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr p_out);
typedef void (*GDExtensionClassReference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDExtensionClassUnreference)(GDExtensionClassInstancePtr p_instance);
typedef void (*GDExtensionClassCallVirtual)(GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
typedef GDExtensionObjectPtr (*GDExtensionClassCreateInstance)(void *p_userdata);
typedef void (*GDExtensionClassFreeInstance)(void *p_userdata, GDExtensionClassInstancePtr p_instance);
typedef GDExtensionClassCallVirtual (*GDExtensionClassGetVirtual)(void *p_userdata, GDExtensionConstStringNamePtr p_name);
typedef struct {
GDExtensionBool is_virtual;
GDExtensionBool is_abstract;
GDExtensionClassSet set_func;
GDExtensionClassGet get_func;
GDExtensionClassGetPropertyList get_property_list_func;
GDExtensionClassFreePropertyList free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassNotification notification_func;
GDExtensionClassToString to_string_func;
GDExtensionClassReference reference_func;
GDExtensionClassUnreference unreference_func;
GDExtensionClassCreateInstance create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract.
GDExtensionClassFreeInstance free_instance_func; // Destructor; mandatory.
GDExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function.
GDExtensionClassGetRID get_rid_func;
void *class_userdata; // Per-class user data, later accessible in instance bindings.
} GDExtensionClassCreationInfo;
typedef void *GDExtensionClassLibraryPtr;
/* Method */
typedef enum {
GDEXTENSION_METHOD_FLAG_NORMAL = 1,
GDEXTENSION_METHOD_FLAG_EDITOR = 2,
GDEXTENSION_METHOD_FLAG_CONST = 4,
GDEXTENSION_METHOD_FLAG_VIRTUAL = 8,
GDEXTENSION_METHOD_FLAG_VARARG = 16,
GDEXTENSION_METHOD_FLAG_STATIC = 32,
GDEXTENSION_METHOD_FLAGS_DEFAULT = GDEXTENSION_METHOD_FLAG_NORMAL,
} GDExtensionClassMethodFlags;
typedef enum {
GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT8,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT8,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT16,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32,
GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64,
GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT,
GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE
} GDExtensionClassMethodArgumentMetadata;
typedef void (*GDExtensionClassMethodCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
typedef void (*GDExtensionClassMethodPtrCall)(void *method_userdata, GDExtensionClassInstancePtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
typedef struct {
GDExtensionStringNamePtr name;
void *method_userdata;
GDExtensionClassMethodCall call_func;
GDExtensionClassMethodPtrCall ptrcall_func;
uint32_t method_flags; // Bitfield of `GDExtensionClassMethodFlags`.
/* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored. */
GDExtensionBool has_return_value;
GDExtensionPropertyInfo *return_value_info;
GDExtensionClassMethodArgumentMetadata return_value_metadata;
/* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`.
* Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies.
*/
uint32_t argument_count;
GDExtensionPropertyInfo *arguments_info;
GDExtensionClassMethodArgumentMetadata *arguments_metadata;
/* Default arguments: `default_arguments` is an array of size `default_argument_count`. */
uint32_t default_argument_count;
GDExtensionVariantPtr *default_arguments;
} GDExtensionClassMethodInfo;
/* SCRIPT INSTANCE EXTENSION */
typedef void *GDExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInstance native implementation.
typedef GDExtensionBool (*GDExtensionScriptInstanceSet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value);
typedef GDExtensionBool (*GDExtensionScriptInstanceGet)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef const GDExtensionPropertyInfo *(*GDExtensionScriptInstanceGetPropertyList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionScriptInstanceFreePropertyList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionPropertyInfo *p_list);
typedef GDExtensionVariantType (*GDExtensionScriptInstanceGetPropertyType)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionBool *r_is_valid);
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyCanRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef GDExtensionBool (*GDExtensionScriptInstancePropertyGetRevert)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef GDExtensionObjectPtr (*GDExtensionScriptInstanceGetOwner)(GDExtensionScriptInstanceDataPtr p_instance);
typedef void (*GDExtensionScriptInstancePropertyStateAdd)(GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value, void *p_userdata);
typedef void (*GDExtensionScriptInstanceGetPropertyState)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionScriptInstancePropertyStateAdd p_add_func, void *p_userdata);
typedef const GDExtensionMethodInfo *(*GDExtensionScriptInstanceGetMethodList)(GDExtensionScriptInstanceDataPtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionScriptInstanceFreeMethodList)(GDExtensionScriptInstanceDataPtr p_instance, const GDExtensionMethodInfo *p_list);
typedef GDExtensionBool (*GDExtensionScriptInstanceHasMethod)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef void (*GDExtensionScriptInstanceCall)(GDExtensionScriptInstanceDataPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
typedef void (*GDExtensionScriptInstanceNotification)(GDExtensionScriptInstanceDataPtr p_instance, int32_t p_what);
typedef void (*GDExtensionScriptInstanceToString)(GDExtensionScriptInstanceDataPtr p_instance, GDExtensionBool *r_is_valid, GDExtensionStringPtr r_out);
typedef void (*GDExtensionScriptInstanceRefCountIncremented)(GDExtensionScriptInstanceDataPtr p_instance);
typedef GDExtensionBool (*GDExtensionScriptInstanceRefCountDecremented)(GDExtensionScriptInstanceDataPtr p_instance);
typedef GDExtensionObjectPtr (*GDExtensionScriptInstanceGetScript)(GDExtensionScriptInstanceDataPtr p_instance);
typedef GDExtensionBool (*GDExtensionScriptInstanceIsPlaceholder)(GDExtensionScriptInstanceDataPtr p_instance);
typedef void *GDExtensionScriptLanguagePtr;
typedef GDExtensionScriptLanguagePtr (*GDExtensionScriptInstanceGetLanguage)(GDExtensionScriptInstanceDataPtr p_instance);
typedef void (*GDExtensionScriptInstanceFree)(GDExtensionScriptInstanceDataPtr p_instance);
typedef void *GDExtensionScriptInstancePtr; // Pointer to ScriptInstance.
typedef struct {
GDExtensionScriptInstanceSet set_func;
GDExtensionScriptInstanceGet get_func;
GDExtensionScriptInstanceGetPropertyList get_property_list_func;
GDExtensionScriptInstanceFreePropertyList free_property_list_func;
GDExtensionScriptInstancePropertyCanRevert property_can_revert_func;
GDExtensionScriptInstancePropertyGetRevert property_get_revert_func;
GDExtensionScriptInstanceGetOwner get_owner_func;
GDExtensionScriptInstanceGetPropertyState get_property_state_func;
GDExtensionScriptInstanceGetMethodList get_method_list_func;
GDExtensionScriptInstanceFreeMethodList free_method_list_func;
GDExtensionScriptInstanceGetPropertyType get_property_type_func;
GDExtensionScriptInstanceHasMethod has_method_func;
GDExtensionScriptInstanceCall call_func;
GDExtensionScriptInstanceNotification notification_func;
GDExtensionScriptInstanceToString to_string_func;
GDExtensionScriptInstanceRefCountIncremented refcount_incremented_func;
GDExtensionScriptInstanceRefCountDecremented refcount_decremented_func;
GDExtensionScriptInstanceGetScript get_script_func;
GDExtensionScriptInstanceIsPlaceholder is_placeholder_func;
GDExtensionScriptInstanceSet set_fallback_func;
GDExtensionScriptInstanceGet get_fallback_func;
GDExtensionScriptInstanceGetLanguage get_language_func;
GDExtensionScriptInstanceFree free_func;
} GDExtensionScriptInstanceInfo;
/* INTERFACE */
typedef struct {
uint32_t version_major;
uint32_t version_minor;
uint32_t version_patch;
const char *version_string;
/* GODOT CORE */
void *(*mem_alloc)(size_t p_bytes);
void *(*mem_realloc)(void *p_ptr, size_t p_bytes);
void (*mem_free)(void *p_ptr);
void (*print_error)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
void (*print_warning)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
void (*print_script_error)(const char *p_description, const char *p_function, const char *p_file, int32_t p_line);
uint64_t (*get_native_struct_size)(GDExtensionConstStringNamePtr p_name);
/* GODOT VARIANT */
/* variant general */
void (*variant_new_copy)(GDExtensionVariantPtr r_dest, GDExtensionConstVariantPtr p_src);
void (*variant_new_nil)(GDExtensionVariantPtr r_dest);
void (*variant_destroy)(GDExtensionVariantPtr p_self);
/* variant type */
void (*variant_call)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
void (*variant_call_static)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error);
void (*variant_evaluate)(GDExtensionVariantOperator p_op, GDExtensionConstVariantPtr p_a, GDExtensionConstVariantPtr p_b, GDExtensionVariantPtr r_return, GDExtensionBool *r_valid);
void (*variant_set)(GDExtensionVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid);
void (*variant_set_named)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid);
void (*variant_set_keyed)(GDExtensionVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid);
void (*variant_set_indexed)(GDExtensionVariantPtr p_self, GDExtensionInt p_index, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid, GDExtensionBool *r_oob);
void (*variant_get)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid);
void (*variant_get_named)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid);
void (*variant_get_keyed)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid);
void (*variant_get_indexed)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_index, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid, GDExtensionBool *r_oob);
GDExtensionBool (*variant_iter_init)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionBool *r_valid);
GDExtensionBool (*variant_iter_next)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionBool *r_valid);
void (*variant_iter_get)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid);
GDExtensionInt (*variant_hash)(GDExtensionConstVariantPtr p_self);
GDExtensionInt (*variant_recursive_hash)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_recursion_count);
GDExtensionBool (*variant_hash_compare)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_other);
GDExtensionBool (*variant_booleanize)(GDExtensionConstVariantPtr p_self);
void (*variant_duplicate)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_ret, GDExtensionBool p_deep);
void (*variant_stringify)(GDExtensionConstVariantPtr p_self, GDExtensionStringPtr r_ret);
GDExtensionVariantType (*variant_get_type)(GDExtensionConstVariantPtr p_self);
GDExtensionBool (*variant_has_method)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_method);
GDExtensionBool (*variant_has_member)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member);
GDExtensionBool (*variant_has_key)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid);
void (*variant_get_type_name)(GDExtensionVariantType p_type, GDExtensionStringPtr r_name);
GDExtensionBool (*variant_can_convert)(GDExtensionVariantType p_from, GDExtensionVariantType p_to);
GDExtensionBool (*variant_can_convert_strict)(GDExtensionVariantType p_from, GDExtensionVariantType p_to);
/* ptrcalls */
GDExtensionVariantFromTypeConstructorFunc (*get_variant_from_type_constructor)(GDExtensionVariantType p_type);
GDExtensionTypeFromVariantConstructorFunc (*get_variant_to_type_constructor)(GDExtensionVariantType p_type);
GDExtensionPtrOperatorEvaluator (*variant_get_ptr_operator_evaluator)(GDExtensionVariantOperator p_operator, GDExtensionVariantType p_type_a, GDExtensionVariantType p_type_b);
GDExtensionPtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, GDExtensionInt p_hash);
GDExtensionPtrConstructor (*variant_get_ptr_constructor)(GDExtensionVariantType p_type, int32_t p_constructor);
GDExtensionPtrDestructor (*variant_get_ptr_destructor)(GDExtensionVariantType p_type);
void (*variant_construct)(GDExtensionVariantType p_type, GDExtensionVariantPtr p_base, const GDExtensionConstVariantPtr *p_args, int32_t p_argument_count, GDExtensionCallError *r_error);
GDExtensionPtrSetter (*variant_get_ptr_setter)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member);
GDExtensionPtrGetter (*variant_get_ptr_getter)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member);
GDExtensionPtrIndexedSetter (*variant_get_ptr_indexed_setter)(GDExtensionVariantType p_type);
GDExtensionPtrIndexedGetter (*variant_get_ptr_indexed_getter)(GDExtensionVariantType p_type);
GDExtensionPtrKeyedSetter (*variant_get_ptr_keyed_setter)(GDExtensionVariantType p_type);
GDExtensionPtrKeyedGetter (*variant_get_ptr_keyed_getter)(GDExtensionVariantType p_type);
GDExtensionPtrKeyedChecker (*variant_get_ptr_keyed_checker)(GDExtensionVariantType p_type);
void (*variant_get_constant_value)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_constant, GDExtensionVariantPtr r_ret);
GDExtensionPtrUtilityFunction (*variant_get_ptr_utility_function)(GDExtensionConstStringNamePtr p_function, GDExtensionInt p_hash);
/* extra utilities */
void (*string_new_with_latin1_chars)(GDExtensionStringPtr r_dest, const char *p_contents);
void (*string_new_with_utf8_chars)(GDExtensionStringPtr r_dest, const char *p_contents);
void (*string_new_with_utf16_chars)(GDExtensionStringPtr r_dest, const char16_t *p_contents);
void (*string_new_with_utf32_chars)(GDExtensionStringPtr r_dest, const char32_t *p_contents);
void (*string_new_with_wide_chars)(GDExtensionStringPtr r_dest, const wchar_t *p_contents);
void (*string_new_with_latin1_chars_and_len)(GDExtensionStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
void (*string_new_with_utf8_chars_and_len)(GDExtensionStringPtr r_dest, const char *p_contents, GDExtensionInt p_size);
void (*string_new_with_utf16_chars_and_len)(GDExtensionStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_size);
void (*string_new_with_utf32_chars_and_len)(GDExtensionStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_size);
void (*string_new_with_wide_chars_and_len)(GDExtensionStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_size);
/* Information about the following functions:
* - The return value is the resulting encoded string length.
* - The length returned is in characters, not in bytes. It also does not include a trailing zero.
* - These functions also do not write trailing zero, If you need it, write it yourself at the position indicated by the length (and make sure to allocate it).
* - Passing NULL in r_text means only the length is computed (again, without including trailing zero).
* - p_max_write_length argument is in characters, not bytes. It will be ignored if r_text is NULL.
* - p_max_write_length argument does not affect the return value, it's only to cap write length.
*/
GDExtensionInt (*string_to_latin1_chars)(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length);
GDExtensionInt (*string_to_utf8_chars)(GDExtensionConstStringPtr p_self, char *r_text, GDExtensionInt p_max_write_length);
GDExtensionInt (*string_to_utf16_chars)(GDExtensionConstStringPtr p_self, char16_t *r_text, GDExtensionInt p_max_write_length);
GDExtensionInt (*string_to_utf32_chars)(GDExtensionConstStringPtr p_self, char32_t *r_text, GDExtensionInt p_max_write_length);
GDExtensionInt (*string_to_wide_chars)(GDExtensionConstStringPtr p_self, wchar_t *r_text, GDExtensionInt p_max_write_length);
char32_t *(*string_operator_index)(GDExtensionStringPtr p_self, GDExtensionInt p_index);
const char32_t *(*string_operator_index_const)(GDExtensionConstStringPtr p_self, GDExtensionInt p_index);
/* Packed array functions */
uint8_t *(*packed_byte_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedByteArray
const uint8_t *(*packed_byte_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedByteArray
GDExtensionTypePtr (*packed_color_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedColorArray, returns Color ptr
GDExtensionTypePtr (*packed_color_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedColorArray, returns Color ptr
float *(*packed_float32_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedFloat32Array
const float *(*packed_float32_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedFloat32Array
double *(*packed_float64_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedFloat64Array
const double *(*packed_float64_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedFloat64Array
int32_t *(*packed_int32_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedInt32Array
const int32_t *(*packed_int32_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedInt32Array
int64_t *(*packed_int64_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedInt32Array
const int64_t *(*packed_int64_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedInt32Array
GDExtensionStringPtr (*packed_string_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedStringArray
GDExtensionStringPtr (*packed_string_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedStringArray
GDExtensionTypePtr (*packed_vector2_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedVector2Array, returns Vector2 ptr
GDExtensionTypePtr (*packed_vector2_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedVector2Array, returns Vector2 ptr
GDExtensionTypePtr (*packed_vector3_array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedVector3Array, returns Vector3 ptr
GDExtensionTypePtr (*packed_vector3_array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be a PackedVector3Array, returns Vector3 ptr
GDExtensionVariantPtr (*array_operator_index)(GDExtensionTypePtr p_self, GDExtensionInt p_index); // p_self should be an Array ptr
GDExtensionVariantPtr (*array_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionInt p_index); // p_self should be an Array ptr
/* Dictionary functions */
GDExtensionVariantPtr (*dictionary_operator_index)(GDExtensionTypePtr p_self, GDExtensionConstVariantPtr p_key); // p_self should be an Dictionary ptr
GDExtensionVariantPtr (*dictionary_operator_index_const)(GDExtensionConstTypePtr p_self, GDExtensionConstVariantPtr p_key); // p_self should be an Dictionary ptr
/* OBJECT */
void (*object_method_bind_call)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionVariantPtr r_ret, GDExtensionCallError *r_error);
void (*object_method_bind_ptrcall)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret);
void (*object_destroy)(GDExtensionObjectPtr p_o);
GDExtensionObjectPtr (*global_get_singleton)(GDExtensionConstStringNamePtr p_name);
void *(*object_get_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */
GDExtensionObjectPtr (*object_cast_to)(GDExtensionConstObjectPtr p_object, void *p_class_tag);
GDExtensionObjectPtr (*object_get_instance_from_id)(GDObjectInstanceID p_instance_id);
GDObjectInstanceID (*object_get_instance_id)(GDExtensionConstObjectPtr p_object);
/* REFERENCE */
GDExtensionObjectPtr (*ref_get_object)(GDExtensionConstRefPtr p_ref);
void (*ref_set_object)(GDExtensionRefPtr p_ref, GDExtensionObjectPtr p_object);
/* SCRIPT INSTANCE */
GDExtensionScriptInstancePtr (*script_instance_create)(const GDExtensionScriptInstanceInfo *p_info, GDExtensionScriptInstanceDataPtr p_instance_data);
/* CLASSDB */
GDExtensionObjectPtr (*classdb_construct_object)(GDExtensionConstStringNamePtr p_classname); /* The passed class must be a built-in godot class, or an already-registered extension class. In both case, object_set_instance should be called to fully initialize the object. */
GDExtensionMethodBindPtr (*classdb_get_method_bind)(GDExtensionConstStringNamePtr p_classname, GDExtensionConstStringNamePtr p_methodname, GDExtensionInt p_hash);
void *(*classdb_get_class_tag)(GDExtensionConstStringNamePtr p_classname);
/* CLASSDB EXTENSION */
/* Provided parameters for `classdb_register_extension_*` can be safely freed once the function returns. */
void (*classdb_register_extension_class)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_parent_class_name, const GDExtensionClassCreationInfo *p_extension_funcs);
void (*classdb_register_extension_class_method)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionClassMethodInfo *p_method_info);
void (*classdb_register_extension_class_integer_constant)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_enum_name, GDExtensionConstStringNamePtr p_constant_name, GDExtensionInt p_constant_value, GDExtensionBool p_is_bitfield);
void (*classdb_register_extension_class_property)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, const GDExtensionPropertyInfo *p_info, GDExtensionConstStringNamePtr p_setter, GDExtensionConstStringNamePtr p_getter);
void (*classdb_register_extension_class_property_group)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringPtr p_group_name, GDExtensionConstStringPtr p_prefix);
void (*classdb_register_extension_class_property_subgroup)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringPtr p_subgroup_name, GDExtensionConstStringPtr p_prefix);
void (*classdb_register_extension_class_signal)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count);
void (*classdb_unregister_extension_class)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */
void (*get_library_path)(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path);
} GDExtensionInterface;
/* INITIALIZATION */
typedef enum {
GDEXTENSION_INITIALIZATION_CORE,
GDEXTENSION_INITIALIZATION_SERVERS,
GDEXTENSION_INITIALIZATION_SCENE,
GDEXTENSION_INITIALIZATION_EDITOR,
GDEXTENSION_MAX_INITIALIZATION_LEVEL,
} GDExtensionInitializationLevel;
typedef struct {
/* Minimum initialization level required.
* If Core or Servers, the extension needs editor or game restart to take effect */
GDExtensionInitializationLevel minimum_initialization_level;
/* Up to the user to supply when initializing */
void *userdata;
/* This function will be called multiple times for each initialization level. */
void (*initialize)(void *userdata, GDExtensionInitializationLevel p_level);
void (*deinitialize)(void *userdata, GDExtensionInitializationLevel p_level);
} GDExtensionInitialization;
/* Define a C function prototype that implements the function below and expose it to dlopen() (or similar).
* This is the entry point of the GDExtension library and will be called on initialization.
* It can be used to set up different init levels, which are called during various stages of initialization/shutdown.
* The function name must be a unique one specified in the .gdextension config file.
*/
typedef GDExtensionBool (*GDExtensionInitializationFunction)(const GDExtensionInterface *p_interface, GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization);
#ifdef __cplusplus
}
#endif
#endif // GDEXTENSION_INTERFACE_H

2
demo/.gitattributes vendored
View File

@@ -1,2 +0,0 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

2
demo/.gitignore vendored
View File

@@ -1,2 +0,0 @@
# Godot 4+ specific ignores
.godot/

View File

@@ -1,7 +0,0 @@
[plugin]
name="Godot Git Plugin"
description="This plugin lets you interact with Git without leaving the Godot editor. More information can be found at https://github.com/godotengine/godot-git-plugin/wiki"
author="twaritwaikar"
version="v3.0.0-beta1"
script="godot-git-plugin.gd"

View File

@@ -1,3 +0,0 @@
[gd_scene format=3 uid="uid://cr5ci1iwmxnlb"]
[node name="Node3D" type="Node3D"]

View File

@@ -1,12 +0,0 @@
extends Node
# Called when the node enters the scene tree for the first time.
func _ready():
print("Hello world!")
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass

View File

@@ -1,22 +0,0 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/features=PackedStringArray("4.0")
[editor]
version_control/plugin_name="GitPlugin"
version_control/autoload_on_startup=true
[editor_plugins]
enabled=PackedStringArray()

View File

@@ -4,15 +4,7 @@ import os
env = {}
Import("env")
# Process some arguments
if env["use_llvm"]:
env["CC"] = "clang"
env["CXX"] = "clang++"
if env["platform"] == "":
print("No valid target platform selected.")
quit()
Import("ssl")
env["target_path"] = "../" + env["target_path"]
@@ -20,39 +12,27 @@ if not os.path.isdir(env["target_path"]):
os.mkdir(env["target_path"])
# Check our platform specifics
env["target_path"] += env["platform"] + "/"
if env["platform"] == "macos":
env["target_path"] += "macos/"
# Force static linkage (https://stackoverflow.com/a/2995999/7370948)
env.Append(LIBS=[File(env["macos_openssl_static_ssl"]),
File(env["macos_openssl_static_crypto"])])
if env["macos_deployment_target"] != "default":
env.Append(CCFLAGS=["-mmacosx-version-min=" +
env["macos_deployment_target"]])
env.Append(LINKFLAGS=["-mmacosx-version-min=" +
env["macos_deployment_target"]])
elif env["platform"] == "linux":
env["target_path"] += "linux/"
env.Append(LIBS=[File(env["linux_openssl_static_ssl"]),
File(env["linux_openssl_static_crypto"])])
elif env["platform"] == "windows":
env["target_path"] += "win64/"
env.Append(LIBS=["advapi32", "winhttp", "rpcrt4", "crypt32",
"ole32", "user32", "wsock32", "ws2_32", "bcrypt"])
env.Append(CPPPATH=[".", "src/"])
env.Append(CPPPATH=["../thirdparty/git2/libgit2/include/"])
env.Append(LIBPATH=["../thirdparty/bin/"])
env.Prepend(LIBS=["git2", "ssh2"])
env.Append(CPPPATH=["#thirdparty/git2/libgit2/include/"])
lib_sources = Glob("src/*.cpp")
env.Depends(lib_sources, ssl)
library = env.SharedLibrary(
target=env["target_path"] +
"{}{}{}".format(env["target_name"], env["suffix"], env["SHLIBSUFFIX"]),
source=Glob("src/*.cpp")
source=lib_sources
)
Default(library)

View File

@@ -19,8 +19,8 @@ void uninitialize_git_plugin_module(godot::ModuleInitializationLevel p_level) {
extern "C" {
GDExtensionBool GDE_EXPORT git_plugin_init(const GDExtensionInterface *p_interface, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
GDExtensionBool GDE_EXPORT git_plugin_init(const GDExtensionInterfaceGetProcAddress p_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
godot::GDExtensionBinding::InitObject init_obj(p_address, p_library, r_initialization);
init_obj.register_initializer(initialize_git_plugin_module);
init_obj.register_terminator(uninitialize_git_plugin_module);

View File

@@ -10,11 +10,7 @@
extern "C" int progress_cb(const char *str, int len, void *data) {
(void)data;
char *progress_str = new char[len + 1];
std::memcpy(progress_str, str, len);
progress_str[len] = '\0';
godot::UtilityFunctions::push_warning("remote: ", CString(godot::String(progress_str).strip_edges()).data);
delete[] progress_str;
godot::UtilityFunctions::print("remote: ", godot::String::utf8(str, len).strip_edges());
return 0;
}
@@ -27,10 +23,10 @@ extern "C" int update_cb(const char *refname, const git_oid *a, const git_oid *b
git_oid_tostr(b_str, short_commit_length, b);
if (git_oid_is_zero(a)) {
godot::UtilityFunctions::print("* [new] ", CString(godot::String(b_str)).data, " ", CString(godot::String(refname)).data);
godot::UtilityFunctions::print("* [new] ", godot::String::utf8(b_str), " ", godot::String::utf8(refname));
} else {
git_oid_tostr(a_str, short_commit_length, a);
godot::UtilityFunctions::print("[updated] ", CString(godot::String(a_str)).data, "...", CString(godot::String(b_str)).data, " ", CString(godot::String(refname)).data);
godot::UtilityFunctions::print("[updated] ", godot::String::utf8(a_str), "...", godot::String::utf8(b_str), " ", godot::String::utf8(refname));
}
return 0;
@@ -63,16 +59,16 @@ extern "C" int push_transfer_progress_cb(unsigned int current, unsigned int tota
progress = (current * 100) / total;
}
godot::UtilityFunctions::print("Writing Objects: ", uint32_t(progress), "% (", uint32_t(current), "/", uint32_t(total), ", ", uint32_t(bytes), " bytes done.");
godot::UtilityFunctions::print("Writing Objects: ", uint32_t(progress), "% (", uint32_t(current), "/", uint32_t(total), ", ", uint32_t(bytes), " bytes done.)");
return 0;
}
extern "C" int push_update_reference_cb(const char *refname, const char *status, void *data) {
godot::String status_str = status;
if (status_str == "") {
godot::UtilityFunctions::print("[rejected] ", CString(godot::String(refname)).data, " ", CString(status_str).data);
if (status != NULL) {
godot::String status_str = godot::String::utf8(status);
godot::UtilityFunctions::print("[rejected] ", godot::String::utf8(refname), " ", status_str);
} else {
godot::UtilityFunctions::print("[updated] ", CString(godot::String(refname)).data);
godot::UtilityFunctions::print("[updated] ", godot::String::utf8(refname));
}
return 0;
}
@@ -82,16 +78,18 @@ extern "C" int credentials_cb(git_cred **out, const char *url, const char *usern
godot::String proper_username = username_from_url ? username_from_url : creds->username;
if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT) {
return git_cred_userpass_plaintext_new(out, CString(proper_username).data, CString(creds->password).data);
if (!creds->ssh_public_key_path.is_empty()) {
if (allowed_types & GIT_CREDENTIAL_SSH_KEY) {
return git_credential_ssh_key_new(out,
CString(proper_username).data,
CString(creds->ssh_public_key_path).data,
CString(creds->ssh_private_key_path).data,
CString(creds->ssh_passphrase).data);
}
}
if (allowed_types & GIT_CREDENTIAL_SSH_KEY) {
return git_credential_ssh_key_new(out,
CString(proper_username).data,
CString(creds->ssh_public_key_path).data,
CString(creds->ssh_private_key_path).data,
CString(creds->ssh_passphrase).data);
if (allowed_types & GIT_CREDENTIAL_USERPASS_PLAINTEXT) {
return git_cred_userpass_plaintext_new(out, CString(proper_username).data, CString(creds->password).data);
}
if (allowed_types & GIT_CREDENTIAL_USERNAME) {

View File

@@ -63,10 +63,10 @@ bool GitPlugin::check_errors(int error, godot::String function, godot::String fi
message = message + ".";
if ((lg2err = git_error_last()) != nullptr && lg2err->message != nullptr) {
message = message + " Error " + godot::String::num_int64(error) + ": ";
message = message + godot::String(lg2err->message);
message = message + godot::String::utf8(lg2err->message);
}
godot::UtilityFunctions::push_error("GitPlugin: ", CString(message).data, " in ", CString(file).data, ":", CString(function).data, "#L", line);
godot::UtilityFunctions::push_error("GitPlugin: ", message, " in ", file, ":", function, "#L", line);
return true;
}
@@ -232,9 +232,9 @@ godot::TypedArray<godot::Dictionary> GitPlugin::_get_modified_files_data() {
const git_status_entry *entry = git_status_byindex(statuses.get(), i);
godot::String path;
if (entry->index_to_workdir) {
path = entry->index_to_workdir->new_file.path;
path = godot::String::utf8(entry->index_to_workdir->new_file.path);
} else {
path = entry->head_to_index->new_file.path;
path = godot::String::utf8(entry->head_to_index->new_file.path);
}
const static int git_status_wt = GIT_STATUS_WT_NEW | GIT_STATUS_WT_MODIFIED | GIT_STATUS_WT_DELETED | GIT_STATUS_WT_TYPECHANGE | GIT_STATUS_WT_RENAMED | GIT_STATUS_CONFLICTED;
@@ -245,8 +245,8 @@ godot::TypedArray<godot::Dictionary> GitPlugin::_get_modified_files_data() {
}
if (entry->status & git_status_index) {
if (entry->status == GIT_STATUS_INDEX_RENAMED) {
godot::String old_path = entry->head_to_index->old_file.path;
if (entry->status & GIT_STATUS_INDEX_RENAMED) {
godot::String old_path = godot::String::utf8(entry->head_to_index->old_file.path);
stats_files.push_back(create_status_file(old_path, map_changes.at(GIT_STATUS_INDEX_DELETED), TREE_AREA_STAGED));
stats_files.push_back(create_status_file(path, map_changes.at(GIT_STATUS_INDEX_NEW), TREE_AREA_STAGED));
} else {
@@ -273,9 +273,9 @@ godot::TypedArray<godot::String> GitPlugin::_get_branch_list() {
if (git_branch_is_head(ref.get())) {
// Always send the current branch as the first branch in list
branch_names.push_front(name);
branch_names.push_front(godot::String::utf8(name));
} else {
branch_names.push_back(godot::String(name));
branch_names.push_back(godot::String::utf8(name));
}
}
@@ -352,7 +352,7 @@ godot::String GitPlugin::_get_current_branch_name() {
const char *name = "";
GIT2_CALL_R(git_branch_name(&name, branch.get()), "Could not get branch name from current branch reference", "");
return name;
return godot::String::utf8(name);
}
godot::TypedArray<godot::String> GitPlugin::_get_remotes() {
@@ -361,13 +361,13 @@ godot::TypedArray<godot::String> GitPlugin::_get_remotes() {
godot::TypedArray<godot::String> remotes;
for (int i = 0; i < remote_array.count; i++) {
remotes.push_back(remote_array.strings[i]);
remotes.push_back(godot::String::utf8(remote_array.strings[i]));
}
return remotes;
}
godot::TypedArray<godot::Dictionary> GitPlugin::_get_previous_commits(int64_t max_commits) {
godot::TypedArray<godot::Dictionary> GitPlugin::_get_previous_commits(int32_t max_commits) {
git_revwalk_ptr walker;
GIT2_CALL_R(git_revwalk_new(Capture(walker), repo.get()), "Could not create new revwalk", godot::TypedArray<godot::Dictionary>());
GIT2_CALL_R(git_revwalk_sorting(walker.get(), GIT_SORT_TIME), "Could not sort revwalk by time", godot::TypedArray<godot::Dictionary>());
@@ -382,10 +382,10 @@ godot::TypedArray<godot::Dictionary> GitPlugin::_get_previous_commits(int64_t ma
GIT2_CALL_R(git_commit_lookup(Capture(commit), repo.get(), &oid), "Failed to lookup the commit", commits);
git_oid_tostr(commit_id, GIT_OID_HEXSZ + 1, git_commit_id(commit.get()));
godot::String msg = git_commit_message(commit.get());
godot::String msg = godot::String::utf8(git_commit_message(commit.get()));
const git_signature *sig = git_commit_author(commit.get());
godot::String author = godot::String() + sig->name + " <" + sig->email + ">";
godot::String author = godot::String::utf8(sig->name) + " <" + godot::String::utf8(sig->email) + ">";
commits.push_back(create_commit(msg, author, commit_id, sig->when.time, sig->when.offset));
}
@@ -394,7 +394,7 @@ godot::TypedArray<godot::Dictionary> GitPlugin::_get_previous_commits(int64_t ma
}
void GitPlugin::_fetch(const godot::String &remote) {
godot::UtilityFunctions::print("GitPlugin: Performing fetch from ", CString(remote).data);
godot::UtilityFunctions::print("GitPlugin: Performing fetch from ", remote);
git_remote_ptr remote_object;
GIT2_CALL(git_remote_lookup(Capture(remote_object), repo.get(), CString(remote).data), "Could not lookup remote \"" + remote + "\"");
@@ -418,7 +418,7 @@ void GitPlugin::_fetch(const godot::String &remote) {
}
void GitPlugin::_pull(const godot::String &remote) {
godot::UtilityFunctions::print("GitPlugin: Performing pull from ", CString(remote).data);
godot::UtilityFunctions::print("GitPlugin: Performing pull from ", remote);
git_remote_ptr remote_object;
GIT2_CALL(git_remote_lookup(Capture(remote_object), repo.get(), CString(remote).data), "Could not lookup remote \"" + remote + "\"");
@@ -515,7 +515,7 @@ void GitPlugin::_pull(const godot::String &remote) {
}
void GitPlugin::_push(const godot::String &remote, bool force) {
godot::UtilityFunctions::print("GitPlugin: Performing push to ", CString(remote).data);
godot::UtilityFunctions::print("GitPlugin: Performing push to ", remote);
git_remote_ptr remote_object;
GIT2_CALL(git_remote_lookup(Capture(remote_object), repo.get(), CString(remote).data), "Could not lookup remote \"" + remote + "\"");
@@ -529,7 +529,8 @@ void GitPlugin::_push(const godot::String &remote, bool force) {
remote_cbs.push_transfer_progress = &push_transfer_progress_cb;
remote_cbs.push_update_reference = &push_update_reference_cb;
GIT2_CALL(git_remote_connect(remote_object.get(), GIT_DIRECTION_PUSH, &remote_cbs, nullptr, nullptr), "Could not connect to remote \"" + remote + "\". Are your credentials correct? Try using a PAT token (in case you are using Github) as your password");
godot::String msg = "Could not connect to remote \"" + remote + "\". Are your credentials correct? Try using a PAT token (in case you are using Github) as your password";
GIT2_CALL(git_remote_connect(remote_object.get(), GIT_DIRECTION_PUSH, &remote_cbs, nullptr, nullptr), msg);
godot::String branch_name = _get_current_branch_name();
@@ -560,7 +561,7 @@ bool GitPlugin::_checkout_branch(const godot::String &branch_name) {
return true;
}
godot::TypedArray<godot::Dictionary> GitPlugin::_get_diff(const godot::String &identifier, const int64_t area) {
godot::TypedArray<godot::Dictionary> GitPlugin::_get_diff(const godot::String &identifier, const int32_t area) {
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
godot::TypedArray<godot::Dictionary> diff_contents;
@@ -629,7 +630,7 @@ godot::TypedArray<godot::Dictionary> GitPlugin::_parse_diff(git_diff *diff) {
git_patch_ptr patch;
GIT2_CALL_R(git_patch_from_diff(Capture(patch), diff, i), "Could not create patch from diff", godot::TypedArray<godot::Dictionary>());
godot::Dictionary diff_file = create_diff_file(delta->new_file.path, delta->old_file.path);
godot::Dictionary diff_file = create_diff_file(godot::String::utf8(delta->new_file.path), godot::String::utf8(delta->old_file.path));
godot::TypedArray<godot::Dictionary> diff_hunks;
for (int j = 0; j < git_patch_num_hunks(patch.get()); j++) {
@@ -650,7 +651,7 @@ godot::TypedArray<godot::Dictionary> GitPlugin::_parse_diff(git_diff *diff) {
godot::String status = " "; // We reserve 1 null terminated space to fill the + or the - character at git_diff_line->origin
status[0] = git_diff_line->origin;
diff_lines.push_back(create_diff_line(git_diff_line->new_lineno, git_diff_line->old_lineno, godot::String(content), status));
diff_lines.push_back(create_diff_line(git_diff_line->new_lineno, git_diff_line->old_lineno, godot::String::utf8(content), status));
delete[] content;
}
@@ -680,9 +681,9 @@ bool GitPlugin::_initialize(const godot::String &project_path) {
git_buf discovered_repo_path = {};
if (git_repository_discover(&discovered_repo_path, CString(project_path).data, 1, nullptr) == 0) {
repo_project_path = godot::String(discovered_repo_path.ptr);
repo_project_path = godot::String::utf8(discovered_repo_path.ptr);
godot::UtilityFunctions::print("Found a repository at " + godot::String(discovered_repo_path.ptr) + ".");
godot::UtilityFunctions::print("Found a repository at " + repo_project_path + ".");
git_buf_dispose(&discovered_repo_path);
} else {
repo_project_path = project_path;
@@ -690,7 +691,7 @@ bool GitPlugin::_initialize(const godot::String &project_path) {
godot::UtilityFunctions::push_warning("Could not find any higher level repositories.");
}
godot::UtilityFunctions::print("Selected repository path: " + godot::String(repo_project_path) + ".");
godot::UtilityFunctions::print("Selected repository path: " + repo_project_path + ".");
GIT2_CALL_R(git_repository_init(Capture(repo), CString(repo_project_path).data, 0), "Could not initialize repository", false);
git_reference_ptr head;

View File

@@ -40,10 +40,10 @@ public:
void _unstage_file(const godot::String &file_path) override;
void _discard_file(const godot::String &file_path) override;
void _commit(const godot::String &msg) override;
godot::TypedArray<godot::Dictionary> _get_diff(const godot::String &identifier, int64_t area) override;
godot::TypedArray<godot::Dictionary> _get_diff(const godot::String &identifier, int32_t area) override;
bool _shut_down() override;
godot::String _get_vcs_name() override;
godot::TypedArray<godot::Dictionary> _get_previous_commits(int64_t max_commits) override;
godot::TypedArray<godot::Dictionary> _get_previous_commits(int32_t max_commits) override;
godot::TypedArray<godot::String> _get_branch_list() override;
godot::TypedArray<godot::String> _get_remotes() override;
void _create_branch(const godot::String &branch_name) override;

22
release.sh Normal file → Executable file
View File

@@ -5,19 +5,21 @@
echo "Enter the new version number (e.g. 1.2.1):"
read version
echo "Enter the Windows x64 release ZIP URL:"
read windowsZIPURL
echo "Enter the Windows x64 release ZIP artifact ID or URL:"
read windowsArtifactID
echo "Enter the Linux x64 release ZIP URL:"
read linuxZIPURL
echo "Enter the Linux x64 release ZIP artifact ID or URL:"
read linuxArtifactID
echo "Enter the MacOS universal release ZIP URL:"
read macZIPURL
echo "Enter the MacOS universal release ZIP artifact ID or URL:"
read macArtifactID
# wget-ing the github.com URL gives a 404, so we use the method proposed here - https://github.com/actions/upload-artifact/issues/51#issuecomment-735989475
windowsZIPURL=${windowsZIPURL/github.com/nightly.link}
linuxZIPURL=${linuxZIPURL/github.com/nightly.link}
macZIPURL=${macZIPURL/github.com/nightly.link}
# The ${foo##*/} syntax extracts the string after the last '/' in case it's a full artifact URL.
baseURL=https://nightly.link/godotengine/godot-git-plugin/actions/artifacts/
windowsZIPURL=${baseURL}${windowsArtifactID##*/}.zip
linuxZIPURL=${baseURL}${linuxArtifactID##*/}.zip
macZIPURL=${baseURL}${macArtifactID##*/}.zip
wget -O windows.zip $windowsZIPURL
wget -O linux.zip $linuxZIPURL
@@ -43,7 +45,7 @@ sed -i "s/version=\"[^\"]*\"/version=\"v${version}\"/g" $pluginPath/plugin.cfg
cp LICENSE $pluginPath/LICENSE
cp THIRDPARTY.md $pluginPath/THIRDPARTY.md
zip -r $releasePath.zip $addonsPath
zip -r $releasePath.zip $addonsPath
rm -rf $releasePath
rm -rf windows

6
thirdparty/SCsub vendored
View File

@@ -1,6 +0,0 @@
#!/usr/bin/env python
Import("env")
SConscript("ssh2/SCsub")
SConscript("git2/SCsub")

135
thirdparty/git2/SCsub vendored
View File

@@ -1,135 +0,0 @@
#!/usr/bin/env python
# Adopted from https://github.com/goostengine/goost/blob/20d8ce4c7d74c26832d69283305b25a72165784a/modules/git/SCsub
Import("env")
env_git = env.Clone()
# Thirdparty source files.
libgit2_sources = []
libgit2_sources += Glob("libgit2/src/" + "*.c")
libgit2_sources += Glob("libgit2/src/allocators/" + "*.c")
libgit2_sources += Glob("libgit2/src/hash/sha1/sha1dc/sha1.c")
libgit2_sources += Glob("libgit2/src/hash/sha1/sha1dc/ubc_check.c")
libgit2_sources += Glob("libgit2/src/hash/sha1/collisiondetect.c")
libgit2_sources += Glob("libgit2/src/transports/" + "*.c")
libgit2_sources += Glob("libgit2/src/hash/transports/" + "*.c")
libgit2_sources += Glob("libgit2/src/hash/xdiff/" + "*.c")
libgit2_sources += Glob("libgit2/src/xdiff/" + "*.c")
libgit2_sources += Glob("libgit2/src/streams/" + "*.c")
libgit2_sources += Glob("libgit2/deps/http-parser/" + "*.c")
libgit2_sources += Glob("libgit2/deps/pcre/" + "*.c")
libgit2_sources += Glob("libgit2/deps/zlib/" + "*.c")
if "32" in env["arch"]:
env_git.Prepend(CPPDEFINES=["GIT_ARCH_32"])
else:
env_git.Prepend(CPPDEFINES=["GIT_ARCH_64"])
env_git.Prepend(
CPPPATH=[
"libgit2/include/",
"libgit2/src/",
"libgit2/deps/http-parser/",
"libgit2/deps/pcre/",
"libgit2/deps/zlib/",
"libgit2/deps/ntlmclient/",
"../ssh2/libssh2/include/",
]
)
env_git.Prepend(
CPPDEFINES=[
"GIT_THREADS",
"GIT_SSH",
"GIT_SSH_MEMORY_CREDENTIALS",
"LIBGIT2_NO_FEATURES_H",
"GIT_SHA1_COLLISIONDETECT",
"GIT_HTTPS",
"SRC_UTIL_H_",
"GIT_REGEX_BUILTIN",
]
)
if env_git["platform"] == "windows":
libgit2_sources += Glob("libgit2/src/win32/" + "*.c")
env_git.Prepend(
CPPDEFINES=[
"GIT_WINHTTP",
"HAVE_SYS_STAT_H",
"HAVE_SYS_TYPES_H",
"HAVE_WINDOWS_H",
"HAVE_STDINT_H",
"HAVE_INTTYPES_H",
"HAVE_MEMMOVE",
"HAVE_STRERROR",
"HAVE_STRTOLL",
"HAVE__STRTOI64",
"SUPPORT_PCRE8",
"NO_RECURSE",
"HAVE_LONG_LONG",
"HAVE_UNSIGNED_LONG_LONG",
("NEWLINE", "10"),
("POSIX_MALLOC_THRESHOLD", "10"),
("LINK_SIZE", "2"),
("PARENS_NEST_LIMIT", "250"),
("MATCH_LIMIT", "10000000"),
("MATCH_LIMIT_RECURSION", "10000000"),
"PCREGREP_BUFSIZE",
("MAX_NAME_SIZE", "32"),
("MAX_NAME_COUNT", "10000"),
"HAVE_WINCNG",
"LIBSSH2_WINCNG"
]
)
if env_git["platform"] in ["linux", "macos"]:
env_git.Append(CCFLAGS="-fPIC")
libgit2_sources += Glob("libgit2/src/unix/" + "*.c")
libgit2_sources += [
"libgit2/deps/ntlmclient/crypt_openssl.c",
"libgit2/deps/ntlmclient/unicode_builtin.c"
]
env_git.Prepend(
CPPDEFINES=[
"HAVE_DIRENT_H",
"HAVE_SYS_STAT_H",
"HAVE_SYS_TYPES_H",
"HAVE_UNISTD_H",
"HAVE_STDINT_H",
"HAVE_INTTYPES_H",
"HAVE_BCOPY",
"HAVE_MEMMOVE",
"HAVE_STRERROR",
"HAVE_STRTOLL",
"HAVE_STRTOQ",
"SUPPORT_PCRE8",
"NO_RECURSE",
"HAVE_LONG_LONG",
"HAVE_UNSIGNED_LONG_LONG",
("NEWLINE", "10"),
("POSIX_MALLOC_THRESHOLD", "10"),
("LINK_SIZE", "2"),
("PARENS_NEST_LIMIT", "250"),
("MATCH_LIMIT", "10000000"),
("MATCH_LIMIT_RECURSION", "10000000"),
"PCREGREP_BUFSIZE",
("MAX_NAME_SIZE", "32"),
("MAX_NAME_COUNT", "10000"),
"GIT_OPENSSL",
"GIT_USE_FUTIMENS",
"GIT_USE_STAT_MTIM",
"CRYPT_OPENSSL",
"UNICODE_BUILTIN"
]
)
if env_git["platform"] == "macos":
env_git.Prepend(CPPPATH=[env_git["macos_openssl"] + "include/"])
static_ssl = File(env_git["macos_openssl_static_ssl"])
static_crypto = File(env_git["macos_openssl_static_crypto"])
env_git.Append(LIBS=[static_ssl, static_crypto])
env_git.StaticLibrary(target="../bin/" + "git2", source=libgit2_sources)

1
thirdparty/openssl vendored Submodule

Submodule thirdparty/openssl added at 17a2c51118

Binary file not shown.

Binary file not shown.

113
thirdparty/ssh2/SCsub vendored
View File

@@ -1,113 +0,0 @@
#!/usr/bin/env python
# Adopted from https://github.com/nodegit/nodegit/blob/4561dcb7c120474a4553baa27e4c4c2f4be23a2b/vendor/libgit2.gyp
Import("env")
env_ssh2 = env.Clone()
# Thirdparty source files.
libssh2_sources = [
"libssh2/src/agent.c",
"libssh2/src/bcrypt_pbkdf.c",
"libssh2/src/blowfish.c",
"libssh2/src/crypt.c",
"libssh2/src/keepalive.c",
"libssh2/src/libgcrypt.c",
"libssh2/src/openssl.c",
"libssh2/src/publickey.c",
"libssh2/src/sftp.c",
"libssh2/src/version.c",
"libssh2/src/channel.c",
"libssh2/src/global.c",
"libssh2/src/kex.c",
"libssh2/src/mac.c",
"libssh2/src/packet.c",
"libssh2/src/scp.c",
"libssh2/src/transport.c",
"libssh2/src/comp.c",
"libssh2/src/hostkey.c",
"libssh2/src/knownhost.c",
"libssh2/src/misc.c",
"libssh2/src/pem.c",
"libssh2/src/session.c",
"libssh2/src/userauth.c",
]
env_ssh2.Prepend(
CPPPATH=[
"libssh2/include/"
"libssh2/src/"
]
)
if env_ssh2["platform"] == "windows":
env_ssh2.Append(
CPPPATH=[
"libssh2/include/",
"libssh2/win32/"
]
)
libssh2_sources += ["libssh2/src/agent_win.c", "libssh2/src/wincng.c"]
env_ssh2.Append(
CPPDEFINES=[
"LIBSSH2_WINCNG",
"HAVE_WINCNG"
]
)
env_ssh2.Append(LIBS=["crypt32", "user32"])
if env_ssh2["platform"] in ["linux", "macos"]:
env_ssh2.Append(CCFLAGS="-fPIC")
env_ssh2.Append(
CPPPATH=[
".",
"libssh2/include/",
]
)
libssh2_sources += ["libssh2/src/openssl.c"]
env_ssh2.Append(
CPPDEFINES=[
"LIBSSH2_CONFIG_H",
"HAVE_SYS_UIO_H",
("HAVE_ALLOCA", 1),
("HAVE_ALLOCA_H", 1),
("HAVE_ARPA_INET_H", 1),
("HAVE_ERRNO_H", 1),
("HAVE_FCNTL_H", 1),
("HAVE_GETTIMEOFDAY", 1),
("HAVE_GETTIMEOFDAY", 1),
("HAVE_INTTYPES_H", 1),
("HAVE_LONGLONG", 1),
("HAVE_NETINET_IN_H", 1),
("HAVE_O_NONBLOCK", 1),
("HAVE_SELECT", 1),
("HAVE_STDINT_H", 1),
("HAVE_STDIO_H", 1),
("HAVE_STDLIB_H", 1),
("HAVE_STRINGS_H", 1),
("HAVE_STRING_H", 1),
("HAVE_STRTOLL", 1),
("HAVE_SYS_IOCTL_H", 1),
("HAVE_SYS_SOCKET_H", 1),
("HAVE_SYS_STAT_H", 1),
("HAVE_SYS_TIME_H", 1),
("HAVE_SYS_TYPES_H", 1),
("HAVE_SYS_UIO_H", 1),
("HAVE_SYS_UN_H", 1),
("HAVE_UNISTD_H", 1),
("LIBSSH2_CLEAR_MEMORY", 1),
("LIBSSH2_DH_GEX_NEW", 1),
("LIBSSH2_OPENSSL", 1),
("LT_OBJDIR", ".libs/"),
("STDC_HEADERS", 1)
]
)
if env_ssh2["platform"] == "macos":
env_ssh2.Append(CPPPATH=[env_ssh2["macos_openssl"] + "include/"])
static_ssl = File(env_ssh2["macos_openssl_static_ssl"])
static_crypto = File(env_ssh2["macos_openssl_static_crypto"])
env_ssh2.Append(LIBS=[static_ssl, static_crypto])
env_ssh2.StaticLibrary(target="../bin/" + "ssh2", source=libssh2_sources)

177
tools/cmake.py Normal file
View File

@@ -0,0 +1,177 @@
import os
import shlex
import sys
import SCons.Action
import SCons.Builder
import SCons.Util
# 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 shlex.split(env["cmake_default_flags"])
config = {}
if "CC" in env:
config["CMAKE_C_COMPILER"] = env["CC"]
if "CXX" in env:
config["CMAKE_CXX_COMPILER"] = env["CXX"]
if env["platform"] == "android":
api = env["android_api_level"]
abi = {
"arm64": "arm64-v8a",
"arm32": "armeabi-v7a",
"x86_32": "x86",
"x86_64": "x86_64",
}[env["arch"]]
config["CMAKE_SYSTEM_NAME"] = "Android"
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())
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
config["CMAKE_CXX_FLAGS"] = linux_flags
elif env["platform"] == "macos":
if env["arch"] == "universal":
config["CMAKE_OSX_ARCHITECTURES"] = '"x86_64;arm64"'
else:
config["CMAKE_OSX_ARCHITECTURES"] = env["arch"]
if env.get("macos_deployment_target", "default") != "default":
config["CMAKE_OSX_DEPLOYMENT_TARGET"] = env["macos_deployment_target"]
if sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ:
config["CMAKE_AR"] = env["AR"]
config["CMAKE_RANLIB"] = env["RANLIB"]
if env["arch"] == "universal":
flags = "-arch x86_64 -arch arm64"
else:
flags = "-arch " + env["arch"]
if env["macos_deployment_target"] != "default":
flags += " -mmacosx-version-min=" + env["macos_deployment_target"]
config["CMAKE_C_FLAGS"] = flags
config["CMAKE_CXX_FLAGS"] = flags
elif env["platform"] == "ios":
if env["arch"] == "universal":
raise ValueError("iOS architecture not supported: %s" % env["arch"])
config["CMAKE_SYSTEM_NAME"] = "iOS"
config["CMAKE_OSX_ARCHITECTURES"] = env["arch"]
if env.get("ios_min_version", "default") != "default":
config["CMAKE_OSX_DEPLOYMENT_TARGET"] = env["ios_min_version"]
if env["ios_simulator"]:
config["CMAKE_OSX_SYSROOT"] = "iphonesimulator"
elif env["platform"] == "windows":
config["CMAKE_SYSTEM_NAME"] = "Windows"
if env.get("is_msvc", False):
config["CMAKE_POLICY_DEFAULT_CMP0091"] = "NEW"
if env.get("debug_crt", False):
config["CMAKE_MSVC_RUNTIME_LIBRARY"] = "MultiThreadedDebugDLL"
else:
if env.get("use_static_cpp", False):
config["CMAKE_MSVC_RUNTIME_LIBRARY"] = "MultiThreaded"
else:
config["CMAKE_MSVC_RUNTIME_LIBRARY"] = "MultiThreadedDLL"
return ["-D%s=%s" % it for it in config.items()]
def cmake_emitter(target, source, env):
return [str(target[0]) + "/CMakeCache.txt"] + target[1:], [str(source[0]) + "/CMakeLists.txt"] + source[1:]
def cmake_generator(target, source, env, for_signature):
# Strip the -j option for signature to avoid rebuilding when num_jobs changes.
build = env["CMAKEBUILDCOM"].replace("-j$CMAKEBUILDJOBS", "") if for_signature else env["CMAKEBUILDCOM"]
actions = [
SCons.Action.Action("$CMAKECONFCOM", "$CMAKECONFCOMSTR"),
SCons.Action.Action(build, "$CMAKEBUILDCOMSTR"),
]
if env["CMAKE_INSTALL"]:
actions.append(
SCons.Action.Action("$CMAKEINSTALLCOM", "$CMAKEINSTALLCOMSTR"),
)
return actions
def cmake_build(
env, target_dir, source_dir, cmake_outputs=[], cmake_targets=[], cmake_options=[], dependencies=[], install=False
):
cmake_env = env.Clone()
target = env.Dir("{}/{}/{}".format(target_dir, env["platform"], env["arch"]))
source = env.Dir(source_dir)
builder_targets = [target] + [str(target) + "/" + f for f in cmake_outputs]
builder_sources = [source] + dependencies
default_flags = cmake_default_flags(env)
# Merge flags
flags = []
for df in default_flags:
if not df.startswith("-D"):
flags.append(df)
else:
f = df[2:].split("=")[0]
if f in cmake_options:
df += " " + cmake_options[f]
cmake_options.pop(f)
flags.append(df)
for opt in cmake_options:
flags.append("-D%s=%s" % (opt, cmake_options[opt]))
# Select generator
if env["cmake_generator"]:
flags.extend(["-G", env["cmake_generator"]])
elif env["platform"] == "windows":
if env.get("is_msvc", False):
flags.extend(["-G", "NMake Makefiles"])
elif sys.platform in ["win32", "msys", "cygwin"]:
flags.extend(["-G", "Ninja"])
else:
flags.extend(["-G", "Unix Makefiles"])
cmake_env.Append(CMAKECONFFLAGS=flags)
if len(cmake_targets) > 0:
cmake_env.Append(CMAKEBUILDFLAGS=["-t"] + [t for t in cmake_targets])
cmake_env["CMAKE_INSTALL"] = install
return cmake_env.CMake(builder_targets, builder_sources)
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")
def exists(env):
return True
def generate(env):
env["CMAKE"] = env["cmake"]
env["CMAKECONFFLAGS"] = SCons.Util.CLVar("")
env["CMAKECONFCOM"] = "$CMAKE -B ${TARGET.dir} $CMAKECONFFLAGS ${SOURCE.dir}"
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.AddMethod(cmake_build, "CMakeBuild")

69
tools/git2.py Normal file
View File

@@ -0,0 +1,69 @@
import os
def build_library(env, deps):
config = {
"CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release",
"OPENSSL_USE_STATIC_LIBS": 1,
"OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"],
"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,
"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],
"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":
config["CMAKE_C_FLAGS"] = "-fPIC"
else:
config["OPENSSL_ROOT_DIR"] = env["SSL_BUILD"]
is_msvc = env.get("is_msvc", False)
lib_ext = ".lib" if is_msvc else ".a"
lib_prefix = "" if is_msvc else "lib"
libs = ["{}git2{}".format(lib_prefix, lib_ext)]
source = env.Dir("#thirdparty/git2/libgit2").abspath
target = env.Dir("#bin/thirdparty/libgit2").abspath
git2 = env.CMakeBuild(
"#bin/thirdparty/git2/",
"#thirdparty/git2/libgit2",
cmake_options=config,
cmake_outputs=libs,
cmake_targets=[],
dependencies=deps,
)
env.Append(CPPPATH=["#thirdparty/git2/libgit2/include"])
env.Prepend(LIBS=git2[1:])
if env["platform"] == "windows":
env.PrependUnique(LIBS=["secur32"])
return git2
def exists(env):
return "CMake" in env
def generate(env):
env.AddMethod(build_library, "BuildGIT2")

288
tools/openssl.py Normal file
View File

@@ -0,0 +1,288 @@
import os, sys
import SCons.Util
import SCons.Builder
import SCons.Action
from SCons.Defaults import Mkdir
from SCons.Variables import PathVariable, BoolVariable
def ssl_platform_target(env):
targets = {}
platform = env["platform"]
if platform == "linux":
targets = {
"x86_32": "linux-x86",
"x86_64": "linux-x86_64",
"arm64": "linux-aarch64",
"arm32": "linux-armv4",
"rv64": "linux64-riscv64",
}
elif platform == "android":
targets = {
"arm64": "android-arm64",
"arm32": "android-arm",
"x86_32": "android-x86",
"x86_64": "android-x86_64",
}
elif platform == "macos":
targets = {
"x86_64": "darwin64-x86_64",
"arm64": "darwin64-arm64",
}
elif platform == "ios":
if env["ios_simulator"]:
targets = {
"x86_64": "iossimulator-xcrun",
"arm64": "iossimulator-xcrun",
}
else:
targets = {
"arm64": "ios64-xcrun",
"arm32": "ios-xcrun",
}
elif platform == "windows":
if env.get("is_msvc", False):
targets = {
"x86_32": "VC-WIN32",
"x86_64": "VC-WIN64A",
}
else:
targets = {
"x86_32": "mingw",
"x86_64": "mingw64",
}
arch = env["arch"]
target = targets.get(arch, "")
if target == "":
raise ValueError("Architecture '%s' not supported for platform: '%s'" % (arch, platform))
return target
def ssl_platform_options(env):
ssl_config_options = [
"no-ssl2",
"no-ssl3",
"no-weak-ssl-ciphers",
"no-legacy",
"no-shared",
"no-tests",
]
if env["platform"] == "windows":
ssl_config_options.append("enable-capieng")
return ssl_config_options
def ssl_platform_flags(env):
args = []
if env["platform"] == "android":
if env.get("android_api_level", ""):
api = int(env["android_api_level"])
args.append("-D__ANDROID_API__=%s" % api)
elif env["platform"] == "macos":
if env["macos_deployment_target"] != "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"]:
args.append("%s=%s" % (k, env[k]))
elif env["platform"] == "windows":
is_win_host = sys.platform in ["win32", "msys", "cygwin"]
if not (is_win_host or env.get("is_msvc", False)):
mingw_prefixes = {
"x86_32": "--cross-compile-prefix=i686-w64-mingw32-",
"x86_64": "--cross-compile-prefix=x86_64-w64-mingw32-",
}
args.append(mingw_prefixes[env["arch"]])
return args
def ssl_configure_args(env):
if env.get("openssl_configure_options", ""):
opts = SCons.Util.CLVar(env["openssl_configure_options"])
else:
opts = ssl_platform_options(env)
if env.get("openssl_configure_target", ""):
target = [env["openssl_configure_target"]]
else:
target = [ssl_platform_target(env)]
if env.get("openssl_configure_flags", ""):
flags = SCons.Util.CLVar(env["openssl_configure_flags"])
else:
flags = ssl_platform_flags(env)
return opts + target + flags
def ssl_emitter(target, source, env):
return env["SSL_LIBS"], [env.File(env["SSL_SOURCE"] + "/Configure"), env.File(env["SSL_SOURCE"] + "/VERSION.dat")]
def build_openssl(env, jobs=None):
if env["SSL_EXTERNAL"]:
# Setup the env to use the provided libraries, and return them without building.
env.Prepend(CPPPATH=[env["SSL_INCLUDE"]])
env.Prepend(LIBPATH=[env["SSL_BUILD"]])
if env["platform"] == "windows":
env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"])
env.Prepend(LIBS=env["SSL_LIBS"])
return [env["SSL_CRYPTO_LIBRARY"], env["SSL_LIBRARY"]]
if jobs is None:
jobs = int(env.GetOption("num_jobs"))
# Since the OpenSSL build system does not support macOS universal binaries, we first need to build the two libraries
# separately, then we join them together using lipo.
if env["platform"] == "macos" and env["arch"] == "universal":
build_envs = {
"x86_64": env.Clone(),
"arm64": env.Clone(),
}
arch_ssl = []
for arch in build_envs:
benv = build_envs[arch]
benv["arch"] = arch
generate(benv)
benv["SSLBUILDJOBS"] = max([1, int(jobs / len(build_envs))])
ssl = benv.OpenSSLBuilder()
arch_ssl.extend(ssl)
benv.NoCache(ssl) # Needs refactoring to properly cache generated headers.
# x86_64 and arm64 includes are equivalent.
env["SSL_INCLUDE"] = build_envs["arm64"]["SSL_INCLUDE"]
# Join libraries using lipo.
lipo_action = "lipo $SOURCES -create -output $TARGET"
ssl_libs = list(map(lambda arch: build_envs[arch]["SSL_LIBRARY"], build_envs))
ssl_crypto_libs = list(map(lambda arch: build_envs[arch]["SSL_CRYPTO_LIBRARY"], build_envs))
ssl = env.Command(env["SSL_LIBRARY"], ssl_libs, lipo_action)
ssl += env.Command(env["SSL_CRYPTO_LIBRARY"], ssl_crypto_libs, lipo_action)
env.Depends(ssl, arch_ssl)
else:
benv = env.Clone()
benv["SSLBUILDJOBS"] = jobs
ssl = benv.OpenSSLBuilder()
benv.NoCache(ssl) # Needs refactoring to properly cache generated headers.
# Setup the environment to use the freshly built openssl.
env.Prepend(CPPPATH=[env["SSL_INCLUDE"]])
env.Prepend(LIBPATH=[env["SSL_BUILD"]])
if env["platform"] == "windows":
env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"])
env.Prepend(LIBS=env["SSL_LIBS"])
return ssl
def ssl_generator(target, source, env, for_signature):
# Strip the -j option for signature to avoid rebuilding when num_jobs changes.
build = env["SSLBUILDCOM"].replace("-j$SSLBUILDJOBS", "") if for_signature else env["SSLBUILDCOM"]
return [
Mkdir("$SSL_BUILD"),
Mkdir("$SSL_INSTALL"),
SCons.Action.Action("$SSLCONFIGCOM", "$SSLCONFIGCOMSTR"),
SCons.Action.Action(build, "$SSLBUILDCOMSTR"),
]
def options(opts):
opts.Add(PathVariable("openssl_source", "Path to the openssl sources.", "thirdparty/openssl"))
opts.Add("openssl_build", "Destination path of the openssl build.", "bin/thirdparty/openssl")
opts.Add(
"openssl_configure_options",
"OpenSSL configure options override. Will use a reasonable default if not specified.",
"",
)
opts.Add(
"openssl_configure_target", "OpenSSL configure target override, will be autodetected if not specified.", ""
)
opts.Add(
"openssl_configure_flags",
"OpenSSL configure compiler flags override. Will be autodetected if not specified.",
"",
)
opts.Add(
"openssl_external_crypto",
'An external libcrypto static library (e.g. "/usr/lib/x86_64-linux-gnu/libcrypto.a"). If not provided, OpenSSL will be built from source.',
"",
)
opts.Add(
"openssl_external_ssl",
'An external libssl static library (e.g. "/usr/lib/x86_64-linux-gnu/libssl.a"). If not provided, OpenSSL will be built from source.',
"",
)
opts.Add(
"openssl_external_include",
'An external OpenSSL "include" folder (e.g. "/usr/include/openssl").',
"",
)
def exists(env):
return True
def generate(env):
env.AddMethod(build_openssl, "OpenSSL")
# 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, "") != ""
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)):
print('Error: The options "%s" must all be set to use a external library.' % '", "'.join(external_opts))
sys.exit(255)
env["SSL_CRYPTO_LIBRARY"] = env.File("${openssl_external_crypto}")
env["SSL_LIBRARY"] = env.File("${openssl_external_ssl}")
env["SSL_BUILD"] = env.Dir("${SSL_LIBRARY.dir}").abspath
env["SSL_INSTALL"] = env.Dir("${SSL_LIBRARY.dir}").abspath
env["SSL_INCLUDE"] = env.Dir("${openssl_external_include}").abspath
env["SSL_LIBS"] = [env["SSL_LIBRARY"], env["SSL_CRYPTO_LIBRARY"]]
env["SSL_EXTERNAL"] = True
return
# We will need to build our own OpenSSL library.
env["SSL_EXTERNAL"] = False
# Android needs the NDK in ENV, and proper PATH setup.
if env["platform"] == "android" and env["ENV"].get("ANDROID_NDK_ROOT", "") == "":
cc_path = os.path.dirname(env["CC"])
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", ""))
env["SSL_SOURCE"] = env.Dir(env["openssl_source"]).abspath
env["SSL_BUILD"] = env.Dir(env["openssl_build"] + "/{}/{}".format(env["platform"], env["arch"])).abspath
env["SSL_INSTALL"] = env.Dir(env["SSL_BUILD"] + "/dest").abspath
env["SSL_INCLUDE"] = env.Dir(env["SSL_INSTALL"] + "/include").abspath
lib_ext = ".lib" if env.get("is_msvc", False) else ".a"
env["SSL_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libssl" + lib_ext)
env["SSL_CRYPTO_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libcrypto" + lib_ext)
env["SSL_LIBS"] = [env["SSL_LIBRARY"], env["SSL_CRYPTO_LIBRARY"]]
# Configure action
env["PERL"] = env.get("PERL", "perl")
env["_ssl_configure_args"] = ssl_configure_args
env["SSLPLATFORMCONFIG"] = "${_ssl_configure_args(__env__)}"
env["SSLCONFFLAGS"] = SCons.Util.CLVar("")
# fmt: off
env["SSLCONFIGCOM"] = 'cd ${TARGET.dir} && $PERL -- ${SOURCE.abspath} --prefix="${SSL_INSTALL}" --openssldir="${SSL_INSTALL}" $SSLPLATFORMCONFIG $SSLCONFFLAGS'
# fmt: on
# Build action
env["SSLBUILDJOBS"] = "${__env__.GetOption('num_jobs')}"
# fmt: off
env["SSLBUILDCOM"] = "make -j$SSLBUILDJOBS -C ${TARGET.dir} && make -j$SSLBUILDJOBS -C ${TARGET.dir} install_sw install_ssldirs"
# fmt: on
# Windows MSVC needs to build using NMake
if env["platform"] == "windows" and env.get("is_msvc", False):
env["SSLBUILDCOM"] = "cd ${TARGET.dir} && nmake install_sw install_ssldirs"
env["BUILDERS"]["OpenSSLBuilder"] = SCons.Builder.Builder(generator=ssl_generator, emitter=ssl_emitter)
env.AddMethod(build_openssl, "OpenSSL")

53
tools/ssh2.py Normal file
View File

@@ -0,0 +1,53 @@
import os
def build_library(env, deps):
config = {
"CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release",
"OPENSSL_USE_STATIC_LIBS": 1,
"OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"],
"OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"].abspath,
"OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"].abspath,
"OPENSSL_ROOT_DIR": env["SSL_INSTALL"],
"BUILD_EXAMPLES": 0,
"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,
}
if env["platform"] != "windows":
config["CMAKE_C_FLAGS"] = "-fPIC"
else:
config["OPENSSL_ROOT_DIR"] = env["SSL_BUILD"]
is_msvc = env.get("is_msvc", False)
lib_ext = ".lib" if is_msvc else ".a"
libs = ["src/libssh2{}".format(lib_ext)]
source = env.Dir("#thirdparty/ssh2/libssh2").abspath
target = env.Dir("#bin/thirdparty/libssh2").abspath
ssh2 = env.CMakeBuild(
"#bin/thirdparty/ssh2/",
"#thirdparty/ssh2/libssh2",
cmake_options=config,
cmake_outputs=libs,
cmake_targets=[],
dependencies=deps,
)
env.Append(CPPPATH=["#thirdparty/ssh2/libssh2/include"])
env.Prepend(LIBS=ssh2[1:])
return ssh2
def exists(env):
return "CMake" in env
def generate(env):
env.AddMethod(build_library, "BuildSSH2")