diff options
author | Brad King <brad.king@kitware.com> | 2020-05-28 21:29:31 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-05-29 09:52:03 (GMT) |
commit | fa7b041eca021cecfd883cc5796150dae5ad4c5f (patch) | |
tree | 680712109524c20481337726521f49a823409fac /Tests | |
parent | a9f4f58f0c3837549c41479a177c864d3cfcf760 (diff) | |
download | CMake-fa7b041eca021cecfd883cc5796150dae5ad4c5f.zip CMake-fa7b041eca021cecfd883cc5796150dae5ad4c5f.tar.gz CMake-fa7b041eca021cecfd883cc5796150dae5ad4c5f.tar.bz2 |
PCH: Fix logic error that incorrectly clears sources during VS generation
Since commit 729d997f10 (Precompile Headers: Add REUSE_FROM signature,
2019-08-30, v3.16.0-rc1~101^2), `GetPchFileObject` handles the case that
it is called first for another target's `REUSE_FROM` by calling
`AddSource` to make sure `GetObjectName` can produce the correct object
name. However, `AddSource` causes `ClearSourcesCache` to be called,
which since commit a9f4f58f0c (cmGeneratorTarget: Clear AllConfigSources
in ClearSourcesCache, 2020-05-15, v3.16.7~2^2) now correctly erases the
`AllConfigSources` structure. This is okay during `AddPchDependencies`,
but there is another code path in which it is problematic.
When the Visual Studio generator's `WriteAllSources` method is looping
over the sources, the `cmake_pch.cxx` source is encountered first. This
causes `OutputSourceSpecificFlags` to call `GetPchCreateCompileOptions`,
which calls `GetPchFile`, which under MSVC with `CMAKE_LINK_PCH` calls
`GetPchFileObject`. That leads to `ClearSourcesCache` erasing the
structure over which `WriteAllSources` is iterating!
This bug is caught by our `RunCMake.PrecompileHeaders` test when run
with the VS generator as of the commit that exposed it by fixing
`ClearSourcesCache`. However, that change was backported to the CMake
3.16 series after testing only with later versions versions that contain
commit a55df20499 (Multi-Ninja: Add precompile headers support,
2020-01-10, v3.17.0-rc1~136^2). By adding proper multi-config support
for PCH, that commit taught `cmLocalGenerator::AddPchDependencies` to
call `GetPchFile` with the real set of configurations instead of just
the empty string. This allows the `GetPchFile` cache of PCH sources to
be populated up front so that the later calls to it in the
`WriteAllSources` loop as described above do not actually call
`GetPchFileObject` or `ClearSourcesCache`. That hid the problem.
Fix this by re-ordering calls to `AddPchDependencies` to handle
`REUSE_FROM` targets only after the targets whose PCH they re-use.
Remove the now-unnecessary call to `AddSource` from `GetPchFileObject`
so that `ClearSourcesCache` is never called during `WriteAllSources`.
Update the PchReuseFrom test case to cover an ordering of targets that
causes generators to encounter a `REUSE_FROM` target before the target
whose PCH it re-uses.
Fixes: #20770
Diffstat (limited to 'Tests')
-rw-r--r-- | Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake index 03a97ed..f8fba44 100644 --- a/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake +++ b/Tests/RunCMake/PrecompileHeaders/PchReuseFrom.cmake @@ -5,6 +5,11 @@ if(CMAKE_C_COMPILE_OPTIONS_USE_PCH) add_definitions(-DHAVE_PCH_SUPPORT) endif() +# Add this before the target from which we will reuse the PCH +# to test that generators can handle reversed ordering. +add_library(foo foo.c) +target_include_directories(foo PUBLIC include) + add_library(empty empty.c) target_precompile_headers(empty PRIVATE <stdio.h> @@ -12,8 +17,6 @@ target_precompile_headers(empty PRIVATE ) target_include_directories(empty PUBLIC include) -add_library(foo foo.c) -target_include_directories(foo PUBLIC include) target_precompile_headers(foo REUSE_FROM empty) # should not cause problems if configured multiple times |