From 876f6651b45e7c4e014571ce1c4d53f70ac68813 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Thu, 28 Apr 2022 17:18:07 +1200 Subject: [PATCH] cmake: fix PCH to work with msvc/ninja Ninja puts way more effort into compiling targets in parallel, and ignores dependenceis until link time. So we need to jump though hoops to force ninja to compile pch.cpp before any targets which depend on the PCH. --- Source/Core/Common/CMakeLists.txt | 2 +- Source/PCH/CMakeLists.txt | 37 +++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 984a143ce9..287680aeea 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -312,7 +312,7 @@ endif() if(MSVC) # Add precompiled header # it will propergate down to everything that depends on common - target_link_libraries(common PUBLIC pch) + target_link_libraries(common PUBLIC use_pch) # We need to disable PCH for this one file, because it's C and our PCH is C++ set_source_files_properties( diff --git a/Source/PCH/CMakeLists.txt b/Source/PCH/CMakeLists.txt index aeddfa52f5..2ee6adaa12 100644 --- a/Source/PCH/CMakeLists.txt +++ b/Source/PCH/CMakeLists.txt @@ -2,23 +2,42 @@ # Instead of having one PCH per module, dolphin has one PCH shared between all modules. # So we need to implement PCH manually, rather than using the PCH support built into cmake -add_library(pch pch.h pch.cpp) +add_library(build_pch pch.h pch.cpp) + +# fmt/format.h is included in the PCH +target_link_libraries(build_pch PUBLIC fmt::fmt) # pch.cpp should be compiled with the /Yc command, which creates the precompiled header -target_compile_options(pch PRIVATE /Yc"pch.h" /Fo$) +target_compile_options(build_pch PRIVATE /Ycpch.h) # /Fp sets the location of the PCH. By forcing it to a fixed location, all modules -# will share this one PCH -target_compile_options(pch PUBLIC /Fp$) +# will share this one PCH. We give it a fixed name so we can depend on it later +target_compile_options(build_pch PUBLIC /Fp$/dolphin.pch ) # Sharing a PCH breaks pdb files. So we use the /Z7 option to inline the pdb into # the binary. That also requires us to disable minimal rebuilds. -target_compile_options(pch PUBLIC /Z7 /Gm-) +target_compile_options(build_pch PUBLIC /Z7 /Gm-) -# targets which include pch need these compile options +# To get this working with ninja, we need to tell it that compiling pch.cpp generates an extra output +set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/pch.cpp PROPERTIES + OBJECT_OUTPUTS $/dolphin.pch +) + +# and then create a custom target that depends on the pch output +# so that ninja won't start building anything that depends on this +# target before the pch is built +add_custom_target(force_build_pch + DEPENDS $/dolphin.pch +) + +# linking against this interface libary will cause targets to enable PCH +add_library(use_pch INTERFACE) +target_link_libraries(use_pch INTERFACE build_pch) + +# targets which use the pch need these compile options # /Yu - Use precompiled header named "pch.h" # /FI - Force include "pch.h" at top of every source file -target_compile_options(pch INTERFACE /Yu"pch.h" /FI"pch.h") +target_compile_options(use_pch INTERFACE /Yupch.h /FIpch.h) -# fmt/format.h is included in the PCH -target_link_libraries(pch PUBLIC fmt::fmt) +# For ninja, we need to depend on force_build_pch +add_dependencies(use_pch force_build_pch)