Add cross compile support on x86_64 Linux with MinGW toolchain (#340)

fixed #335
This commit is contained in:
Maurice Heumann
2025-05-30 10:23:35 +02:00
committed by GitHub
10 changed files with 97 additions and 2 deletions

View File

@@ -25,7 +25,21 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
##########################################
if(NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
if(MINGW)
# Minimum version check for MinGW compiler
set(MINGW_C_COMPILER_MIN_VERSION "14.0.0")
set(MINGW_CXX_COMPILER_MIN_VERSION "14.0.0")
if (${CMAKE_C_COMPILER_VERSION} VERSION_LESS_EQUAL ${MINGW_C_COMPILER_MIN_VERSION})
message(FATAL_ERROR "${CMAKE_C_COMPILER} version should >= ${MINGW_C_COMPILER_MIN_VERSION}")
endif()
if (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS_EQUAL ${MINGW_CXX_COMPILER_MIN_VERSION})
message(FATAL_ERROR "${CMAKE_C_COMPILER} version should >= ${MINGW_CXX_COMPILER_MIN_VERSION}")
endif()
# MinGW LTO will cause errors in compile stage, We just disable it
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
elseif(NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()

View File

@@ -0,0 +1,38 @@
# cross compile
set(CMAKE_SYSTEM_NAME Windows)
set(MINGW_C_COMPILER_NAME "x86_64-w64-mingw32-gcc")
set(MINGW_CXX_COMPILER_NAME "x86_64-w64-mingw32-g++")
set(MINGW_WINDRES_COMPILER_NAME "x86_64-w64-mingw32-windres")
find_file(MINGW_C_COMPILER ${MINGW_C_COMPILER_NAME})
find_file(MINGW_CXX_COMPILER ${MINGW_CXX_COMPILER_NAME})
find_file(MINGW_WINDRES_COMPILER ${MINGW_WINDRES_COMPILER_NAME})
if (${MINGW_C_COMPILER} STREQUAL "MINGW_C_COMPILER-NOTFOUND")
message(FATAL_ERROR "mingw-w64 compiler not found: ${MINGW_C_COMPILER_NAME}")
endif()
if (${MINGW_CXX_COMPILER} STREQUAL "MINGW_CXX_COMPILER-NOTFOUND")
message(FATAL_ERROR "mingw-w64 compiler not found: ${MINGW_CXX_COMPILER_NAME}")
endif()
if (${MINGW_WINDRES_COMPILER} STREQUAL "MINGW_WINDRES_COMPILER-NOTFOUND")
message(FATAL_ERROR "mingw-w64 compiler not found: ${MINGW_WINDRES_COMPILER_NAME}")
endif()
# this macro is needed when compile `libwindows-emulator.a`
add_compile_definitions(NTDDI_VERSION=NTDDI_WIN10_MN)
# set the compiler
set(CMAKE_C_COMPILER ${MINGW_C_COMPILER})
set(CMAKE_CXX_COMPILER ${MINGW_CXX_COMPILER})
set(CMAKE_RC_COMPILER ${MINGW_WINDRES_COMPILER})
# set the compiler search path
set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@@ -9,6 +9,9 @@ momo_add_subdirectory_and_get_targets("backends" BACKEND_TARGETS)
momo_targets_set_folder("backends" ${BACKEND_TARGETS})
if (NOT MOMO_BUILD_AS_LIBRARY)
if (MINGW)
add_link_options(-static-libstdc++ -static -lwinpthread)
endif()
add_subdirectory(analyzer)
add_subdirectory(debugger)
add_subdirectory(fuzzing-engine)

View File

@@ -11,7 +11,14 @@ target_include_directories(emulator-common INTERFACE "${CMAKE_CURRENT_LIST_DIR}"
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(emulator-common PUBLIC
Threads::Threads
zlibstatic
)
if(MINGW)
target_link_libraries(emulator-common PUBLIC
ws2_32
)
endif()

View File

@@ -2,8 +2,14 @@
#if _WIN32
#include "../utils/win.hpp"
#ifdef __MINGW64__
#include <winsock2.h>
#include <ws2tcpip.h>
#include <cstdint>
#else
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#else
#include <sys/types.h>

View File

@@ -18,6 +18,10 @@
#define WIN32_LEAN_AND_MEAN
#endif
#ifdef __MINGW64__
#include <windows.h>
#else
#include <Windows.h>
#endif
#endif

View File

@@ -8,4 +8,8 @@ list(SORT SRC_FILES)
add_executable(test-sample ${SRC_FILES})
if(MINGW)
target_link_libraries(test-sample PRIVATE ws2_32)
endif()
momo_assign_source_group(${SRC_FILES})

View File

@@ -12,9 +12,16 @@
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <intrin.h>
#ifdef __MINGW64__
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#endif
#pragma comment(lib, "ws2_32.lib")
@@ -594,6 +601,7 @@ namespace
}
}
#ifndef __MINGW64__
bool test_access_violation_exception()
{
__try
@@ -641,6 +649,7 @@ namespace
{
return test_access_violation_exception() && test_illegal_instruction_exception();
}
#endif
bool trap_flag_cleared = false;
constexpr DWORD TRAP_FLAG_MASK = 0x100;
@@ -665,7 +674,11 @@ namespace
__writeeflags(__readeflags() | TRAP_FLAG_MASK);
#ifdef __MINGW64__
asm("nop");
#else
__nop();
#endif
RemoveVectoredExceptionHandler(veh_handle);
@@ -736,7 +749,9 @@ int main(const int argc, const char* argv[])
RUN_TEST(test_threads, "Threads")
RUN_TEST(test_env, "Environment")
RUN_TEST(test_exceptions, "Exceptions")
#ifndef __MINGW64__
RUN_TEST(test_native_exceptions, "Native Exceptions")
#endif
if (!getenv("EMULATOR_ICICLE"))
{
RUN_TEST(test_interrupts, "Interrupts")

View File

@@ -1,5 +1,9 @@
#pragma once
#ifdef __MINGW64__
#include <unistd.h>
#endif
#include <cstdlib>
#include <gtest/gtest.h>
#include <windows_emulator.hpp>