diff --git a/.github/workflows/windows-test.yml b/.github/workflows/windows-test.yml index c7af6e0ee..5af13663b 100644 --- a/.github/workflows/windows-test.yml +++ b/.github/workflows/windows-test.yml @@ -65,6 +65,49 @@ jobs: env: METACALL_BUILD_OPTIONS: ${{ matrix.options.build }} tests + windows-mingw-test: + name: Windows MinGW Test + runs-on: windows-latest + + steps: + - name: Check out the repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + install: > + base-devel + mingw-w64-x86_64-gcc + mingw-w64-x86_64-cmake + mingw-w64-x86_64-make + cache: false + - name: Wait for MSYS2 to complete setup + run: sleep 60 + - name: Add MSYS2 to PATH + run: | + echo "C:\msys64\mingw64\bin" >> $Env:GITHUB_PATH + echo "C:\msys64\usr\bin" >> $Env:GITHUB_PATH + - name: Create build directory + run: mkdir build + + - name: Configure with CMake + working-directory: ./build + run: | + cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug -DOPTION_FORK_SAFE=OFF -DOPTION_BUILD_PLUGINS_BACKTRACE=OFF .. + - name: Build with CMake + working-directory: ./build + run: cmake --build . + + - name: Run CTest + working-directory: ./build + run: | + ctest -j$(getconf _NPROCESSORS_ONLN) --timeout 5400 --output-on-failure -C Debug + shell: bash + windows-distributable: name: Windows Distributable Dispatch needs: windows-test diff --git a/source/detours/funchook_detour/scripts/download.bat.in b/source/detours/funchook_detour/scripts/download.bat.in index 8f1fd3842..a2702001b 100755 --- a/source/detours/funchook_detour/scripts/download.bat.in +++ b/source/detours/funchook_detour/scripts/download.bat.in @@ -1,11 +1,11 @@ @echo on rem Download repository if it does not exist -if not exist @FUNCHOOK_SOURCE_DIR@/.git ( - if exist @FUNCHOOK_SOURCE_DIR@ ( +if not exist "@FUNCHOOK_SOURCE_DIR@/.git" ( + if exist "@FUNCHOOK_SOURCE_DIR@" ( rmdir /S /Q "@FUNCHOOK_SOURCE_DIR@" ) - "@GIT_EXECUTABLE@" clone --single-branch --branch v@FUNCHOOK_VERSION@ --recursive https://github.com/kubo/funchook.git @FUNCHOOK_SOURCE_DIR@ + "@GIT_EXECUTABLE@" clone --single-branch --branch v@FUNCHOOK_VERSION@ --recursive https://github.com/kubo/funchook.git "@FUNCHOOK_SOURCE_DIR@" ) rem Write empty CMake file to avoid cmake warnings diff --git a/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h b/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h index 670ece371..63f5a4cbd 100644 --- a/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h +++ b/source/dynlink/include/dynlink/dynlink_impl_symbol_win32.h @@ -32,22 +32,49 @@ extern "C" { #endif /* -- Definitions -- */ +#if defined(__MING32__) || defined(__MINGW64__) + #define DYNLINK_SYMBOL_PREFIX \ + dynlink_symbol_ -#define DYNLINK_SYMBOL_PREFIX + /* -- Macros -- */ -/* -- Macros -- */ + #define DYNLINK_SYMBOL_EXPORT(name) \ + DYNLINK_NO_EXPORT struct dynlink_symbol_addr_win32_type DYNLINK_SYMBOL_NAME(name) = { \ + (dynlink_symbol_addr_win32_impl)&name \ + } +#else + #define DYNLINK_SYMBOL_PREFIX -#define DYNLINK_SYMBOL_EXPORT(name) \ - DYNLINK_NO_EXPORT struct \ - { \ - char name; \ - } PREPROCESSOR_CONCAT(dynlink_no_export_, name) + /* -- Macros -- */ -#define DYNLINK_SYMBOL_GET(name) name + #define DYNLINK_SYMBOL_EXPORT(name) \ + DYNLINK_NO_EXPORT struct \ + { \ + char name; \ + } PREPROCESSOR_CONCAT(dynlink_no_export_, name) +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) + #define DYNLINK_SYMBOL_GET(name) \ + (((dynlink_symbol_addr_win32)(name))->symbol) +#else + #define DYNLINK_SYMBOL_GET(name) name +#endif /* -- Type definitions -- */ +#if defined(__MINGW32__) || defined(__MINGW64__) +/* MinGW-compatible definition */ +typedef void (*dynlink_symbol_addr_win32_impl)(void); + +typedef struct dynlink_symbol_addr_win32_type +{ + dynlink_symbol_addr_win32_impl symbol; +} * dynlink_symbol_addr_win32; + +#else typedef void (*dynlink_symbol_addr_win32)(void); +#endif typedef dynlink_symbol_addr_win32 dynlink_symbol_addr; diff --git a/source/dynlink/source/dynlink_impl_win32.c b/source/dynlink/source/dynlink_impl_win32.c index 8ea74bb24..6afb99a13 100644 --- a/source/dynlink/source/dynlink_impl_win32.c +++ b/source/dynlink/source/dynlink_impl_win32.c @@ -41,11 +41,16 @@ const char *dynlink_impl_interface_extension_win32(void) void dynlink_impl_interface_get_name_win32(dynlink_name name, dynlink_name_impl name_impl, size_t size) { +#if defined(__MINGW32__) || defined(__MINGW64__) + strncpy(name_impl, "lib", size); + strncat(name_impl, name, size - strlen(name_impl) - 1); +#else strncpy(name_impl, name, size); +#endif - strncat(name_impl, ".", size - 1); + strncat(name_impl, ".", size - strlen(name_impl) - 1); - strncat(name_impl, dynlink_impl_extension(), size - 1); + strncat(name_impl, dynlink_impl_extension(), size - strlen(name_impl) - 1); } dynlink_impl dynlink_impl_interface_load_win32(dynlink handle) @@ -76,8 +81,13 @@ int dynlink_impl_interface_symbol_win32(dynlink handle, dynlink_impl impl, dynli (void)handle; +#if defined(__MINGW32__) || defined(__MINGW64__) + // For MinGW, set the symbol member of the struct + (*addr)->symbol = (dynlink_symbol_addr_win32_impl)proc_addr; +#else + // For MSVC or other compilers, cast directly *addr = (dynlink_symbol_addr)proc_addr; - +#endif return (*addr == NULL); }