diff --git a/CMakeLists.txt b/CMakeLists.txt index 39062e3fbe6..fba6b9afa92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,8 +48,8 @@ if(MINGW) include(cmake/widl.cmake) endif() -# Find/Add build dependencies and stubs shared by all projects -if((WIN32 OR "${CMAKE_SYSTEM}" MATCHES "Windows") AND ${CMAKE_SIZEOF_VOID_P} EQUAL 4) +# Find/Add build dependencies and stubs shared by all projects. +if(WIN32 OR "${CMAKE_SYSTEM}" MATCHES "Windows") include(cmake/miles.cmake) include(cmake/bink.cmake) include(cmake/dx8.cmake) diff --git a/CMakePresets.json b/CMakePresets.json index 4274c6357d2..9dec124f059 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -191,6 +191,17 @@ "cacheVariables": { "RTS_BUILD_OPTION_PROFILE": "ON" } + }, + { + "name": "mingw-w64-x86_64", + "displayName": "MinGW-w64 64-bit (x86_64) Release", + "generator": "Unix Makefiles", + "binaryDir": "${sourceDir}/build/${presetName}", + "toolchainFile": "${sourceDir}/cmake/toolchains/mingw-w64-x86_64.cmake", + "cacheVariables": { + "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", + "CMAKE_BUILD_TYPE": "Release" + } } ], "buildPresets": [ diff --git a/cmake/dx8.cmake b/cmake/dx8.cmake index dd08f56119a..392b413cf6c 100644 --- a/cmake/dx8.cmake +++ b/cmake/dx8.cmake @@ -4,4 +4,47 @@ FetchContent_Declare( GIT_TAG 7bddff8c01f5fb931c3cb73d4aa8e66d303d97bc ) -FetchContent_MakeAvailable(dx8) +# Populate only: the fetched repo's CMakeLists.txt has no architecture condition, +# so d3d8lib is defined here, where it can diverge by CMAKE_SIZEOF_VOID_P. +FetchContent_GetProperties(dx8) +if(NOT dx8_POPULATED) + FetchContent_Populate(dx8) +endif() + +add_library(d3d8lib INTERFACE) + +# MinGW-w64 x86_64 ships no libd3d8.a and no libd3dx8, so on x64 this target +# carries headers and defines only and cannot link. See issue #473. +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_link_libraries(d3d8lib INTERFACE d3d8 dinput8 dxguid) +else() + message(STATUS "DX8: x64 build — headers only, no D3D8 link libraries available") +endif() + +# MSVC-specific configuration +if(MSVC) + # Use bundled MSVC-compiled .lib files + target_link_libraries(d3d8lib INTERFACE d3dx8) + target_link_directories(d3d8lib BEFORE INTERFACE ${dx8_SOURCE_DIR}) + target_link_options(d3d8lib INTERFACE /NODEFAULTLIB:libci.lib) + + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "12.0.8804") + # Modern MSVC (VS 2013+) has complete DirectX headers in Windows SDK + target_link_libraries(d3d8lib INTERFACE legacy_stdio_definitions) + target_link_options(d3d8lib INTERFACE /SAFESEH:NO) + else() + # VC6 and older MSVC need extra headers - their DirectX SDK is missing newer definitions + target_include_directories(d3d8lib INTERFACE ${dx8_SOURCE_DIR}/extra) + endif() +endif() + +# MinGW-specific configuration +if(MINGW) + # i686 ships libd3d8.a and libd3dx8d.a; x86_64 ships neither. + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_link_libraries(d3d8lib INTERFACE d3dx8d) + endif() +endif() + +target_compile_definitions(d3d8lib INTERFACE -DBUILD_WITH_D3D8) +target_include_directories(d3d8lib INTERFACE ${dx8_SOURCE_DIR}) diff --git a/cmake/mingw.cmake b/cmake/mingw.cmake index c0953430552..ce4ce6b979a 100644 --- a/cmake/mingw.cmake +++ b/cmake/mingw.cmake @@ -9,7 +9,8 @@ if(MINGW) set(IS_MINGW32 TRUE) message(STATUS "MinGW-w64 32-bit (i686) detected") else() - message(FATAL_ERROR "MinGW-w64 64-bit (x86_64) detected, but this project only supports 32-bit builds. Use the i686-w64-mingw32 toolchain.") + set(IS_MINGW64 TRUE) + message(STATUS "MinGW-w64 64-bit (x86_64) detected — experimental, see issue #473") endif() # Windows subsystem @@ -53,7 +54,8 @@ if(MINGW) ) endif() - # Required Windows libraries for DX8 + COM + # Required Windows libraries for DX8 + COM. d3d8 is gated to 32-bit because + # link_libraries() is directory-scoped and would also hit the Miles/Bink stubs. link_libraries( uuid # COM GUIDs ole32 # COM runtime @@ -63,7 +65,7 @@ if(MINGW) comctl32 # Common controls winmm # Multimedia (timeGetTime, etc.) vfw32 # Video for Windows (AVIFile functions) - d3d8 # Direct3D 8 + $<$:d3d8> # Direct3D 8 — 32-bit only dinput8 # DirectInput 8 dsound # DirectSound imm32 # Input Method Manager (IME) @@ -78,8 +80,9 @@ if(MINGW) # MinGW-w64 only provides libd3dx8d.a (debug library), not libd3dx8.a # The min-dx8-sdk (dx8.cmake) handles this correctly via d3d8lib interface target, # but for compatibility with direct library references in main executables, - # we create an alias so that linking to d3dx8 automatically uses d3dx8d - if(NOT TARGET d3dx8) + # we create an alias so that linking to d3dx8 automatically uses d3dx8d. + # 32-bit only: x86_64 MinGW-w64 ships neither libd3dx8.a nor libd3dx8d.a. + if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT TARGET d3dx8) add_library(d3dx8 INTERFACE IMPORTED GLOBAL) set_target_properties(d3dx8 PROPERTIES INTERFACE_LINK_LIBRARIES "d3dx8d" diff --git a/cmake/toolchains/mingw-w64-x86_64.cmake b/cmake/toolchains/mingw-w64-x86_64.cmake new file mode 100644 index 00000000000..8e0f993c906 --- /dev/null +++ b/cmake/toolchains/mingw-w64-x86_64.cmake @@ -0,0 +1,32 @@ +# MinGW-w64 64-bit (x86_64) Toolchain File +# Use with: cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/mingw-w64-x86_64.cmake + +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +# Specify the cross compiler +set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) +set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) +set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) +set(CMAKE_AR x86_64-w64-mingw32-ar) +set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) +set(CMAKE_DLLTOOL x86_64-w64-mingw32-dlltool) + +# Target environment +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) + +# Adjust the default behavior of the FIND_XXX() commands: +# search programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# search headers and libraries in the target environment +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Force 64-bit pointer size +set(CMAKE_SIZEOF_VOID_P 8) + +# Disable MFC-dependent tools (not compatible with MinGW-w64) +set(RTS_BUILD_CORE_TOOLS OFF CACHE BOOL "Disable MFC-dependent core tools for MinGW" FORCE) +set(RTS_BUILD_GENERALS_TOOLS OFF CACHE BOOL "Disable MFC-dependent Generals tools for MinGW" FORCE) +set(RTS_BUILD_ZEROHOUR_TOOLS OFF CACHE BOOL "Disable MFC-dependent Zero Hour tools for MinGW" FORCE)