Skip to content

Commit 2478fe2

Browse files
committed
Add Windows support.
1 parent 4943d52 commit 2478fe2

File tree

6 files changed

+83
-8
lines changed

6 files changed

+83
-8
lines changed

README.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ git clone --recursive https://github.com/migeran/libgodot_project
3535
3636
cd libgodot_project
3737
38-
# Build for the host platform (Mac and Linux)
38+
# Build for Mac and Linux
3939
./build_libgodot.sh
4040
41+
# Or build for Windows
42+
build_libgodot.bat
43+
4144
# Build for iOS (Mac only)
4245
./build_libgodot.sh --target ios
4346
```
@@ -48,6 +51,7 @@ The C++ sample shows how Godot can be controlled by a host process, by displayin
4851

4952
After libgodot is compiled successfully, run the following commands to test the C++ sample:
5053

54+
On Linux and MacOS:
5155
```
5256
cd samples/cpp_sample
5357
mkdir build
@@ -56,6 +60,16 @@ cd build
5660
./sample
5761
```
5862

63+
On Windows:
64+
```
65+
cd samples/cpp_sample
66+
mkdir build
67+
cmake -S . -B build -G Ninja
68+
cd build
69+
ninja
70+
sample.exe
71+
```
72+
5973
### SwiftUI Sample
6074

6175
To test the SwiftUI sample, just open the ios_sample project in XCode 15.1+, build it and run on any iOS device. (iOS Simulator is not supported due to Godot limitations.)
@@ -96,7 +110,7 @@ This class is made accessible over the GDExtension API. This class can be used t
96110
To actually create a Godot instance a new symbol is added to the GDExtension API:
97111
98112
```cpp
99-
GDExtensionObjectPtr gdextension_create_godot_instance(int p_argc, char *p_argv[], GDExtensionInitializationFunction p_init_func);
113+
GDExtensionObjectPtr libgodot_create_godot_instance(int p_argc, char *p_argv[], GDExtensionInitializationFunction p_init_func, void *p_platform_data);
100114
```
101115

102116
This function can be used to create a new Godot instance and return a GodotInstance object reference to control it. Both samples show how easy it is to bind this function and then use the generated GDExtension API bindings with the returned GodotInstance object.

build_libgodot.bat

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
set BASE_DIR=%~dp0
2+
3+
cd %BASE_DIR%
4+
mkdir build
5+
6+
cd godot
7+
8+
call scons platform=windows arch=x86_64 verbose=yes msvc=yes dev_build=yes debug_symbols=yes
9+
call scons platform=windows target=template_debug arch=x86_64 verbose=yes msvc=yes library_type=shared_library dev_build=yes debug_symbols=yes
10+
11+
copy /y bin\godot.windows.template_debug.dev.x86_64.dll ..\build\libgodot.dll
12+
13+
start /wait bin\godot.windows.editor.dev.x86_64.exe --dump-extension-api
14+
copy /y extension_api.json ..\build\extension_api.json
15+
copy /y ..\build\extension_api.json ..\godot-cpp\gdextension
16+
copy /y core\extension\gdextension_interface.h ..\godot-cpp\gdextension
17+
18+
cd ..

godot

Submodule godot updated from 2f82b24 to 255be24

godot-cpp

Submodule godot-cpp updated 69 files

samples/cpp_sample/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ target_include_directories(${PROJECT_NAME} SYSTEM
2222
${GODOT_CPP_DIR}/gen/include
2323
${GODOT_CPP_DIR}/gdextension
2424
)
25-
target_link_libraries(${PROJECT_NAME} dl godot-cpp Threads::Threads)
25+
if (WIN32)
26+
target_link_libraries(${PROJECT_NAME} godot-cpp Threads::Threads)
27+
else()
28+
target_link_libraries(${PROJECT_NAME} dl godot-cpp Threads::Threads)
29+
endif (WIN32)
2630
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
2731
COMMAND ${CMAKE_COMMAND} -E copy
2832
${LIBGODOT_BUILD_DIR}/libgodot${CMAKE_SHARED_LIBRARY_SUFFIX}

samples/cpp_sample/src/main.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#include <stdlib.h>
22
#include <stdio.h>
3+
#if defined(__APPLE__) || defined(__unix__)
34
#include <dlfcn.h>
5+
#elif defined(_WIN32)
6+
#include <windows.h>
7+
#endif
48
#include <string>
59
#include <vector>
610

@@ -13,8 +17,10 @@
1317

1418
#ifdef __APPLE__
1519
#define LIBGODOT_LIBRARY_NAME "libgodot.dylib"
16-
#else
20+
#elif defined(__unix__)
1721
#define LIBGODOT_LIBRARY_NAME "./libgodot.so"
22+
#elif defined(_WIN32)
23+
#define LIBGODOT_LIBRARY_NAME "libgodot.dll"
1824
#endif
1925

2026
extern "C" {
@@ -47,6 +53,7 @@ GDExtensionBool GDE_EXPORT gdextension_default_init(GDExtensionInterfaceGetProcA
4753
class LibGodot {
4854
public:
4955
LibGodot(std::string p_path = LIBGODOT_LIBRARY_NAME) {
56+
#if defined(__APPLE__) || defined(__unix__)
5057
handle = dlopen(p_path.c_str(), RTLD_LAZY);
5158
if (handle == nullptr) {
5259
fprintf(stderr, "Error opening libgodot: %s\n", dlerror());
@@ -66,23 +73,49 @@ class LibGodot {
6673
handle == nullptr;
6774
return;
6875
}
76+
#elif defined(_WIN32)
77+
LPCSTR libgodot_library_name = reinterpret_cast<LPCSTR>(LIBGODOT_LIBRARY_NAME);
78+
handle = LoadLibrary(libgodot_library_name);
79+
if (handle == NULL) {
80+
fprintf(stderr, "Error opening libgodot: %lu\n", GetLastError());
81+
return;
82+
}
83+
func_libgodot_create_godot_instance = (GDExtensionObjectPtr (*)(int, char *[], GDExtensionInitializationFunction, void *))GetProcAddress(handle, "libgodot_create_godot_instance");
84+
if (func_libgodot_create_godot_instance == NULL) {
85+
fprintf(stderr, "Error acquiring function: %lu\n", GetLastError());
86+
FreeLibrary(handle);
87+
return;
88+
}
89+
#endif
6990
}
7091

7192
~LibGodot() {
7293
if (is_open()) {
94+
#if defined(__APPLE__) || defined(__unix__)
7395
dlclose(handle);
96+
#elif defined(_WIN32)
97+
FreeLibrary(handle);
98+
#endif
7499
}
75100
}
76101

77102
bool is_open() {
103+
#if defined(__APPLE__) || defined(__unix__)
78104
return handle != nullptr && func_libgodot_create_godot_instance != nullptr;
105+
#elif defined(_WIN32)
106+
return handle != NULL && func_libgodot_create_godot_instance != NULL;
107+
#endif
79108
}
80109

81110
godot::GodotInstance *create_godot_instance(int p_argc, char *p_argv[], GDExtensionInitializationFunction p_init_func = gdextension_default_init) {
82111
if (!is_open()) {
83112
return nullptr;
84113
}
85-
GDExtensionObjectPtr instance = func_libgodot_create_godot_instance(p_argc, p_argv, p_init_func);
114+
#if defined(__APPLE__) || defined(__unix__)
115+
GDExtensionObjectPtr instance = func_libgodot_create_godot_instance(p_argc, p_argv, p_init_func, nullptr);
116+
#elif defined(_WIN32)
117+
GDExtensionObjectPtr instance = func_libgodot_create_godot_instance(p_argc, p_argv, p_init_func, handle);
118+
#endif
86119
if (instance == nullptr) {
87120
return nullptr;
88121
}
@@ -95,9 +128,15 @@ class LibGodot {
95128
}
96129

97130
private:
131+
#if defined(__APPLE__) || defined(__unix__)
98132
void *handle = nullptr;
99-
GDExtensionObjectPtr (*func_libgodot_create_godot_instance)(int, char *[], GDExtensionInitializationFunction) = nullptr;
133+
GDExtensionObjectPtr (*func_libgodot_create_godot_instance)(int, char *[], GDExtensionInitializationFunction, void *) = nullptr;
100134
void (*func_libgodot_destroy_godot_instance)(GDExtensionObjectPtr) = nullptr;
135+
#elif defined(_WIN32)
136+
HINSTANCE handle = NULL;
137+
GDExtensionObjectPtr (*func_libgodot_create_godot_instance)(int, char *[], GDExtensionInitializationFunction, void *) = NULL;
138+
void (*func_libgodot_destroy_godot_instance)(GDExtensionObjectPtr) = NULL;
139+
#endif
101140
};
102141

103142
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)