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.
This commit is contained in:
Scott Mansell 2022-04-28 17:18:07 +12:00 committed by Admiral H. Curtiss
parent 89fda54820
commit 876f6651b4
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 29 additions and 10 deletions

View File

@ -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(

View File

@ -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_FILE_DIR:pch>)
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$<TARGET_FILE_DIR:pch>)
# 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$<TARGET_FILE_DIR:build_pch>/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 $<TARGET_FILE_DIR:build_pch>/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 $<TARGET_FILE_DIR:build_pch>/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)