diff --git a/cmake/compiler-env.cmake b/cmake/compiler-env.cmake index f8d770e5..1075875e 100644 --- a/cmake/compiler-env.cmake +++ b/cmake/compiler-env.cmake @@ -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() diff --git a/cmake/toolchain/mingw-w64.cmake b/cmake/toolchain/mingw-w64.cmake new file mode 100644 index 00000000..58f07813 --- /dev/null +++ b/cmake/toolchain/mingw-w64.cmake @@ -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) diff --git a/deps/googletest b/deps/googletest index 09ffd001..7da55820 160000 --- a/deps/googletest +++ b/deps/googletest @@ -1 +1 @@ -Subproject commit 09ffd0015395354774c059a17d9f5bee36177ff9 +Subproject commit 7da55820cc32dedd6c1b048f2d4e13fdde5e8237 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 300b763d..6c71b182 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index dfc64b78..036793eb 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -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() diff --git a/src/common/network/address.hpp b/src/common/network/address.hpp index 363b91bc..6b332699 100644 --- a/src/common/network/address.hpp +++ b/src/common/network/address.hpp @@ -2,8 +2,14 @@ #if _WIN32 #include "../utils/win.hpp" +#ifdef __MINGW64__ +#include +#include +#include +#else #include #include +#endif #else #include diff --git a/src/common/utils/win.hpp b/src/common/utils/win.hpp index 89dd09c9..0b917460 100644 --- a/src/common/utils/win.hpp +++ b/src/common/utils/win.hpp @@ -18,6 +18,10 @@ #define WIN32_LEAN_AND_MEAN #endif +#ifdef __MINGW64__ +#include +#else #include +#endif #endif diff --git a/src/samples/test-sample/CMakeLists.txt b/src/samples/test-sample/CMakeLists.txt index 6a131eff..918b772c 100644 --- a/src/samples/test-sample/CMakeLists.txt +++ b/src/samples/test-sample/CMakeLists.txt @@ -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}) diff --git a/src/samples/test-sample/test.cpp b/src/samples/test-sample/test.cpp index 67634c58..a3ec47ca 100644 --- a/src/samples/test-sample/test.cpp +++ b/src/samples/test-sample/test.cpp @@ -12,9 +12,16 @@ #define NOMINMAX #define WIN32_LEAN_AND_MEAN #include + +#ifdef __MINGW64__ +#include +#include +#include +#else #include #include #include +#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") diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index 8aa201ab..d7d2cdd2 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -1,5 +1,9 @@ #pragma once +#ifdef __MINGW64__ +#include +#endif + #include #include #include