From dcf3ca0f8995324471fc3359ee17d7ea89afd8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 24 Apr 2021 23:12:30 +0200 Subject: [PATCH 1/8] CMake: Force gtest to link CRT dynamically to avoid runtime mismatches Required to fix unit test builds for Windows+MSVC+CMake. For more information, see: https://github.com/google/googletest/blob/23ef29555ef4789f555f1ba8c51b4c52975f0907/googletest/README.md#visual-studio-dynamic-vs-static-runtimes --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06137c57e0..727d32ccef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -844,6 +844,8 @@ include_directories("${PROJECT_BINARY_DIR}/Source/Core") # if(ENABLE_TESTS) message(STATUS "Using static gtest from Externals") + # Force gtest to link the C runtime dynamically on Windows in order to avoid runtime mismatches. + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) add_subdirectory(Externals/gtest EXCLUDE_FROM_ALL) else() message(STATUS "Unit tests are disabled") From c69747c7fb25f380a12267d0b5f9123fdf65be53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 24 Apr 2021 23:23:29 +0200 Subject: [PATCH 2/8] CMake: Fix CMAKE_RUNTIME_OUTPUT_DIRECTORY being ignored in UnitTests CMAKE_RUNTIME_OUTPUT_DIRECTORY_ overrode CMAKE_RUNTIME_OUTPUT_DIRECTORY. It's just unnecessary and it broke UnitTests's custom output directory --- CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 727d32ccef..7c6efd27c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,11 +124,6 @@ if (WIN32) elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") string(APPEND CMAKE_RUNTIME_OUTPUT_DIRECTORY /ARM64) endif() - - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) endif() # setup CCache From f6b8d4758ee3df8fbe94c23a9b6e01fe9e1d06d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 24 Apr 2021 23:59:11 +0200 Subject: [PATCH 3/8] CMake: Copy license.txt to output folder to match existing Win builds --- Source/Core/DolphinQt/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 41b24a9c26..af1a6257a5 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -370,6 +370,11 @@ if(WIN32) COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/Data/Sys" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Sys" ) + # Copy license.txt + add_custom_command(TARGET dolphin-emu POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/license.txt" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/license.txt" + ) + # Copy qt.conf add_custom_command(TARGET dolphin-emu POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.win" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/qt.conf" From e71aef6768459a656566346a35af67207e60ec42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 25 Apr 2021 00:32:23 +0200 Subject: [PATCH 4/8] CMake: Ask windeployqt not to copy DLLs that are unnecessary * no-system-d3d-compiler: d3dcompiler_47.dll * no-angle, no-opengl-sw: libEGL.dll, libGLESv2.dll --- Source/Core/DolphinQt/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index af1a6257a5..d9752fc519 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -406,6 +406,9 @@ if(WIN32) $,--debug,--release> --no-translations --no-compiler-runtime + --no-system-d3d-compiler + --no-angle + --no-opengl-sw "$" ) endif() From ae67a9382bd35d248610774ff6e8f38db7e15f9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 25 Apr 2021 01:15:14 +0200 Subject: [PATCH 5/8] CMake: Put the *.mo files directly in the correct output dir Avoids the need to copy the *.mo files manually *and* more importantly this ensures that the mo files are always recreated if the build output directory is cleared. --- Source/Core/DolphinQt/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index d9752fc519..13c9a3d79a 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -431,7 +431,11 @@ if(GETTEXT_MSGFMT_EXECUTABLE) foreach(po ${LINGUAS}) get_filename_component(lang ${po} NAME_WE) - set(mo_dir ${CMAKE_CURRENT_BINARY_DIR}/${lang}) + if(WIN32) + set(mo_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Languages/${lang}) + else() + set(mo_dir ${CMAKE_CURRENT_BINARY_DIR}/${lang}) + endif() set(mo ${mo_dir}/dolphin-emu.mo) target_sources(dolphin-emu PRIVATE ${mo}) @@ -447,7 +451,6 @@ if(GETTEXT_MSGFMT_EXECUTABLE) add_custom_command(OUTPUT ${mo} COMMAND ${CMAKE_COMMAND} -E make_directory ${mo_dir} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${mo} ${po} - COMMAND ${CMAKE_COMMAND} -E copy ${mo} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Languages/${lang}/dolphin-emu.mo DEPENDS ${po} ) else() From 20d00dfc79c5eb10b5a7578b29a712a08bf8f44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 25 Apr 2021 19:00:32 +0200 Subject: [PATCH 6/8] CMake: Add missing MSVC optimization flags to match VS project props --- CMakeLists.txt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c6efd27c7..45193e813e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,6 +235,12 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC") check_and_add_flag(EXCEPTIONS /EHsc) dolphin_compile_definitions(_DEBUG DEBUG_ONLY) + # Enable function-level linking + add_compile_options(/Gy) + # Generate intrinsic functions + add_compile_options(/Oi) + # Disable buffer security check + add_compile_options(/GS-) # Enforce C++ standard conforming conversion rules to catch possible bugs add_compile_options(/permissive-) # Remove unreferenced inline functions/data to reduce link time and catch bugs @@ -254,6 +260,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC") ) string(APPEND CMAKE_EXE_LINKER_FLAGS " /NXCOMPAT") + # Generate debug data + string(APPEND CMAKE_EXE_LINKER_FLAGS " /DEBUG") + # Eliminate dead code and data + string(APPEND CMAKE_EXE_LINKER_FLAGS " /OPT:REF /OPT:ICF") else() add_definitions(-D_DEFAULT_SOURCE) @@ -352,6 +362,11 @@ if(NOT CMAKE_BUILD_TYPE) "Build type (Release/Debug/RelWithDebInfo/MinSizeRel)" FORCE) endif() +if(CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo" AND CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options(/GL) + string(APPEND CMAKE_EXE_LINKER_FLAGS " /LTCG") +endif() + if(ENABLE_GPROF) check_and_add_flag(HAVE_PG -pg) if(NOT FLAG_C_HAVE_PG) From d0484a9ea9331f2cedb080f06944d737343414f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sun, 25 Apr 2021 19:41:07 +0200 Subject: [PATCH 7/8] CMake: Fix MSVC flags for Release/RelWithDebInfo See https://gitlab.kitware.com/cmake/cmake/-/issues/20812 Manually redefine MSVC flags to match Visual Studio defaults and ensure that Release builds generate debug info. --- CMake/FlagsOverride.cmake | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/CMake/FlagsOverride.cmake b/CMake/FlagsOverride.cmake index 39c55aa62a..d52cf4b153 100644 --- a/CMake/FlagsOverride.cmake +++ b/CMake/FlagsOverride.cmake @@ -1,7 +1,11 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - foreach(f CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if("${${f}}" MATCHES "/Zi") - string(REGEX REPLACE "/Zi" "/Z7" "${f}" "${${f}}") - endif() - endforeach() -endif() \ No newline at end of file + # The default MSVC flags for Release and RelWithDebInfo are poorly chosen + # (see issue https://gitlab.kitware.com/cmake/cmake/-/issues/20812) + # By default, inlining is disabled for RelWithDebInfo. + # Manually redefine MSVC flags to match Visual Studio defaults + # and ensure that Release builds generate debug info. + foreach(f CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELEASE) + # optimize, define NDEBUG, generate debug info + set(${f} "/O2 /DNDEBUG /Z7") + endforeach() +endif() From ae9ac510e2dbed6d7adec40dff33d82bb0f1ff3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Mon, 26 Apr 2021 01:18:17 +0200 Subject: [PATCH 8/8] CMake: Do not enable LTO by default for MSVC LTO is supposed to be enabled by default for VS Release builds according to the VS prop files but a build log from JMC reveals that /GL and /LTCG are not actually passed to cl.exe/link.exe for some reason... LTO also leads to *extremely* and unacceptably slow build times when using link.exe, so let's disable it by default to actually match the project files. --- CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45193e813e..e1565844e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -332,10 +332,15 @@ if(CMAKE_SYSTEM_NAME MATCHES "Darwin") endif() if(ENABLE_LTO) - check_and_add_flag(LTO -flto) - if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) - set(CMAKE_AR gcc-ar) - set(CMAKE_RANLIB gcc-ranlib) + if(CMAKE_C_COMPILER_ID MATCHES "MSVC") + add_compile_options(/GL) + string(APPEND CMAKE_EXE_LINKER_FLAGS " /LTCG") + else() + check_and_add_flag(LTO -flto) + if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) + set(CMAKE_AR gcc-ar) + set(CMAKE_RANLIB gcc-ranlib) + endif() endif() endif() @@ -362,11 +367,6 @@ if(NOT CMAKE_BUILD_TYPE) "Build type (Release/Debug/RelWithDebInfo/MinSizeRel)" FORCE) endif() -if(CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo" AND CMAKE_C_COMPILER_ID MATCHES "MSVC") - add_compile_options(/GL) - string(APPEND CMAKE_EXE_LINKER_FLAGS " /LTCG") -endif() - if(ENABLE_GPROF) check_and_add_flag(HAVE_PG -pg) if(NOT FLAG_C_HAVE_PG)