Skip to content

Commit eafe6d9

Browse files
authored
Merge pull request #477 from o01eg/ci-test-execute-3.2
Test built GDNative plugin with stable Godot
2 parents e2831ff + 279d63d commit eafe6d9

File tree

7 files changed

+305
-0
lines changed

7 files changed

+305
-0
lines changed

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ jobs:
2121
sudo apt-get update -qq
2222
sudo apt-get install -qqq build-essential pkg-config
2323
python -m pip install scons
24+
curl -LO https://downloads.tuxfamily.org/godotengine/3.2.3/Godot_v3.2.3-stable_linux_server.64.zip
25+
unzip Godot_v3.2.3-stable_linux_server.64.zip
2426
2527
- name: Build godot-cpp
2628
run: |
@@ -33,6 +35,14 @@ jobs:
3335
path: bin/libgodot-cpp.linux.release.64.a
3436
if-no-files-found: error
3537

38+
- name: Build test GDNative library
39+
run: |
40+
scons target=release platform=linux bits=64 -j $(nproc) -C test
41+
42+
- name: Run test GDNative library
43+
run: |
44+
./Godot_v3.2.3-stable_linux_server.64 --path test -s script.gd
45+
3646
windows-msvc:
3747
name: Build (Windows, MSVC)
3848
runs-on: windows-2019
@@ -113,6 +123,8 @@ jobs:
113123
- name: Install dependencies
114124
run: |
115125
python -m pip install scons
126+
curl -LO https://downloads.tuxfamily.org/godotengine/3.2.3/Godot_v3.2.3-stable_osx.64.zip
127+
unzip Godot_v3.2.3-stable_osx.64.zip
116128
117129
- name: Build godot-cpp
118130
run: |
@@ -125,6 +137,14 @@ jobs:
125137
path: bin/libgodot-cpp.osx.release.64.a
126138
if-no-files-found: error
127139

140+
- name: Build test GDNative library
141+
run: |
142+
scons target=release platform=osx bits=64 -j $(sysctl -n hw.logicalcpu) -C test
143+
144+
- name: Run test GDNative library
145+
run: |
146+
./Godot.app/Contents/MacOS/Godot --path test -s script.gd
147+
128148
static-checks:
129149
name: Static Checks (clang-format)
130150
runs-on: ubuntu-16.04

test/SConstruct

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/usr/bin/env python
2+
import os
3+
import sys
4+
5+
# Try to detect the host platform automatically.
6+
# This is used if no `platform` argument is passed
7+
if sys.platform.startswith('linux'):
8+
host_platform = 'linux'
9+
elif sys.platform == 'darwin':
10+
host_platform = 'osx'
11+
elif sys.platform == 'win32' or sys.platform == 'msys':
12+
host_platform = 'windows'
13+
else:
14+
raise ValueError(
15+
'Could not detect platform automatically, please specify with '
16+
'platform=<platform>'
17+
)
18+
19+
env = Environment(ENV = os.environ)
20+
21+
opts = Variables([], ARGUMENTS)
22+
23+
# Define our options
24+
opts.Add(EnumVariable('target', "Compilation target", 'debug', ['d', 'debug', 'r', 'release']))
25+
opts.Add(EnumVariable('platform', "Compilation platform", host_platform, ['', 'windows', 'x11', 'linux', 'osx']))
26+
opts.Add(EnumVariable('p', "Compilation target, alias for 'platform'", host_platform, ['', 'windows', 'x11', 'linux', 'osx']))
27+
opts.Add(EnumVariable('bits', 'Target platform bits', '64', ('32', '64')))
28+
opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no'))
29+
opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'bin/', PathVariable.PathAccept))
30+
opts.Add(PathVariable('target_name', 'The library name.', 'libgdexample', PathVariable.PathAccept))
31+
32+
# Local dependency paths, adapt them to your setup
33+
godot_headers_path = "../godot_headers/"
34+
cpp_bindings_path = "../"
35+
cpp_library = "libgodot-cpp"
36+
37+
# only support 64 at this time..
38+
bits = 64
39+
40+
# Updates the environment with the option variables.
41+
opts.Update(env)
42+
# Generates help for the -h scons option.
43+
Help(opts.GenerateHelpText(env))
44+
45+
# This makes sure to keep the session environment variables on Windows.
46+
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
47+
# all the required tools
48+
if host_platform == 'windows' and env['platform'] != 'android':
49+
if env['bits'] == '64':
50+
env = Environment(TARGET_ARCH='amd64')
51+
elif env['bits'] == '32':
52+
env = Environment(TARGET_ARCH='x86')
53+
54+
opts.Update(env)
55+
56+
# Process some arguments
57+
if env['use_llvm']:
58+
env['CC'] = 'clang'
59+
env['CXX'] = 'clang++'
60+
61+
if env['p'] != '':
62+
env['platform'] = env['p']
63+
64+
if env['platform'] == '':
65+
print("No valid target platform selected.")
66+
quit();
67+
68+
# For the reference:
69+
# - CCFLAGS are compilation flags shared between C and C++
70+
# - CFLAGS are for C-specific compilation flags
71+
# - CXXFLAGS are for C++-specific compilation flags
72+
# - CPPFLAGS are for pre-processor flags
73+
# - CPPDEFINES are for pre-processor defines
74+
# - LINKFLAGS are for linking flags
75+
76+
# Check our platform specifics
77+
if env['platform'] == "osx":
78+
env['target_path'] += 'osx/'
79+
cpp_library += '.osx'
80+
env.Append(CCFLAGS=['-arch', 'x86_64'])
81+
env.Append(CXXFLAGS=['-std=c++17'])
82+
env.Append(LINKFLAGS=['-arch', 'x86_64'])
83+
if env['target'] in ('debug', 'd'):
84+
env.Append(CCFLAGS=['-g', '-O2'])
85+
else:
86+
env.Append(CCFLAGS=['-g', '-O3'])
87+
88+
elif env['platform'] in ('x11', 'linux'):
89+
env['target_path'] += 'x11/'
90+
cpp_library += '.linux'
91+
env.Append(CCFLAGS=['-fPIC'])
92+
env.Append(CXXFLAGS=['-std=c++17'])
93+
if env['target'] in ('debug', 'd'):
94+
env.Append(CCFLAGS=['-g3', '-Og'])
95+
else:
96+
env.Append(CCFLAGS=['-g', '-O3'])
97+
98+
elif env['platform'] == "windows":
99+
env['target_path'] += 'win64/'
100+
cpp_library += '.windows'
101+
# This makes sure to keep the session environment variables on windows,
102+
# that way you can run scons in a vs 2017 prompt and it will find all the required tools
103+
env.Append(ENV=os.environ)
104+
105+
env.Append(CPPDEFINES=['WIN32', '_WIN32', '_WINDOWS', '_CRT_SECURE_NO_WARNINGS'])
106+
env.Append(CCFLAGS=['-W3', '-GR'])
107+
if env['target'] in ('debug', 'd'):
108+
env.Append(CPPDEFINES=['_DEBUG'])
109+
env.Append(CCFLAGS=['-EHsc', '-MDd', '-ZI'])
110+
env.Append(LINKFLAGS=['-DEBUG'])
111+
else:
112+
env.Append(CPPDEFINES=['NDEBUG'])
113+
env.Append(CCFLAGS=['-O2', '-EHsc', '-MD'])
114+
115+
if env['target'] in ('debug', 'd'):
116+
cpp_library += '.debug'
117+
else:
118+
cpp_library += '.release'
119+
120+
cpp_library += '.' + str(bits)
121+
122+
# make sure our binding library is properly includes
123+
env.Append(CPPPATH=['.', godot_headers_path, cpp_bindings_path + 'include/', cpp_bindings_path + 'include/core/', cpp_bindings_path + 'include/gen/'])
124+
env.Append(LIBPATH=[cpp_bindings_path + 'bin/'])
125+
env.Append(LIBS=[cpp_library])
126+
127+
# tweak this if you want to use different folders, or more folders, to store your source code in.
128+
env.Append(CPPPATH=['src/'])
129+
sources = Glob('src/*.cpp')
130+
131+
library = env.SharedLibrary(target=env['target_path'] + env['target_name'] , source=sources)
132+
133+
Default(library)
134+

test/gdexample.gdnlib

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[general]
2+
3+
singleton=false
4+
load_once=true
5+
symbol_prefix="godot_"
6+
reloadable=false
7+
8+
[entry]
9+
10+
X11.64="res://bin/x11/libgdexample.so"
11+
Server.64="res://bin/x11/libgdexample.so"
12+
Windows.64="res://bin/win64/libgdexample.dll"
13+
OSX.64="res://bin/osx/libgdexample.dylib"
14+
15+
[dependencies]
16+
17+
X11.64=[]
18+
Server.64=[]
19+
Windows.64=[]
20+
OSX.64=[]

test/gdexample.gdns

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[gd_resource type="NativeScript" load_steps=2 format=2]
2+
3+
[ext_resource path="res://gdexample.gdnlib" type="GDNativeLibrary" id=1]
4+
5+
[resource]
6+
7+
resource_name = "gdexample"
8+
class_name = "SimpleClass"
9+
library = ExtResource( 1 )

test/project.godot

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
; Engine configuration file.
2+
; It's best edited using the editor UI and not directly,
3+
; since the parameters that go here are not all obvious.
4+
;
5+
; Format:
6+
; [section] ; section goes between []
7+
; param=value ; assign values to parameters
8+
9+
config_version=4
10+
11+
_global_script_classes=[ ]
12+
_global_script_class_icons={
13+
14+
}
15+
16+
[application]
17+
18+
config/name="Test CI project"
19+

test/script.gd

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
extends MainLoop
3+
4+
func _initialize():
5+
OS.exit_code = 1
6+
var native_script = load("res://gdexample.gdns")
7+
print("Native Script ", native_script)
8+
if native_script == null || !is_instance_valid(native_script):
9+
return
10+
print("Library ", native_script.library)
11+
if native_script.library == null || !is_instance_valid(native_script.library):
12+
return
13+
var ref = native_script.new()
14+
print("Reference ", ref)
15+
if ref == null || !is_instance_valid(ref):
16+
return
17+
print("Reference name ", ref.name)
18+
if ref.name != "SimpleClass":
19+
return
20+
print("Reference value ", ref.value)
21+
if ref.value != 0:
22+
return
23+
print("Call method ", ref.method(1))
24+
if ref.method(1) != 1:
25+
return
26+
OS.exit_code = 0
27+
28+
func _idle(_delta):
29+
return true
30+

test/src/init.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include <Godot.hpp>
2+
#include <Reference.hpp>
3+
4+
using namespace godot;
5+
6+
class SimpleClass : public Reference {
7+
GODOT_CLASS(SimpleClass, Reference);
8+
9+
public:
10+
SimpleClass() {}
11+
12+
/** `_init` must exist as it is called by Godot. */
13+
void _init() {
14+
_name = String("SimpleClass");
15+
_value = 0;
16+
}
17+
18+
void test_void_method() {
19+
Godot::print("This is test");
20+
}
21+
22+
Variant method(Variant arg) {
23+
Variant ret;
24+
ret = arg;
25+
26+
return ret;
27+
}
28+
29+
static void _register_methods() {
30+
register_method("method", &SimpleClass::method);
31+
32+
/**
33+
* The line below is equivalent to the following GDScript export:
34+
* export var _name = "SimpleClass"
35+
**/
36+
register_property<SimpleClass, String>("name", &SimpleClass::_name, String("SimpleClass"));
37+
38+
/** Alternatively, with getter and setter methods: */
39+
register_property<SimpleClass, int>("value", &SimpleClass::set_value, &SimpleClass::get_value, 0);
40+
41+
/** Registering a signal: **/
42+
register_signal<SimpleClass>("signal_name0"); // windows: error C2668: 'godot::register_signal': ambiguous call to overloaded function
43+
register_signal<SimpleClass>("signal_name1", "string_argument", GODOT_VARIANT_TYPE_STRING);
44+
}
45+
46+
String _name;
47+
int _value;
48+
49+
void set_value(int p_value) {
50+
_value = p_value;
51+
}
52+
53+
int get_value() const {
54+
return _value;
55+
}
56+
};
57+
58+
/** GDNative Initialize **/
59+
extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) {
60+
godot::Godot::gdnative_init(o);
61+
}
62+
63+
/** GDNative Terminate **/
64+
extern "C" void GDN_EXPORT godot_gdnative_terminate(godot_gdnative_terminate_options *o) {
65+
godot::Godot::gdnative_terminate(o);
66+
}
67+
68+
/** NativeScript Initialize **/
69+
extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) {
70+
godot::Godot::nativescript_init(handle);
71+
72+
godot::register_class<SimpleClass>();
73+
}

0 commit comments

Comments
 (0)