From e4fdf70bcabbeec2d181a742f9c13e507017dc1c Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Wed, 29 Jun 2022 20:48:12 +0700 Subject: [PATCH] Support building for Windows using MinGW compiler - Adds docker support for building Windows binaries on Linux. - Update libuv to version 1.44.1. - Use MinGW compiled 64bit Windows binaries for distribution. --- .github/actions/cache-submodules/action.yaml | 2 +- .github/workflows/main.yml | 22 +++++--- addons/godot_xterm/native/SConstruct | 31 +++++++--- addons/godot_xterm/native/docker-compose.yaml | 56 ++++++++++++++++++- .../native/godotxtermnative.gdnlib | 2 +- .../native/src/libgodotxtermnative.cpp | 8 ++- .../native/src/node_pty/win/path_util.cc | 14 ++--- .../native/src/node_pty/win/path_util.h | 8 ++- addons/godot_xterm/native/thirdparty/libuv | 2 +- addons/godot_xterm/native/windows.Dockerfile | 6 ++ 10 files changed, 115 insertions(+), 36 deletions(-) create mode 100644 addons/godot_xterm/native/windows.Dockerfile diff --git a/.github/actions/cache-submodules/action.yaml b/.github/actions/cache-submodules/action.yaml index f27cee9..376a09b 100644 --- a/.github/actions/cache-submodules/action.yaml +++ b/.github/actions/cache-submodules/action.yaml @@ -17,7 +17,7 @@ runs: working-directory: addons/godot_xterm/native/thirdparty shell: bash run: | - cache_version=1 # Increment this number to invalidate the cache. + cache_version=2 # Increment this number to invalidate the cache. godot_cpp_rev=$(git ls-tree HEAD godot-cpp --object-only) libuv_rev=$(git ls-tree HEAD libuv --object-only) libtsm_rev=$(git ls-tree HEAD libtsm --object-only) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f212654..baf3d61 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,13 +14,17 @@ env: jobs: build_docker: - name: 'Build Docker (linux, ${{ matrix.target }}, ${{ matrix.bits }})' + name: 'Build Docker (${{ matrix.platform }}, ${{ matrix.target }}, ${{ matrix.bits }})' runs-on: ubuntu-latest strategy: fail-fast: false matrix: + platform: [ linux, windows ] target: [ release, debug ] bits: [ 64, 32 ] + exclude: + - platform: windows + bits: 32 # 32-bit MinGW builds not currently working. steps: - uses: actions/checkout@v2 with: @@ -29,7 +33,7 @@ jobs: uses: ./.github/actions/cache-submodules id: cache-submodules with: - platform: linux + platform: ${{ matrix.platform }} target: ${{ matrix.target }} bits: ${{ matrix.bits }} - name: Pull docker images @@ -42,20 +46,21 @@ jobs: if: steps.cache-submodules.outputs.cache-hit != 'true' working-directory: addons/godot_xterm/native run: | - docker-compose build godot-cpp-linux - UID_GID="$(id -u):$(id -g)" docker-compose run -e TARGET=${{ matrix.target }} -e BITS=${{ matrix.bits }} godot-cpp-linux + docker-compose build godot-cpp-${{ matrix.platform }} + UID_GID="$(id -u):$(id -g)" docker-compose run -e TARGET=${{ matrix.target }} -e BITS=${{ matrix.bits }} godot-cpp-${{ matrix.platform }} - name: Build libuv if: steps.cache-submodules.outputs.cache-hit != 'true' working-directory: addons/godot_xterm/native - run: UID_GID="$(id -u):$(id -g)" docker-compose run -e TARGET=${{ matrix.target }} -e BITS=${{ matrix.bits }} libuv-linux + run: UID_GID="$(id -u):$(id -g)" docker-compose run -e TARGET=${{ matrix.target }} -e BITS=${{ matrix.bits }} libuv-${{ matrix.platform }} - name: Build libgodot-xterm working-directory: addons/godot_xterm/native - run: UID_GID="$(id -u):$(id -g)" docker-compose run -e TARGET=${{ matrix.target }} -e BITS=${{ matrix.bits }} libgodot-xterm-linux + run: UID_GID="$(id -u):$(id -g)" docker-compose run -e TARGET=${{ matrix.target }} -e BITS=${{ matrix.bits }} libgodot-xterm-${{ matrix.platform }} - name: Upload binaries uses: actions/upload-artifact@v2 with: name: libgodot-xterm-${{ matrix.target }} path: | + addons/godot_xterm/native/bin/*.dll addons/godot_xterm/native/bin/*.so build_native: @@ -125,7 +130,7 @@ jobs: scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} generate_bindings=yes -j2 - name: Setup cmake if: steps.cache-submodules.outputs.cache-hit != 'true' - uses: jwlawson/actions-setup-cmake@v1.9 + uses: jwlawson/actions-setup-cmake@v1 with: cmake-version: '3.23.2' use-32bit: ${{ matrix.bits == 32 && matrix.os == 'windows-latest' }} @@ -160,13 +165,14 @@ jobs: cd addons/godot_xterm/native scons platform=${{ matrix.platform }} target=${{ matrix.target }} bits=${{ matrix.bits }} -j2 - name: Upload binaries + if: ${{ matrix.os != 'windows-latest' && matrix.bits != '64' }} uses: actions/upload-artifact@v2 with: name: libgodot-xterm-${{ matrix.target }} path: | + addons/godot_xterm/native/bin/*.dll addons/godot_xterm/native/bin/*.wasm addons/godot_xterm/native/bin/*.dylib - addons/godot_xterm/native/bin/*.dll html5_export: name: 'HTML5 Export' diff --git a/addons/godot_xterm/native/SConstruct b/addons/godot_xterm/native/SConstruct index 32ce1da..802e5b9 100644 --- a/addons/godot_xterm/native/SConstruct +++ b/addons/godot_xterm/native/SConstruct @@ -62,6 +62,8 @@ opts.Add(EnumVariable( allowed_values=('debug', 'release'), ignorecase=2 )) +opts.Add(BoolVariable("use_mingw", + "Use the MinGW compiler instead of MSVC - only effective on Windows", False)) opts.Add(EnumVariable("macos_arch", "Target macOS architecture", "universal", ["universal", "x86_64", "arm64"])) opts.Add(BoolVariable( @@ -255,7 +257,7 @@ env.Append(LIBS=[ env['target'], 'wasm' if env['platform'] == 'javascript' else env['macos_arch'] if ( env['macos_arch'] != 'universal' and env['platform'] == 'osx') else env['bits'], - env['LIBSUFFIX'], + '.a' if env['use_mingw'] else env['LIBSUFFIX'], )), env.File('thirdparty/libtsm/build/bin/libtsm.{}.{}.{}{}'.format( env['platform'], @@ -280,15 +282,26 @@ else: sources.append('src/node_pty/unix/pty.cc') env.Append(LIBS=['util', env.File('thirdparty/libuv/build/libuv_a.a')]) else: + #sources.append('src/node_pty/win/path_util.cc') #sources.append('src/node_pty/win/conpty.cc') - env.Append(LIBS=[ - env.File('thirdparty/libuv/build/{}/uv_a.lib'.format(env["target"].capitalize())), - 'Advapi32.lib', - 'Iphlpapi.lib', - 'user32.lib', - 'userenv.lib', - 'Ws2_32.lib', - ]) + #sources.append('src/node_pty/win/winpty.cc') + if env['use_mingw'] and not env["disable_pty"]: + env.Append(LIBS=[ + env.File('thirdparty/libuv/build/libuv.dll.a'), + '-lshlwapi' + ]) + Execute([ + Copy('bin/libuv.dll', 'thirdparty/libuv/build/libuv.dll'), + ]) + else: + env.Append(LIBS=[ + env.File('thirdparty/libuv/build/{}/uv_a.lib'.format(env["target"].capitalize())), + 'Advapi32.lib', + 'Iphlpapi.lib', + 'user32.lib', + 'userenv.lib', + 'Ws2_32.lib', + ]) if env['platform'] == 'linux': libsuffix = "a" diff --git a/addons/godot_xterm/native/docker-compose.yaml b/addons/godot_xterm/native/docker-compose.yaml index 9143453..7a9630d 100644 --- a/addons/godot_xterm/native/docker-compose.yaml +++ b/addons/godot_xterm/native/docker-compose.yaml @@ -36,7 +36,7 @@ services: - | target=$${TARGET:-release} bits=$${BITS:-'64'} - mkdir build 2>/dev/null ; + mkdir build 2>/dev/null args="-DCMAKE_BUILD_TYPE=$$target \ -DBUILD_SHARED_LIBS=OFF \ -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE" @@ -57,3 +57,57 @@ services: volumes: - .:/godot-xterm working_dir: /godot-xterm + godot-cpp-windows: + user: ${UID_GID} + build: + context: . + dockerfile: windows.Dockerfile + volumes: + - ./thirdparty/godot-cpp:/godot-cpp + working_dir: /godot-cpp + command: + - /bin/bash + - -c + - | + scons platform=windows use_mingw=yes generate_bindings=yes target=$${TARGET:-release} bits=$${BITS:-64} -j$$(nproc) + libuv-windows: + user: ${UID_GID} + build: + context: . + dockerfile: windows.Dockerfile + volumes: + - ./thirdparty/libuv:/libuv + working_dir: /libuv + command: + - /bin/bash + - -c + - | + target=$${TARGET:-release} + bits=$${BITS:-'64'} + mkdir build 2>/dev/null + args="-DCMAKE_BUILD_TYPE=$$target \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE" + if [[ $$bits -eq 32 ]]; then + args="$$args -DCMAKE_SYSTEM_PROCESSOR=i686 -DCMAKE_C_FLAGS=-m32" + args="$$args -DCMAKE_TOOLCHAIN_FILE=/mingw-w64-i686.cmake" + else + args="$$args -DCMAKE_SYSTEM_PROCESSOR=x86_64 -DCMAKE_C_FLAGS=" + args="$$args -DCMAKE_TOOLCHAIN_FILE=/mingw-w64-x86_64.cmake" + fi + pushd build + cmake .. $$args + popd + cmake --build build + libgodot-xterm-windows: + user: ${UID_GID} + build: + context: . + dockerfile: windows.Dockerfile + volumes: + - .:/godot-xterm + working_dir: /godot-xterm + command: + - /bin/bash + - -c + - scons platform=windows use_mingw=yes target=$${TARGET:-release} bits=$${BITS:-64} -j$$(nproc) diff --git a/addons/godot_xterm/native/godotxtermnative.gdnlib b/addons/godot_xterm/native/godotxtermnative.gdnlib index 3adb2f8..cb5e73b 100644 --- a/addons/godot_xterm/native/godotxtermnative.gdnlib +++ b/addons/godot_xterm/native/godotxtermnative.gdnlib @@ -18,7 +18,7 @@ X11.32="res://addons/godot_xterm/native/bin/libgodot-xterm.linux.32.so" HTML5.wasm32=[ ] OSX.64=[ ] -Windows.64=[ ] +Windows.64=[ "res://addons/godot_xterm/native/bin/libuv.dll" ] Windows.32=[ ] X11.64=[ ] X11.32=[ ] diff --git a/addons/godot_xterm/native/src/libgodotxtermnative.cpp b/addons/godot_xterm/native/src/libgodotxtermnative.cpp index b862263..d926327 100644 --- a/addons/godot_xterm/native/src/libgodotxtermnative.cpp +++ b/addons/godot_xterm/native/src/libgodotxtermnative.cpp @@ -5,11 +5,12 @@ #include "pipe.h" #if defined(__linux__) || defined(__APPLE__) #include "node_pty/unix/pty.h" -#endif +#endif // defined(__linux__) || defined(__APPLE__) #if defined(__WIN32) //#include "node_pty/win/conpty.h" -#endif -#endif +//#include "node_pty/win/winpty.h" +#endif // defined(__WIN32) +#endif // !defined(_PTY_DISABLED) extern "C" void GDN_EXPORT godot_gdnative_init(godot_gdnative_init_options *o) { godot::Godot::gdnative_init(o); @@ -31,6 +32,7 @@ extern "C" void GDN_EXPORT godot_nativescript_init(void *handle) { #endif #if defined(__WIN32) // godot::register_tool_class(); + // godot::register_tool_class(); #endif #endif } diff --git a/addons/godot_xterm/native/src/node_pty/win/path_util.cc b/addons/godot_xterm/native/src/node_pty/win/path_util.cc index 128af22..5de7770 100644 --- a/addons/godot_xterm/native/src/node_pty/win/path_util.cc +++ b/addons/godot_xterm/native/src/node_pty/win/path_util.cc @@ -2,22 +2,16 @@ * Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License) * Copyright (c) 2016, Daniel Imms (MIT License). * Copyright (c) 2018, Microsoft Corporation (MIT License). + * Copyright (c) 2022, Leroy Hopson (MIT License). */ -#include // PathCombine -#include - #include "path_util.h" +#include // PathCombine +#include namespace path_util { -const wchar_t *to_wstring(const Nan::Utf8String &str) { - const char *bytes = *str; - unsigned int sizeOfStr = MultiByteToWideChar(CP_UTF8, 0, bytes, -1, NULL, 0); - wchar_t *output = new wchar_t[sizeOfStr]; - MultiByteToWideChar(CP_UTF8, 0, bytes, -1, output, sizeOfStr); - return output; -} +const wchar_t *to_wstring(String str) { return str.unicode_str(); } bool file_exists(std::wstring filename) { DWORD attr = ::GetFileAttributesW(filename.c_str()); diff --git a/addons/godot_xterm/native/src/node_pty/win/path_util.h b/addons/godot_xterm/native/src/node_pty/win/path_util.h index db8d3cd..1224d2f 100644 --- a/addons/godot_xterm/native/src/node_pty/win/path_util.h +++ b/addons/godot_xterm/native/src/node_pty/win/path_util.h @@ -2,18 +2,22 @@ * Copyright (c) 2013-2015, Christopher Jeffrey, Peter Sunde (MIT License) * Copyright (c) 2016, Daniel Imms (MIT License). * Copyright (c) 2018, Microsoft Corporation (MIT License). + * Copyright (c) 2022, Leroy Hopson (MIT License). */ #ifndef NODE_PTY_PATH_UTIL_H_ #define NODE_PTY_PATH_UTIL_H_ -#include +#include +#include #define MAX_ENV 65536 +using namespace godot; + namespace path_util { -const wchar_t *to_wstring(const Nan::Utf8String &str); +const wchar_t *to_wstring(String str); bool file_exists(std::wstring filename); std::wstring get_shell_path(std::wstring filename); diff --git a/addons/godot_xterm/native/thirdparty/libuv b/addons/godot_xterm/native/thirdparty/libuv index f9ad802..e8b7eb6 160000 --- a/addons/godot_xterm/native/thirdparty/libuv +++ b/addons/godot_xterm/native/thirdparty/libuv @@ -1 +1 @@ -Subproject commit f9ad802fa5dd5afe6730f8e00cfdbf98f1d7a969 +Subproject commit e8b7eb6908a847ffbe6ab2eec7428e43a0aa53a2 diff --git a/addons/godot_xterm/native/windows.Dockerfile b/addons/godot_xterm/native/windows.Dockerfile new file mode 100644 index 0000000..1b365e8 --- /dev/null +++ b/addons/godot_xterm/native/windows.Dockerfile @@ -0,0 +1,6 @@ +FROM ubuntu:latest +RUN apt-get update -y +RUN apt-get install -y cmake mingw-w64 scons +RUN apt-get install -y wget && \ + wget https://gist.githubusercontent.com/peterspackman/8cf73f7f12ba270aa8192d6911972fe8/raw/9d775cdff025ab12bdffe9e9a195e306a429bb86/mingw-w64-x86_64.cmake +RUN sed 's/x86_64-w64-mingw32/i686-w64-mingw32/g' /mingw-w64-x86_64.cmake > /mingw-w64-i686.cmake