mirror of
https://github.com/reactos/CMake.git
synced 2024-11-24 12:09:48 +00:00
Merge topic 'precompile-headers'
8da78d4efe
Precompile headers: Update documentation5772930164
Precompile headers: Add unit tests519606704e
Precompile headers: Add support for Visual Studio generators28be170fbc
Precompile headers: Add support for Xcode generatorb8626261e9
Precompile headers: Add methods to generate PCH sources375d01c680
PCH: add example/test9b6797e71d
PCH: add target_precompile_headers command0467a2f91b
PCH: add PRECOMPILE_HEADERS to special properties Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Daniel Pfeifer <daniel@pfeifer-mail.de> Acked-by: Ivan171 <heavenandhell171@gmail.com> Acked-by: Stanislav Ershov <digital.stream.of.mind@gmail.com> Acked-by: Steve Mokris <smokris@softpixel.com> Acked-by: Evgeniy Dushistov <dushistov@mail.ru> Acked-by: Danila Malyutin <flashmozzg@gmail.com> Acked-by: Viktor Kirilov <vik.kirilov@gmail.com> Acked-by: Lucas Zhao <zhaopf6@163.com> Merge-request: !3553
This commit is contained in:
commit
fa36e2151d
56
Help/command/target_precompile_headers.rst
Normal file
56
Help/command/target_precompile_headers.rst
Normal file
@ -0,0 +1,56 @@
|
||||
target_precompile_headers
|
||||
-------------------------
|
||||
|
||||
Add a list of header files to precompile.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_precompile_headers(<target>
|
||||
<INTERFACE|PUBLIC|PRIVATE> [header1...]
|
||||
[<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
|
||||
|
||||
Adds header files to :prop_tgt:`PRECOMPILE_HEADERS` or
|
||||
:prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` target properties.
|
||||
|
||||
Precompiling header files can speed up compilation by creating a partially
|
||||
processed version of some header files, and then using that version during
|
||||
compilations rather than repeatedly parsing the original headers.
|
||||
|
||||
The named ``<target>`` must have been created by a command such as
|
||||
:command:`add_executable` or :command:`add_library` and must not be an
|
||||
:ref:`ALIAS target <Alias Targets>`.
|
||||
|
||||
The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
|
||||
specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
|
||||
items will populate the :prop_tgt:`PRECOMPILE_HEADERS` property of
|
||||
``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
|
||||
:prop_tgt:`INTERFACE_PRECOMPILE_HEADERS` property of ``<target>``.
|
||||
(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
|
||||
Repeated calls for the same ``<target>`` append items in the order called.
|
||||
|
||||
Arguments to ``target_precompile_headers`` may use "generator expressions"
|
||||
with the syntax ``$<...>``.
|
||||
See the :manual:`cmake-generator-expressions(7)` manual for available
|
||||
expressions. See the :manual:`cmake-compile-features(7)` manual for
|
||||
information on compile features and a list of supported compilers.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_precompile_headers(<target>
|
||||
PUBLIC
|
||||
"project_header.h"
|
||||
PRIVATE
|
||||
<unordered_map>
|
||||
)
|
||||
|
||||
Header files will be double quoted if they are not specified with double
|
||||
quotes or angle brackets.
|
||||
|
||||
See Also
|
||||
^^^^^^^^
|
||||
|
||||
For disabling precompile headers for specific targets there is the
|
||||
property :prop_tgt:`DISABLE_PRECOMPILE_HEADERS`.
|
||||
|
||||
For skipping certain source files there is the source file property
|
||||
:prop_sf:`SKIP_PRECOMPILE_HEADERS`.
|
@ -112,6 +112,7 @@ These commands are available only in CMake projects.
|
||||
/command/target_link_directories
|
||||
/command/target_link_libraries
|
||||
/command/target_link_options
|
||||
/command/target_precompile_headers
|
||||
/command/target_sources
|
||||
/command/try_compile
|
||||
/command/try_run
|
||||
|
@ -181,6 +181,7 @@ Properties on Targets
|
||||
/prop_tgt/DEFINE_SYMBOL
|
||||
/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
|
||||
/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES
|
||||
/prop_tgt/DISABLE_PRECOMPILE_HEADERS
|
||||
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
|
||||
/prop_tgt/EchoString
|
||||
/prop_tgt/ENABLE_EXPORTS
|
||||
@ -240,6 +241,7 @@ Properties on Targets
|
||||
/prop_tgt/INTERFACE_LINK_DIRECTORIES
|
||||
/prop_tgt/INTERFACE_LINK_LIBRARIES
|
||||
/prop_tgt/INTERFACE_LINK_OPTIONS
|
||||
/prop_tgt/INTERFACE_PRECOMPILE_HEADERS
|
||||
/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
|
||||
/prop_tgt/INTERFACE_SOURCES
|
||||
/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
|
||||
@ -295,6 +297,7 @@ Properties on Targets
|
||||
/prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG
|
||||
/prop_tgt/PDB_OUTPUT_DIRECTORY
|
||||
/prop_tgt/POSITION_INDEPENDENT_CODE
|
||||
/prop_tgt/PRECOMPILE_HEADERS
|
||||
/prop_tgt/PREFIX
|
||||
/prop_tgt/PRIVATE_HEADER
|
||||
/prop_tgt/PROJECT_LABEL
|
||||
@ -446,6 +449,7 @@ Properties on Source Files
|
||||
/prop_sf/SKIP_AUTOMOC
|
||||
/prop_sf/SKIP_AUTORCC
|
||||
/prop_sf/SKIP_AUTOUIC
|
||||
/prop_sf/SKIP_PRECOMPILE_HEADERS
|
||||
/prop_sf/Swift_DEPENDENCIES_FILE
|
||||
/prop_sf/Swift_DIAGNOSTICS_FILE
|
||||
/prop_sf/SYMBOLIC
|
||||
|
@ -355,6 +355,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
|
||||
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
|
||||
/variable/CMAKE_DEBUG_POSTFIX
|
||||
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
|
||||
/variable/CMAKE_ENABLE_EXPORTS
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS
|
||||
/variable/CMAKE_EXE_LINKER_FLAGS_CONFIG
|
||||
|
13
Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
Normal file
13
Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
Normal file
@ -0,0 +1,13 @@
|
||||
SKIP_PRECOMPILE_HEADERS
|
||||
-----------------------
|
||||
|
||||
Is this source file skipped by :prop_tgt:`PRECOMPILE_HEADERS` feature.
|
||||
|
||||
This property helps with build problems that one would run into
|
||||
when using the :prop_tgt:`PRECOMPILE_HEADERS` feature.
|
||||
|
||||
One example would be the usage of Objective-C (*.m) files, and
|
||||
Objective-C++ (*.mm) files, which lead to compilation failure
|
||||
because they are treated (in case of Ninja / Makefile generator)
|
||||
as C, and CXX respectively. The precompile headers are not
|
||||
compatible between languages.
|
8
Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
Normal file
8
Help/prop_tgt/DISABLE_PRECOMPILE_HEADERS.rst
Normal file
@ -0,0 +1,8 @@
|
||||
DISABLE_PRECOMPILE_HEADERS
|
||||
--------------------------
|
||||
|
||||
Disables the precompilation of header files specified by
|
||||
:prop_tgt:`PRECOMPILE_HEADERS` property.
|
||||
|
||||
If the property is not set, CMake will use the value provided
|
||||
by :variable:`CMAKE_DISABLE_PRECOMPILE_HEADERS`.
|
14
Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
Normal file
14
Help/prop_tgt/INTERFACE_PRECOMPILE_HEADERS.rst
Normal file
@ -0,0 +1,14 @@
|
||||
INTERFACE_PRECOMPILE_HEADERS
|
||||
----------------------------
|
||||
|
||||
List of interface header files to precompile into consuming targets.
|
||||
|
||||
Targets may populate this property to publish the header files
|
||||
for consuming targets to precompile. The :command:`target_precompile_headers`
|
||||
command populates this property with values given to the ``PUBLIC`` and
|
||||
``INTERFACE`` keywords. Projects may also get and set the property directly.
|
||||
|
||||
Contents of ``INTERFACE_PRECOMPILE_HEADERS`` may use "generator expressions"
|
||||
with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
|
||||
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
|
||||
manual for more on defining buildsystem properties.
|
12
Help/prop_tgt/PRECOMPILE_HEADERS.rst
Normal file
12
Help/prop_tgt/PRECOMPILE_HEADERS.rst
Normal file
@ -0,0 +1,12 @@
|
||||
PRECOMPILE_HEADERS
|
||||
------------------
|
||||
|
||||
List of header files to precompile.
|
||||
|
||||
This property holds a :ref:`semicolon-separated list <CMake Language Lists>`
|
||||
of header files to precompile specified so far for its target.
|
||||
Use the :command:`target_precompile_headers` command to append more header
|
||||
files.
|
||||
|
||||
This property supports
|
||||
:manual:`generator expressions <cmake-generator-expressions(7)>`.
|
6
Help/release/dev/precompile-headers.rst
Normal file
6
Help/release/dev/precompile-headers.rst
Normal file
@ -0,0 +1,6 @@
|
||||
Precompile Headers
|
||||
------------------
|
||||
|
||||
* The :prop_tgt:`PRECOMPILE_HEADERS` target property was added to tell
|
||||
generators to use a list of precompile headers for faster compilation
|
||||
times.
|
6
Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
Normal file
6
Help/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS.rst
Normal file
@ -0,0 +1,6 @@
|
||||
CMAKE_DISABLE_PRECOMPILE_HEADERS
|
||||
--------------------------------
|
||||
|
||||
Default value for :prop_tgt:`DISABLE_PRECOMPILE_HEADERS` of targets.
|
||||
|
||||
By default ``CMAKE_DISABLE_PRECOMPILE_HEADERS`` is ``OFF``.
|
@ -96,5 +96,7 @@ else()
|
||||
set(CMAKE_${lang}_ARCHIVE_FINISH_IPO
|
||||
"\"${__ranlib}\" <TARGET>"
|
||||
)
|
||||
|
||||
set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
|
||||
endmacro()
|
||||
endif()
|
||||
|
@ -11,6 +11,9 @@ set(__COMPILER_GNU 1)
|
||||
include(Compiler/CMakeCommonCompilerMacros)
|
||||
include(Internal/CMakeCheckCompilerFlag)
|
||||
|
||||
set(__pch_header_C "c-header")
|
||||
set(__pch_header_CXX "c++-header")
|
||||
|
||||
macro(__compiler_gnu lang)
|
||||
# Feature flags.
|
||||
set(CMAKE_${lang}_VERBOSE_FLAG "-v")
|
||||
@ -104,4 +107,9 @@ macro(__compiler_gnu lang)
|
||||
unset(_COMPILER_ARGS)
|
||||
endif()
|
||||
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-dM" "-E" "-c" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
|
||||
|
||||
set(CMAKE_PCH_EXTENSION .gch)
|
||||
set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header")
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
|
||||
endmacro()
|
||||
|
@ -32,5 +32,12 @@ else()
|
||||
unset(_COMPILER_ARGS)
|
||||
endif()
|
||||
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "-QdM" "-P" "-Za" "${CMAKE_ROOT}/Modules/CMakeCXXCompilerABI.cpp")
|
||||
|
||||
# Precompile Headers
|
||||
set(CMAKE_PCH_EXTENSION .pchi)
|
||||
set(CMAKE_LINK_PCH ON)
|
||||
set(CMAKE_PCH_EPILOGUE "#pragma hdrstop")
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
|
||||
endmacro()
|
||||
endif()
|
||||
|
@ -8,6 +8,9 @@ if(__WINDOWS_CLANG)
|
||||
endif()
|
||||
set(__WINDOWS_CLANG 1)
|
||||
|
||||
set(__pch_header_C "c-header")
|
||||
set(__pch_header_CXX "c++-header")
|
||||
|
||||
macro(__windows_compiler_clang_gnu lang)
|
||||
set(CMAKE_LIBRARY_PATH_FLAG "-L")
|
||||
set(CMAKE_LINK_LIBRARY_FLAG "-l")
|
||||
@ -73,6 +76,10 @@ macro(__windows_compiler_clang_gnu lang)
|
||||
string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG -Xclang -gcodeview ${__ADDED_FLAGS}")
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
|
||||
|
||||
set(CMAKE_PCH_EXTENSION .gch)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
|
||||
|
||||
unset(__ADDED_FLAGS)
|
||||
unset(__ADDED_FLAGS_DEBUG)
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_LOWER)
|
||||
|
@ -119,6 +119,13 @@ macro(__embarcadero_language lang)
|
||||
"tlib ${CMAKE_START_TEMP_FILE}/p512 <LINK_FLAGS> /a <TARGET_QUOTED> <OBJECTS>${CMAKE_END_TEMP_FILE}"
|
||||
)
|
||||
|
||||
# Precompile Headers
|
||||
if (EMBARCADERO)
|
||||
set(CMAKE_PCH_EXTENSION .pch)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE>)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
|
||||
endif()
|
||||
|
||||
# Initial configuration flags.
|
||||
string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_tM}")
|
||||
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -Od -v")
|
||||
|
@ -329,6 +329,15 @@ macro(__windows_compiler_msvc lang)
|
||||
set(CMAKE_${lang}_LINK_EXECUTABLE
|
||||
"${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
|
||||
|
||||
set(CMAKE_PCH_EXTENSION .pch)
|
||||
set(CMAKE_LINK_PCH ON)
|
||||
if(MSVC_VERSION GREATER_EQUAL 1910)
|
||||
# VS 2017 or greater
|
||||
set(CMAKE_PCH_PROLOGUE "#pragma system_header")
|
||||
endif()
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH /Yu<PCH_HEADER> /FI<PCH_HEADER>)
|
||||
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH /Yc<PCH_HEADER> /FI<PCH_HEADER>)
|
||||
|
||||
if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
|
||||
set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
|
||||
set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
|
||||
|
@ -654,6 +654,8 @@ set(SRCS
|
||||
cmTargetLinkDirectoriesCommand.h
|
||||
cmTargetLinkLibrariesCommand.cxx
|
||||
cmTargetLinkLibrariesCommand.h
|
||||
cmTargetPrecompileHeadersCommand.cxx
|
||||
cmTargetPrecompileHeadersCommand.h
|
||||
cmTargetPropCommandBase.cxx
|
||||
cmTargetPropCommandBase.h
|
||||
cmTargetSourcesCommand.cxx
|
||||
|
@ -78,6 +78,7 @@
|
||||
#include "cmTargetCompileOptionsCommand.h"
|
||||
#include "cmTargetIncludeDirectoriesCommand.h"
|
||||
#include "cmTargetLinkLibrariesCommand.h"
|
||||
#include "cmTargetPrecompileHeadersCommand.h"
|
||||
#include "cmTargetSourcesCommand.h"
|
||||
#include "cmTryCompileCommand.h"
|
||||
#include "cmTryRunCommand.h"
|
||||
@ -276,6 +277,9 @@ void GetProjectCommands(cmState* state)
|
||||
state->AddBuiltinCommand("try_compile",
|
||||
cm::make_unique<cmTryCompileCommand>());
|
||||
state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>());
|
||||
state->AddBuiltinCommand(
|
||||
"target_precompile_headers",
|
||||
cm::make_unique<cmTargetPrecompileHeadersCommand>());
|
||||
|
||||
#if !defined(CMAKE_BOOTSTRAP)
|
||||
state->AddBuiltinCommand("add_compile_definitions",
|
||||
|
@ -91,6 +91,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_OPTIONS", gte,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_PRECOMPILE_HEADERS", gte,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
|
@ -29,7 +29,8 @@ class cmGeneratorTarget;
|
||||
SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \
|
||||
SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS) \
|
||||
SELECT(F, EvaluatingLinkDirectories, LINK_DIRECTORIES) \
|
||||
SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS)
|
||||
SELECT(F, EvaluatingLinkDepends, LINK_DEPENDS) \
|
||||
SELECT(F, EvaluatingPrecompileHeaders, PRECOMPILE_HEADERS)
|
||||
|
||||
#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
|
||||
CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "cmCustomCommand.h"
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmCustomCommandLines.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorExpressionContext.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
@ -278,6 +279,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
|
||||
, DebugCompileDefinitionsDone(false)
|
||||
, DebugLinkOptionsDone(false)
|
||||
, DebugLinkDirectoriesDone(false)
|
||||
, DebugPrecompileHeadersDone(false)
|
||||
, DebugSourcesDone(false)
|
||||
, LinkImplementationLanguageIsContextDependent(true)
|
||||
, UtilityItemsDone(false)
|
||||
@ -312,6 +314,10 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
|
||||
t->GetLinkDirectoriesBacktraces(),
|
||||
this->LinkDirectoriesEntries);
|
||||
|
||||
CreatePropertyGeneratorExpressions(t->GetPrecompileHeadersEntries(),
|
||||
t->GetPrecompileHeadersBacktraces(),
|
||||
this->PrecompileHeadersEntries);
|
||||
|
||||
CreatePropertyGeneratorExpressions(t->GetSourceEntries(),
|
||||
t->GetSourceBacktraces(),
|
||||
this->SourceEntries, true);
|
||||
@ -327,6 +333,7 @@ cmGeneratorTarget::~cmGeneratorTarget()
|
||||
cmDeleteAll(this->CompileDefinitionsEntries);
|
||||
cmDeleteAll(this->LinkOptionsEntries);
|
||||
cmDeleteAll(this->LinkDirectoriesEntries);
|
||||
cmDeleteAll(this->PrecompileHeadersEntries);
|
||||
cmDeleteAll(this->SourceEntries);
|
||||
cmDeleteAll(this->LinkInformation);
|
||||
}
|
||||
@ -3312,6 +3319,152 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
|
||||
return list;
|
||||
}
|
||||
|
||||
std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
|
||||
const std::string& config, const std::string& language) const
|
||||
{
|
||||
std::unordered_set<std::string> uniqueOptions;
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
|
||||
nullptr, nullptr);
|
||||
|
||||
std::vector<std::string> debugProperties;
|
||||
const char* debugProp =
|
||||
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
|
||||
if (debugProp) {
|
||||
cmExpandList(debugProp, debugProperties);
|
||||
}
|
||||
|
||||
bool debugDefines = !this->DebugPrecompileHeadersDone &&
|
||||
std::find(debugProperties.begin(), debugProperties.end(),
|
||||
"PRECOMPILE_HEADERS") != debugProperties.end();
|
||||
|
||||
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
|
||||
this->DebugPrecompileHeadersDone = true;
|
||||
}
|
||||
|
||||
std::vector<EvaluatedTargetPropertyEntry> entries =
|
||||
EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
|
||||
this->PrecompileHeadersEntries);
|
||||
|
||||
AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
|
||||
&dagChecker, entries);
|
||||
|
||||
std::vector<BT<std::string>> list;
|
||||
processOptions(this, entries, list, uniqueOptions, debugDefines,
|
||||
"precompile headers", OptionsParse::None);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
|
||||
const std::string& language) const
|
||||
{
|
||||
if (language != "C" && language != "CXX") {
|
||||
return std::string();
|
||||
}
|
||||
if (this->GetPropertyAsBool("DISABLE_PRECOMPILE_HEADERS")) {
|
||||
return std::string();
|
||||
}
|
||||
const auto inserted =
|
||||
this->PchHeaders.insert(std::make_pair(language + config, ""));
|
||||
if (inserted.second) {
|
||||
const std::vector<BT<std::string>> headers =
|
||||
this->GetPrecompileHeaders(config, language);
|
||||
if (headers.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
std::string& filename = inserted.first->second;
|
||||
|
||||
if (this->GetGlobalGenerator()->IsMultiConfig()) {
|
||||
filename =
|
||||
cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(), "/");
|
||||
} else {
|
||||
// For GCC we need to have the header file .h[xx]
|
||||
// next to the .h[xx].gch file
|
||||
filename = this->ObjectDirectory;
|
||||
}
|
||||
|
||||
filename = cmStrCat(filename, "CMakeFiles/", this->GetName(),
|
||||
".dir/cmake_pch", ((language == "C") ? ".h" : ".hxx"));
|
||||
|
||||
const std::string filename_tmp = cmStrCat(filename, ".tmp");
|
||||
{
|
||||
auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
|
||||
auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE");
|
||||
|
||||
cmGeneratedFileStream file(
|
||||
filename_tmp, false,
|
||||
this->GetGlobalGenerator()->GetMakefileEncoding());
|
||||
file << "/* generated by CMake */\n\n";
|
||||
if (pchPrologue) {
|
||||
file << pchPrologue << "\n";
|
||||
}
|
||||
if (this->GetGlobalGenerator()->IsXcode()) {
|
||||
file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n";
|
||||
}
|
||||
if (language == "CXX") {
|
||||
file << "#ifdef __cplusplus\n";
|
||||
}
|
||||
for (auto const& header_bt : headers) {
|
||||
if (header_bt.Value.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (header_bt.Value[0] == '<' || header_bt.Value[0] == '"') {
|
||||
file << "#include " << header_bt.Value << "\n";
|
||||
} else {
|
||||
file << "#include \"" << header_bt.Value << "\"\n";
|
||||
}
|
||||
}
|
||||
if (language == "CXX") {
|
||||
file << "#endif // __cplusplus\n";
|
||||
}
|
||||
if (this->GetGlobalGenerator()->IsXcode()) {
|
||||
file << "#endif // CMAKE_SKIP_PRECOMPILE_HEADERS\n";
|
||||
}
|
||||
if (pchEpilogue) {
|
||||
file << pchEpilogue << "\n";
|
||||
}
|
||||
}
|
||||
cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
|
||||
cmSystemTools::RemoveFile(filename_tmp);
|
||||
}
|
||||
return inserted.first->second;
|
||||
}
|
||||
|
||||
std::string cmGeneratorTarget::GetPchSource(const std::string& config,
|
||||
const std::string& language) const
|
||||
{
|
||||
if (language != "C" && language != "CXX") {
|
||||
return std::string();
|
||||
}
|
||||
const auto inserted =
|
||||
this->PchSources.insert(std::make_pair(language + config, ""));
|
||||
if (inserted.second) {
|
||||
const std::string pchHeader = this->GetPchHeader(config, language);
|
||||
if (pchHeader.empty()) {
|
||||
return std::string();
|
||||
}
|
||||
std::string& filename = inserted.first->second;
|
||||
filename = cmStrCat(this->LocalGenerator->GetCurrentBinaryDirectory(),
|
||||
"/CMakeFiles/", this->GetName(), ".dir/cmake_pch");
|
||||
|
||||
// For GCC the source extension will be tranformed into .h[xx].gch
|
||||
if (!this->Makefile->IsOn("CMAKE_LINK_PCH")) {
|
||||
filename += ((language == "C") ? ".h.c" : ".hxx.cxx");
|
||||
} else {
|
||||
filename += ((language == "C") ? ".c" : ".cxx");
|
||||
}
|
||||
const std::string filename_tmp = cmStrCat(filename, ".tmp");
|
||||
{
|
||||
cmGeneratedFileStream file(filename_tmp);
|
||||
file << "/* generated by CMake */\n";
|
||||
}
|
||||
cmSystemTools::CopyFileIfDifferent(filename_tmp, filename);
|
||||
cmSystemTools::RemoveFile(filename_tmp);
|
||||
}
|
||||
return inserted.first->second;
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
|
||||
const std::string& config,
|
||||
const std::string& language) const
|
||||
|
@ -455,6 +455,14 @@ public:
|
||||
std::vector<BT<std::string>> GetLinkDepends(
|
||||
std::string const& config, std::string const& language) const;
|
||||
|
||||
std::vector<BT<std::string>> GetPrecompileHeaders(
|
||||
const std::string& config, const std::string& language) const;
|
||||
|
||||
std::string GetPchHeader(const std::string& config,
|
||||
const std::string& language) const;
|
||||
std::string GetPchSource(const std::string& config,
|
||||
const std::string& language) const;
|
||||
|
||||
bool IsSystemIncludeDirectory(const std::string& dir,
|
||||
const std::string& config,
|
||||
const std::string& language) const;
|
||||
@ -867,8 +875,11 @@ private:
|
||||
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
|
||||
std::vector<TargetPropertyEntry*> LinkOptionsEntries;
|
||||
std::vector<TargetPropertyEntry*> LinkDirectoriesEntries;
|
||||
std::vector<TargetPropertyEntry*> PrecompileHeadersEntries;
|
||||
std::vector<TargetPropertyEntry*> SourceEntries;
|
||||
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||
mutable std::map<std::string, std::string> PchHeaders;
|
||||
mutable std::map<std::string, std::string> PchSources;
|
||||
|
||||
void ExpandLinkItems(std::string const& prop, std::string const& value,
|
||||
std::string const& config,
|
||||
@ -922,6 +933,7 @@ private:
|
||||
mutable bool DebugCompileDefinitionsDone;
|
||||
mutable bool DebugLinkOptionsDone;
|
||||
mutable bool DebugLinkDirectoriesDone;
|
||||
mutable bool DebugPrecompileHeadersDone;
|
||||
mutable bool DebugSourcesDone;
|
||||
mutable bool LinkImplementationLanguageIsContextDependent;
|
||||
mutable bool UtilityItemsDone;
|
||||
|
@ -110,6 +110,13 @@ public:
|
||||
|
||||
bool IsIncludeExternalMSProjectSupported() const override { return true; }
|
||||
|
||||
/** Get encoding used by generator for generated source files
|
||||
*/
|
||||
codecvt::Encoding GetMakefileEncoding() const override
|
||||
{
|
||||
return codecvt::ANSI;
|
||||
}
|
||||
|
||||
class TargetSet : public std::set<cmGeneratorTarget const*>
|
||||
{
|
||||
};
|
||||
|
@ -2374,6 +2374,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
|
||||
buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION",
|
||||
this->CreateString(vso.str()));
|
||||
}
|
||||
|
||||
// Precompile Headers
|
||||
std::string pchHeader = gtgt->GetPchHeader(configName, llang);
|
||||
if (!pchHeader.empty()) {
|
||||
buildSettings->AddAttribute("GCC_PREFIX_HEADER",
|
||||
this->CreateString(pchHeader));
|
||||
buildSettings->AddAttribute("GCC_PRECOMPILE_PREFIX_HEADER",
|
||||
this->CreateString("YES"));
|
||||
}
|
||||
|
||||
// put this last so it can override existing settings
|
||||
// Convert "XCODE_ATTRIBUTE_*" properties directly.
|
||||
{
|
||||
@ -2829,6 +2839,8 @@ bool cmGlobalXCodeGenerator::CreateGroups(
|
||||
continue;
|
||||
}
|
||||
|
||||
generator->AddPchDependencies(gtgt, "");
|
||||
|
||||
auto addSourceToGroup = [this, mf, gtgt,
|
||||
&sourceGroups](std::string const& source) {
|
||||
cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "cmRulePlaceholderExpander.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmSourceFileLocation.h"
|
||||
#include "cmSourceFileLocationKind.h"
|
||||
#include "cmState.h"
|
||||
#include "cmStateDirectory.h"
|
||||
#include "cmStateTypes.h"
|
||||
@ -37,6 +38,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
@ -2124,6 +2126,82 @@ void cmLocalGenerator::AppendFlagEscape(std::string& flags,
|
||||
this->AppendFlags(flags, this->EscapeForShell(rawFlag));
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target,
|
||||
const std::string& config)
|
||||
{
|
||||
const std::string lang = target->GetLinkerLanguage(config);
|
||||
const std::string buildType = cmSystemTools::UpperCase(config);
|
||||
const std::string pchSource = target->GetPchSource(config, lang);
|
||||
const std::string pchHeader = target->GetPchHeader(config, lang);
|
||||
|
||||
if (pchSource.empty() || pchHeader.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string createOptVar =
|
||||
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_CREATE_PCH");
|
||||
std::string createOptionList =
|
||||
this->Makefile->GetSafeDefinition(createOptVar);
|
||||
|
||||
const std::string useOptVar =
|
||||
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_USE_PCH");
|
||||
std::string useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
|
||||
|
||||
const std::string pchExtension =
|
||||
this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
if (createOptionList.empty() || useOptionList.empty() ||
|
||||
pchExtension.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto pch_sf = this->Makefile->GetOrCreateSource(
|
||||
pchSource, false, cmSourceFileLocationKind::Known);
|
||||
std::string pchFile = pchHeader;
|
||||
|
||||
if (!this->GetGlobalGenerator()->IsXcode()) {
|
||||
// Exclude the pch files from linking
|
||||
if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
|
||||
cmSystemTools::ReplaceString(pchFile, (lang == "C" ? ".h" : ".hxx"),
|
||||
pchExtension);
|
||||
pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
|
||||
} else {
|
||||
pchFile += pchExtension;
|
||||
pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
|
||||
}
|
||||
|
||||
target->AddSource(pchSource, true);
|
||||
|
||||
for (auto& str : { std::ref(useOptionList), std::ref(createOptionList) }) {
|
||||
cmSystemTools::ReplaceString(str, "<PCH_HEADER>", pchHeader);
|
||||
cmSystemTools::ReplaceString(str, "<PCH_FILE>", pchFile);
|
||||
}
|
||||
}
|
||||
|
||||
pch_sf->SetProperty("COMPILE_OPTIONS", createOptionList.c_str());
|
||||
|
||||
std::vector<cmSourceFile*> sources;
|
||||
target->GetSourceFiles(sources, buildType);
|
||||
for (cmSourceFile* sf : sources) {
|
||||
if (pch_sf == sf || sf->GetLanguage() != lang) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sf->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
|
||||
if (this->GetGlobalGenerator()->IsXcode()) {
|
||||
sf->SetProperty("COMPILE_DEFINITIONS",
|
||||
"CMAKE_SKIP_PRECOMPILE_HEADERS");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this->GetGlobalGenerator()->IsXcode()) {
|
||||
sf->SetProperty("OBJECT_DEPENDS", pchFile.c_str());
|
||||
sf->SetProperty("COMPILE_OPTIONS", useOptionList.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
|
||||
cmGeneratorTarget* target,
|
||||
const std::string& config,
|
||||
@ -2716,6 +2794,11 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
|
||||
}
|
||||
}
|
||||
|
||||
const char* pchExtension = source.GetProperty("PCH_EXTENSION");
|
||||
if (pchExtension) {
|
||||
customOutputExtension = pchExtension;
|
||||
}
|
||||
|
||||
// Remove the source extension if it is to be replaced.
|
||||
if (replaceExt || customOutputExtension) {
|
||||
keptSourceExtension = false;
|
||||
|
@ -124,6 +124,8 @@ public:
|
||||
virtual void AppendFlags(std::string& flags, const char* newFlags) const;
|
||||
virtual void AppendFlagEscape(std::string& flags,
|
||||
const std::string& rawFlag) const;
|
||||
void AddPchDependencies(cmGeneratorTarget* target,
|
||||
const std::string& config);
|
||||
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
|
||||
const std::string& config,
|
||||
const std::string& lang);
|
||||
|
@ -1320,6 +1320,8 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||
const std::string& libName,
|
||||
cmGeneratorTarget* target)
|
||||
{
|
||||
this->AddPchDependencies(target, "");
|
||||
|
||||
std::vector<std::string> configs;
|
||||
this->Makefile->GetConfigurations(configs);
|
||||
|
||||
|
@ -40,6 +40,8 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
|
||||
this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
|
||||
}
|
||||
|
||||
cmMakefileExecutableTargetGenerator::~cmMakefileExecutableTargetGenerator() =
|
||||
|
@ -42,6 +42,8 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
|
||||
this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
|
||||
}
|
||||
|
||||
cmMakefileLibraryTargetGenerator::~cmMakefileLibraryTargetGenerator() =
|
||||
|
@ -239,10 +239,15 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
||||
this->GeneratorTarget->GetExtraSources(extraSources, config);
|
||||
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
|
||||
extraSources, this->MacOSXContentGenerator);
|
||||
const char* pchExtension =
|
||||
this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
std::vector<cmSourceFile const*> externalObjects;
|
||||
this->GeneratorTarget->GetExternalObjects(externalObjects, config);
|
||||
for (cmSourceFile const* sf : externalObjects) {
|
||||
this->ExternalObjects.push_back(sf->GetFullPath());
|
||||
auto const& objectFileName = sf->GetFullPath();
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
this->ExternalObjects.push_back(objectFileName);
|
||||
}
|
||||
}
|
||||
std::vector<cmSourceFile const*> objectSources;
|
||||
this->GeneratorTarget->GetObjectSources(objectSources, config);
|
||||
@ -1238,7 +1243,14 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
|
||||
if (!lineContinue) {
|
||||
lineContinue = "\\";
|
||||
}
|
||||
|
||||
const char* pchExtension =
|
||||
this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
for (std::string const& obj : this->Objects) {
|
||||
if (cmSystemTools::StringEndsWith(obj, pchExtension)) {
|
||||
continue;
|
||||
}
|
||||
*this->BuildFileStream << " " << lineContinue << "\n";
|
||||
*this->BuildFileStream
|
||||
<< cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
|
||||
@ -1331,10 +1343,16 @@ private:
|
||||
void cmMakefileTargetGenerator::WriteObjectsStrings(
|
||||
std::vector<std::string>& objStrings, std::string::size_type limit)
|
||||
{
|
||||
const char* pchExtension =
|
||||
this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
cmMakefileTargetGeneratorObjectStrings helper(
|
||||
objStrings, this->LocalGenerator,
|
||||
this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit);
|
||||
for (std::string const& obj : this->Objects) {
|
||||
if (cmSystemTools::StringEndsWith(obj, pchExtension)) {
|
||||
continue;
|
||||
}
|
||||
helper.Feed(obj);
|
||||
}
|
||||
for (std::string const& obj : this->ExternalObjects) {
|
||||
|
@ -25,6 +25,8 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
|
||||
this->LocalGenerator->AddPchDependencies(target, this->ConfigName);
|
||||
}
|
||||
|
||||
cmMakefileUtilityTargetGenerator::~cmMakefileUtilityTargetGenerator() =
|
||||
|
@ -59,6 +59,8 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
|
||||
this->OSXBundleGenerator =
|
||||
cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
|
||||
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
|
||||
|
||||
GetLocalGenerator()->AddPchDependencies(target, this->GetConfigName());
|
||||
}
|
||||
|
||||
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
|
||||
|
@ -790,10 +790,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
|
||||
extraSources, this->MacOSXContentGenerator.get());
|
||||
}
|
||||
{
|
||||
const char* pchExtension =
|
||||
GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
|
||||
std::vector<cmSourceFile const*> externalObjects;
|
||||
this->GeneratorTarget->GetExternalObjects(externalObjects, config);
|
||||
for (cmSourceFile const* sf : externalObjects) {
|
||||
this->Objects.push_back(this->GetSourceFilePath(sf));
|
||||
const auto objectFileName = this->GetSourceFilePath(sf);
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
this->Objects.push_back(objectFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -955,8 +961,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
|
||||
vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
|
||||
|
||||
objBuild.Outputs.push_back(objectFileName);
|
||||
// Add this object to the list of object files.
|
||||
this->Objects.push_back(objectFileName);
|
||||
const char* pchExtension =
|
||||
this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
|
||||
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
|
||||
// Add this object to the list of object files.
|
||||
this->Objects.push_back(objectFileName);
|
||||
}
|
||||
|
||||
objBuild.ExplicitDeps.push_back(sourceFileName);
|
||||
|
||||
|
@ -190,6 +190,8 @@ public:
|
||||
std::vector<cmListFileBacktrace> CompileFeaturesBacktraces;
|
||||
std::vector<std::string> CompileDefinitionsEntries;
|
||||
std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
|
||||
std::vector<std::string> PrecompileHeadersEntries;
|
||||
std::vector<cmListFileBacktrace> PrecompileHeadersBacktraces;
|
||||
std::vector<std::string> SourceEntries;
|
||||
std::vector<cmListFileBacktrace> SourceBacktraces;
|
||||
std::vector<std::string> LinkOptionsEntries;
|
||||
@ -349,6 +351,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
initProp("Swift_LANGUAGE_VERSION");
|
||||
initProp("Swift_MODULE_DIRECTORY");
|
||||
initProp("VS_JUST_MY_CODE_DEBUGGING");
|
||||
initProp("DISABLE_PRECOMPILE_HEADERS");
|
||||
#ifdef __APPLE__
|
||||
if (this->GetGlobalGenerator()->IsXcode()) {
|
||||
initProp("XCODE_GENERATE_SCHEME");
|
||||
@ -1018,6 +1021,16 @@ cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const
|
||||
return cmMakeRange(impl->CompileDefinitionsBacktraces);
|
||||
}
|
||||
|
||||
cmStringRange cmTarget::GetPrecompileHeadersEntries() const
|
||||
{
|
||||
return cmMakeRange(impl->PrecompileHeadersEntries);
|
||||
}
|
||||
|
||||
cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const
|
||||
{
|
||||
return cmMakeRange(impl->PrecompileHeadersBacktraces);
|
||||
}
|
||||
|
||||
cmStringRange cmTarget::GetSourceEntries() const
|
||||
{
|
||||
return cmMakeRange(impl->SourceEntries);
|
||||
@ -1069,6 +1082,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
|
||||
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
|
||||
MAKE_STATIC_PROP(COMPILE_FEATURES);
|
||||
MAKE_STATIC_PROP(COMPILE_OPTIONS);
|
||||
MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
|
||||
MAKE_STATIC_PROP(CUDA_PTX_COMPILATION);
|
||||
MAKE_STATIC_PROP(EXPORT_NAME);
|
||||
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
|
||||
@ -1167,6 +1181,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
|
||||
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
|
||||
impl->LinkDirectoriesBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == propPRECOMPILE_HEADERS) {
|
||||
impl->PrecompileHeadersEntries.clear();
|
||||
impl->PrecompileHeadersBacktraces.clear();
|
||||
if (value) {
|
||||
impl->PrecompileHeadersEntries.emplace_back(value);
|
||||
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
|
||||
impl->PrecompileHeadersBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == propLINK_LIBRARIES) {
|
||||
impl->LinkImplementationPropertyEntries.clear();
|
||||
impl->LinkImplementationPropertyBacktraces.clear();
|
||||
@ -1283,6 +1305,12 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
|
||||
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
|
||||
impl->LinkDirectoriesBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == "PRECOMPILE_HEADERS") {
|
||||
if (value && *value) {
|
||||
impl->PrecompileHeadersEntries.emplace_back(value);
|
||||
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
|
||||
impl->PrecompileHeadersBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == "LINK_LIBRARIES") {
|
||||
if (value && *value) {
|
||||
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
|
||||
@ -1394,6 +1422,13 @@ void cmTarget::InsertLinkDirectory(std::string const& entry,
|
||||
impl->LinkDirectoriesBacktraces.insert(btPosition, bt);
|
||||
}
|
||||
|
||||
void cmTarget::InsertPrecompileHeader(std::string const& entry,
|
||||
cmListFileBacktrace const& bt)
|
||||
{
|
||||
impl->PrecompileHeadersEntries.push_back(entry);
|
||||
impl->PrecompileHeadersBacktraces.push_back(bt);
|
||||
}
|
||||
|
||||
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
|
||||
const char* value,
|
||||
cmMakefile* context,
|
||||
@ -1514,6 +1549,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
|
||||
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
|
||||
MAKE_STATIC_PROP(LINK_OPTIONS);
|
||||
MAKE_STATIC_PROP(LINK_DIRECTORIES);
|
||||
MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
|
||||
MAKE_STATIC_PROP(IMPORTED);
|
||||
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
|
||||
MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
|
||||
@ -1529,6 +1565,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
|
||||
propCOMPILE_FEATURES,
|
||||
propCOMPILE_OPTIONS,
|
||||
propCOMPILE_DEFINITIONS,
|
||||
propPRECOMPILE_HEADERS,
|
||||
propLINK_OPTIONS,
|
||||
propLINK_DIRECTORIES,
|
||||
propIMPORTED,
|
||||
@ -1617,6 +1654,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const
|
||||
output = cmJoin(impl->Utilities, ";");
|
||||
return output.c_str();
|
||||
}
|
||||
if (prop == propPRECOMPILE_HEADERS) {
|
||||
if (impl->PrecompileHeadersEntries.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static std::string output;
|
||||
output = cmJoin(impl->PrecompileHeadersEntries, ";");
|
||||
return output.c_str();
|
||||
}
|
||||
if (prop == propIMPORTED) {
|
||||
return this->IsImported() ? "TRUE" : "FALSE";
|
||||
}
|
||||
|
@ -216,6 +216,8 @@ public:
|
||||
cmListFileBacktrace const& bt, bool before = false);
|
||||
void InsertLinkDirectory(std::string const& entry,
|
||||
cmListFileBacktrace const& bt, bool before = false);
|
||||
void InsertPrecompileHeader(std::string const& entry,
|
||||
cmListFileBacktrace const& bt);
|
||||
|
||||
void AppendBuildInterfaceIncludes();
|
||||
|
||||
@ -237,6 +239,9 @@ public:
|
||||
cmStringRange GetCompileDefinitionsEntries() const;
|
||||
cmBacktraceRange GetCompileDefinitionsBacktraces() const;
|
||||
|
||||
cmStringRange GetPrecompileHeadersEntries() const;
|
||||
cmBacktraceRange GetPrecompileHeadersBacktraces() const;
|
||||
|
||||
cmStringRange GetSourceEntries() const;
|
||||
cmBacktraceRange GetSourceBacktraces() const;
|
||||
|
||||
|
36
Source/cmTargetPrecompileHeadersCommand.cxx
Normal file
36
Source/cmTargetPrecompileHeadersCommand.cxx
Normal file
@ -0,0 +1,36 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmTargetPrecompileHeadersCommand.h"
|
||||
|
||||
#include "cmMakefile.h"
|
||||
#include "cmMessageType.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmTarget.h"
|
||||
|
||||
bool cmTargetPrecompileHeadersCommand::InitialPass(
|
||||
std::vector<std::string> const& args, cmExecutionStatus&)
|
||||
{
|
||||
return this->HandleArguments(args, "PRECOMPILE_HEADERS");
|
||||
}
|
||||
|
||||
void cmTargetPrecompileHeadersCommand::HandleMissingTarget(
|
||||
const std::string& name)
|
||||
{
|
||||
const std::string e =
|
||||
cmStrCat("Cannot specify precompile headers for target \"", name,
|
||||
"\" which is not built by this project.");
|
||||
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
|
||||
}
|
||||
|
||||
std::string cmTargetPrecompileHeadersCommand::Join(
|
||||
const std::vector<std::string>& content)
|
||||
{
|
||||
return cmJoin(content, ";");
|
||||
}
|
||||
|
||||
bool cmTargetPrecompileHeadersCommand::HandleDirectContent(
|
||||
cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
|
||||
{
|
||||
tgt->AppendProperty("PRECOMPILE_HEADERS", this->Join(content).c_str());
|
||||
return true;
|
||||
}
|
41
Source/cmTargetPrecompileHeadersCommand.h
Normal file
41
Source/cmTargetPrecompileHeadersCommand.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmTargetPrecompileHeadersCommand_h
|
||||
#define cmTargetPrecompileHeadersCommand_h
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cm_memory.hxx"
|
||||
|
||||
#include "cmCommand.h"
|
||||
|
||||
#include "cmTargetPropCommandBase.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
class cmTarget;
|
||||
|
||||
class cmTargetPrecompileHeadersCommand : public cmTargetPropCommandBase
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<cmCommand> Clone() override
|
||||
{
|
||||
return cm::make_unique<cmTargetPrecompileHeadersCommand>();
|
||||
}
|
||||
|
||||
bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status) override;
|
||||
|
||||
private:
|
||||
void HandleMissingTarget(const std::string& name) override;
|
||||
|
||||
bool HandleDirectContent(cmTarget* tgt,
|
||||
const std::vector<std::string>& content,
|
||||
bool prepend, bool system) override;
|
||||
|
||||
std::string Join(const std::vector<std::string>& content) override;
|
||||
};
|
||||
|
||||
#endif
|
@ -249,6 +249,8 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator(
|
||||
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
|
||||
this->InSourceBuild = (this->Makefile->GetCurrentSourceDirectory() ==
|
||||
this->Makefile->GetCurrentBinaryDirectory());
|
||||
|
||||
this->LocalGenerator->AddPchDependencies(target, "");
|
||||
}
|
||||
|
||||
cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
|
||||
@ -2148,6 +2150,9 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
|
||||
if (si.Kind == cmGeneratorTarget::SourceKindObjectSource) {
|
||||
this->OutputSourceSpecificFlags(e2, si.Source);
|
||||
}
|
||||
if (si.Source->GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS")) {
|
||||
e2.Element("PrecompiledHeader", "NotUsing");
|
||||
}
|
||||
if (!exclude_configs.empty()) {
|
||||
this->WriteExcludeFromBuild(e2, exclude_configs);
|
||||
}
|
||||
@ -2629,6 +2634,13 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
|
||||
this->IPOEnabledConfigurations.insert(configName);
|
||||
}
|
||||
|
||||
// Precompile Headers
|
||||
std::string pchHeader =
|
||||
this->GeneratorTarget->GetPchHeader(configName, linkLanguage);
|
||||
if (this->MSTools && vcxproj == this->ProjectType && pchHeader.empty()) {
|
||||
clOptions.AddFlag("PrecompiledHeader", "NotUsing");
|
||||
}
|
||||
|
||||
// Get preprocessor definitions for this directory.
|
||||
std::string defineFlags = this->Makefile->GetDefineFlags();
|
||||
if (this->MSTools) {
|
||||
@ -2644,7 +2656,6 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
|
||||
// replace this setting with "true" below.
|
||||
clOptions.AddFlag("UseFullPaths", "false");
|
||||
}
|
||||
clOptions.AddFlag("PrecompiledHeader", "NotUsing");
|
||||
clOptions.AddFlag("AssemblerListingLocation", "$(IntDir)");
|
||||
}
|
||||
}
|
||||
|
@ -573,3 +573,5 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|9[0-9])")
|
||||
endif()
|
||||
|
||||
add_RunCMake_test("CTestCommandExpandLists")
|
||||
|
||||
add_RunCMake_test(PrecompileHeaders)
|
||||
|
3
Tests/RunCMake/PrecompileHeaders/CMakeLists.txt
Normal file
3
Tests/RunCMake/PrecompileHeaders/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.15.0)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
17
Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
Normal file
17
Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
Normal file
@ -0,0 +1,17 @@
|
||||
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/CMakeFiles/foo.dir/cmake_pch.h")
|
||||
set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/CMakeFiles/foobar.dir/cmake_pch.h")
|
||||
else()
|
||||
set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
|
||||
set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${foo_pch_header})
|
||||
set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (EXISTS ${foobar_pch_header})
|
||||
set(RunCMake_TEST_FAILED "Generated foobar pch header ${foobar_pch_header} should not exist")
|
||||
return()
|
||||
endif()
|
14
Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake
Normal file
14
Tests/RunCMake/PrecompileHeaders/DisabledPch.cmake
Normal file
@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(DisabledPch C)
|
||||
|
||||
add_library(foo foo.c)
|
||||
target_include_directories(foo PUBLIC include)
|
||||
target_precompile_headers(foo PUBLIC
|
||||
foo.h
|
||||
<stdio.h>
|
||||
\"string.h\"
|
||||
)
|
||||
|
||||
add_executable(foobar foobar.c)
|
||||
target_link_libraries(foobar foo)
|
||||
set_target_properties(foobar PROPERTIES DISABLE_PRECOMPILE_HEADERS ON)
|
36
Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
Normal file
36
Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
Normal file
@ -0,0 +1,36 @@
|
||||
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/CMakeFiles/foo.dir/cmake_pch.h")
|
||||
set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/CMakeFiles/foobar.dir/cmake_pch.h")
|
||||
else()
|
||||
set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
|
||||
set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${foo_pch_header})
|
||||
set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS ${foobar_pch_header})
|
||||
set(RunCMake_TEST_FAILED "Generated foobar pch header ${foobar_pch_header} does not exist")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(STRINGS ${foo_pch_header} foo_pch_header_strings)
|
||||
|
||||
if (NOT "#include \"foo.h\"" IN_LIST foo_pch_header_strings OR
|
||||
NOT "#include <stdio.h>" IN_LIST foo_pch_header_strings OR
|
||||
NOT "#include \"string.h\"" IN_LIST foo_pch_header_strings)
|
||||
set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} has bad content")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(STRINGS ${foobar_pch_header} foobar_pch_header_strings)
|
||||
|
||||
if (NOT "#include \"foo.h\"" IN_LIST foobar_pch_header_strings OR
|
||||
NOT "#include <stdio.h>" IN_LIST foobar_pch_header_strings OR
|
||||
NOT "#include \"string.h\"" IN_LIST foobar_pch_header_strings OR
|
||||
NOT "#include \"bar.h\"" IN_LIST foobar_pch_header_strings)
|
||||
set(RunCMake_TEST_FAILED "Generated foobar pch header ${foobar_pch_header} has bad content")
|
||||
return()
|
||||
endif()
|
20
Tests/RunCMake/PrecompileHeaders/PchInterface.cmake
Normal file
20
Tests/RunCMake/PrecompileHeaders/PchInterface.cmake
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(PchInterface C)
|
||||
|
||||
add_library(foo foo.c)
|
||||
target_include_directories(foo PUBLIC include)
|
||||
target_precompile_headers(foo PUBLIC
|
||||
foo.h
|
||||
<stdio.h>
|
||||
\"string.h\"
|
||||
)
|
||||
|
||||
add_library(bar INTERFACE)
|
||||
target_include_directories(bar INTERFACE include)
|
||||
target_precompile_headers(bar INTERFACE bar.h)
|
||||
|
||||
add_executable(foobar foobar.c)
|
||||
target_link_libraries(foobar foo bar)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME foobar COMMAND foobar)
|
@ -0,0 +1,12 @@
|
||||
if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/CMakeFiles/main.dir/cmake_pch.hxx")
|
||||
else()
|
||||
set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/cmake_pch.hxx")
|
||||
endif()
|
||||
|
||||
file(STRINGS ${main_pch_header} main_pch_header_strings)
|
||||
string(REGEX MATCH "#pragma warning\\(push, 0\\).*#include.*pch.h.*#pragma warning\\(pop\\)" matched_code ${main_pch_header_strings})
|
||||
if(NOT matched_code)
|
||||
set(RunCMake_TEST_FAILED "Generated pch file doesn't include expected prologue and epilogue code")
|
||||
return()
|
||||
endif()
|
11
Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue.cmake
Normal file
11
Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue.cmake
Normal file
@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(PchPrologueEpilogue)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CMAKE_PCH_PROLOGUE "#pragma warning(push, 0)")
|
||||
set(CMAKE_PCH_EPILOGUE "#pragma warning(pop)")
|
||||
|
||||
add_executable(main main.cpp)
|
||||
target_precompile_headers(main PRIVATE pch.h)
|
18
Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
Normal file
18
Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
Normal file
@ -0,0 +1,18 @@
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
include(RunCMake)
|
||||
|
||||
function(run_test name)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
|
||||
run_cmake(${name})
|
||||
# Precompiled headers are not supported with multiple architectures.
|
||||
if(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
run_cmake(DisabledPch)
|
||||
run_test(PchInterface)
|
||||
run_cmake(PchPrologueEpilogue)
|
||||
run_test(SkipPrecompileHeaders)
|
13
Tests/RunCMake/PrecompileHeaders/SkipPrecompileHeaders.cmake
Normal file
13
Tests/RunCMake/PrecompileHeaders/SkipPrecompileHeaders.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(SkipPrecompileHeaders)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_executable(pch-test main.cpp non-pch.cpp)
|
||||
target_precompile_headers(pch-test PRIVATE pch.h)
|
||||
|
||||
set_source_files_properties(non-pch.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
|
||||
|
||||
enable_testing()
|
||||
add_test(NAME pch-test COMMAND pch-test)
|
6
Tests/RunCMake/PrecompileHeaders/foo.c
Normal file
6
Tests/RunCMake/PrecompileHeaders/foo.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "foo.h"
|
||||
|
||||
int foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
7
Tests/RunCMake/PrecompileHeaders/foobar.c
Normal file
7
Tests/RunCMake/PrecompileHeaders/foobar.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "bar.h"
|
||||
#include "foo.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
return foo() + bar();
|
||||
}
|
9
Tests/RunCMake/PrecompileHeaders/include/bar.h
Normal file
9
Tests/RunCMake/PrecompileHeaders/include/bar.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef bar_h
|
||||
#define bar_h
|
||||
|
||||
static int bar()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
6
Tests/RunCMake/PrecompileHeaders/include/foo.h
Normal file
6
Tests/RunCMake/PrecompileHeaders/include/foo.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef foo_h
|
||||
#define foo_h
|
||||
|
||||
extern int foo();
|
||||
|
||||
#endif
|
4
Tests/RunCMake/PrecompileHeaders/main.cpp
Normal file
4
Tests/RunCMake/PrecompileHeaders/main.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
3
Tests/RunCMake/PrecompileHeaders/non-pch.cpp
Normal file
3
Tests/RunCMake/PrecompileHeaders/non-pch.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#ifdef PCH_INCLUDED
|
||||
# error "PCH must not be included into this file!"
|
||||
#endif
|
3
Tests/RunCMake/PrecompileHeaders/pch.h
Normal file
3
Tests/RunCMake/PrecompileHeaders/pch.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define PCH_INCLUDED 1
|
@ -25,6 +25,7 @@ run_cmake(VsProjectImport)
|
||||
run_cmake(VsPackageReferences)
|
||||
run_cmake(VsDpiAware)
|
||||
run_cmake(VsDpiAwareBadParam)
|
||||
run_cmake(VsPrecompileHeaders)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
|
||||
run_cmake(VsJustMyCode)
|
||||
|
69
Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
Normal file
69
Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
Normal file
@ -0,0 +1,69 @@
|
||||
set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx")
|
||||
set(pch_source "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.cxx")
|
||||
|
||||
file(TO_NATIVE_PATH "${pch_source}" pch_source_win)
|
||||
|
||||
if(NOT EXISTS "${pch_header}")
|
||||
set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.")
|
||||
return()
|
||||
endif()
|
||||
if(NOT EXISTS "${pch_source}")
|
||||
set(RunCMake_TEST_FAILED "Generated PCH header ${pch_source} does not exist.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
|
||||
if (NOT EXISTS "${tgt_project}")
|
||||
set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(STRINGS ${tgt_project} tgt_projects_strings)
|
||||
|
||||
foreach(line IN LISTS tgt_projects_strings)
|
||||
if (line MATCHES "<PrecompiledHeader.*>Use</PrecompiledHeader>")
|
||||
set(have_pch_use ON)
|
||||
endif()
|
||||
|
||||
if (line MATCHES "<PrecompiledHeader.*>Create</PrecompiledHeader>")
|
||||
set(have_pch_create ON)
|
||||
endif()
|
||||
|
||||
if (line MATCHES "<PrecompiledHeaderFile.*>${pch_header}</PrecompiledHeaderFile>")
|
||||
set(have_pch_header ON)
|
||||
endif()
|
||||
|
||||
if (line MATCHES "<ForcedIncludeFiles.*>${pch_header}</ForcedIncludeFiles>")
|
||||
set(have_force_pch_header ON)
|
||||
endif()
|
||||
|
||||
string(FIND "${line}" "<ClCompile Include=\"${pch_source_win}\">" find_pos)
|
||||
if (NOT find_pos EQUAL "-1")
|
||||
set(have_pch_source_compile ON)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (NOT have_pch_use)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeader>Use</PrecompiledHeader> block.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT have_pch_create)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeader>Create</PrecompiledHeader> block.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT have_pch_header)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the <PrecompiledHeaderFile>${pch_header}</PrecompiledHeaderFile> block.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT have_force_pch_header)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the <ForcedIncludeFiles>${pch_header}</ForcedIncludeFiles> block.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT have_pch_source_compile)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the <ClCompile Include=\"${pch_source_win}\"> block.")
|
||||
return()
|
||||
endif()
|
4
Tests/RunCMake/VS10Project/VsPrecompileHeaders.cmake
Normal file
4
Tests/RunCMake/VS10Project/VsPrecompileHeaders.cmake
Normal file
@ -0,0 +1,4 @@
|
||||
project(VsPrecompileHeaders CXX)
|
||||
|
||||
add_library(tgt SHARED empty.cxx)
|
||||
target_precompile_headers(tgt PRIVATE stdafx.h)
|
@ -12,6 +12,7 @@ run_cmake(XcodeObjectNeedsQuote)
|
||||
run_cmake(XcodeOptimizationFlags)
|
||||
run_cmake(XcodePreserveNonOptimizationFlags)
|
||||
run_cmake(XcodePreserveObjcFlag)
|
||||
run_cmake(XcodePrecompileHeaders)
|
||||
if (NOT XCODE_VERSION VERSION_LESS 6)
|
||||
run_cmake(XcodePlatformFrameworks)
|
||||
endif()
|
||||
|
@ -0,0 +1,35 @@
|
||||
set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx")
|
||||
|
||||
if(NOT EXISTS "${pch_header}")
|
||||
set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(tgt_project "${RunCMake_TEST_BINARY_DIR}/XcodePrecompileHeaders.xcodeproj/project.pbxproj")
|
||||
if (NOT EXISTS "${tgt_project}")
|
||||
set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
file(STRINGS ${tgt_project} tgt_projects_strings)
|
||||
|
||||
foreach(line IN LISTS tgt_projects_strings)
|
||||
if (line MATCHES "GCC_PRECOMPILE_PREFIX_HEADER = YES;")
|
||||
set(have_pch_prefix ON)
|
||||
endif()
|
||||
|
||||
string(FIND "${line}" "GCC_PREFIX_HEADER = \"${pch_header}\";" find_pos)
|
||||
if (NOT find_pos EQUAL "-1")
|
||||
set(have_pch_header ON)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (NOT have_pch_prefix)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the GCC_PRECOMPILE_PREFIX_HEADER = YES; line.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT have_pch_header)
|
||||
set(RunCMake_TEST_FAILED "Generated project should have the GCC_PREFIX_HEADER = \"${pch_header}\"; line.")
|
||||
return()
|
||||
endif()
|
4
Tests/RunCMake/XcodeProject/XcodePrecompileHeaders.cmake
Normal file
4
Tests/RunCMake/XcodeProject/XcodePrecompileHeaders.cmake
Normal file
@ -0,0 +1,4 @@
|
||||
project(XcodePrecompileHeaders CXX)
|
||||
|
||||
add_library(tgt foo.cpp)
|
||||
target_precompile_headers(tgt PRIVATE stdafx.h)
|
@ -23,6 +23,7 @@
|
||||
# HACK: check whether this can be removed with next iwyu release.
|
||||
{ include: [ "<bits/shared_ptr.h>", private, "<memory>", public ] },
|
||||
{ include: [ "<bits/std_function.h>", private, "<functional>", public ] },
|
||||
{ include: [ "<bits/refwrap.h>", private, "<functional>", public ] },
|
||||
{ include: [ "<bits/stdint-intn.h>", private, "<stdint.h>", public ] },
|
||||
{ include: [ "<bits/stdint-uintn.h>", private, "<stdint.h>", public ] },
|
||||
{ include: [ "<bits/time.h>", private, "<time.h>", public ] },
|
||||
@ -73,6 +74,7 @@
|
||||
# Use '-Xiwyu -v7' to see the fully qualified names that need this.
|
||||
# TODO: Can this be simplified with an @-expression?
|
||||
#{ symbol: [ "@std::__decay_and_strip<.*>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<char const (&)[1]>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<cmCommand *&>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<cmGeneratorTarget *&>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::__decay_and_strip<cmFindCommon::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
|
Loading…
Reference in New Issue
Block a user