mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-01 03:29:18 -05:00
fa7b041eca
Since commit729d997f10(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 commita9f4f58f0c(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 commita55df20499(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
31 lines
830 B
CMake
31 lines
830 B
CMake
cmake_minimum_required(VERSION 3.15)
|
|
project(PchReuseFrom C)
|
|
|
|
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>
|
|
<string.h>
|
|
)
|
|
target_include_directories(empty PUBLIC include)
|
|
|
|
target_precompile_headers(foo REUSE_FROM empty)
|
|
|
|
# should not cause problems if configured multiple times
|
|
target_precompile_headers(foo REUSE_FROM empty)
|
|
|
|
add_executable(foobar foobar.c)
|
|
target_link_libraries(foobar foo )
|
|
set_target_properties(foobar PROPERTIES PRECOMPILE_HEADERS_REUSE_FROM foo)
|
|
|
|
enable_testing()
|
|
add_test(NAME foobar COMMAND foobar)
|