mirror of
https://github.com/Kitware/CMake.git
synced 2026-07-11 18:13:40 +00:00
Autogen: Process .hh headers based on new policy CMP0100 settings
Reintroduces .hh header processing in AUTOMOC and AUTOUIC based on the new policy CMP0100 setting. Fixes: #13904 CMAKE_AUTOMOC misses headers with ".hh" extension
This commit is contained in:
@@ -57,6 +57,7 @@ Policies Introduced by CMake 3.17
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100>
|
||||
CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099>
|
||||
CMP0098: FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing. </policy/CMP0098>
|
||||
|
||||
|
||||
40
Help/policy/CMP0100.rst
Normal file
40
Help/policy/CMP0100.rst
Normal file
@@ -0,0 +1,40 @@
|
||||
CMP0100
|
||||
-------
|
||||
|
||||
Let :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` process
|
||||
header files that end with a ``.hh`` extension.
|
||||
|
||||
Since version 3.17, CMake processes header files that end with a
|
||||
``.hh`` extension in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
|
||||
In earlier CMake versions, these header files were ignored by
|
||||
:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
|
||||
|
||||
This policy affects how header files that end with a ``.hh`` extension
|
||||
get treated in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
|
||||
|
||||
The ``OLD`` behavior for this policy is to ignore ``.hh`` header files
|
||||
in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
|
||||
|
||||
The ``NEW`` behavior for this policy is to process ``.hh`` header files
|
||||
in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` just like other header files.
|
||||
|
||||
.. note::
|
||||
|
||||
To silence the ``CMP0100`` warning source files can be excluded from
|
||||
:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` processing by setting the
|
||||
source file properties :prop_sf:`SKIP_AUTOMOC`, :prop_sf:`SKIP_AUTOUIC` or
|
||||
:prop_sf:`SKIP_AUTOGEN`.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
# Source skip example:
|
||||
set_property(SOURCE /path/to/file1.hh PROPERTY SKIP_AUTOMOC ON)
|
||||
set_property(SOURCE /path/to/file2.hh PROPERTY SKIP_AUTOUIC ON)
|
||||
set_property(SOURCE /path/to/file3.hh PROPERTY SKIP_AUTOGEN ON)
|
||||
|
||||
This policy was introduced in CMake version 3.17.0. CMake version
|
||||
|release| warns when the policy is not set and uses ``OLD`` behavior.
|
||||
Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW``
|
||||
explicitly.
|
||||
|
||||
.. include:: DEPRECATED.txt
|
||||
6
Help/release/dev/autogen_hh_headers.rst
Normal file
6
Help/release/dev/autogen_hh_headers.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
autogen_hh_headers
|
||||
------------------
|
||||
|
||||
* :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` learned to process headers with
|
||||
a ``.hh`` extension. The new behavior is enabled by policy
|
||||
:policy:`CMP0100`.
|
||||
@@ -297,7 +297,9 @@ class cmMakefile;
|
||||
SELECT(POLICY, CMP0099, \
|
||||
"Link properties are transitive over private dependency on static " \
|
||||
"libraries.", \
|
||||
3, 17, 0, cmPolicies::WARN)
|
||||
3, 17, 0, cmPolicies::WARN) \
|
||||
SELECT(POLICY, CMP0100, "Let AUTOMOC and AUTOUIC process .hh files.", 3, \
|
||||
17, 0, cmPolicies::WARN)
|
||||
|
||||
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
|
||||
#define CM_FOR_EACH_POLICY_ID(POLICY) \
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "cmSourceGroup.h"
|
||||
#include "cmState.h"
|
||||
#include "cmStateTypes.h"
|
||||
#include "cmString.hxx"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
@@ -354,24 +355,38 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
|
||||
}
|
||||
}
|
||||
|
||||
// Check status of policy CMP0071
|
||||
{
|
||||
cmPolicies::PolicyStatus const CMP0071_status =
|
||||
this->Makefile->GetPolicyStatus(cmPolicies::CMP0071);
|
||||
switch (CMP0071_status) {
|
||||
case cmPolicies::WARN:
|
||||
this->CMP0071Warn = true;
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
// Ignore GENERATED file
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// Process GENERATED file
|
||||
this->CMP0071Accept = true;
|
||||
break;
|
||||
}
|
||||
// Check status of policy CMP0071 regarding handling of GENERATED files
|
||||
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0071)) {
|
||||
case cmPolicies::WARN:
|
||||
// Ignore GENERATED files but warn
|
||||
this->CMP0071Warn = true;
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
// Ignore GENERATED files
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// Process GENERATED files
|
||||
this->CMP0071Accept = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check status of policy CMP0100 regarding handling of .hh headers
|
||||
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0100)) {
|
||||
case cmPolicies::WARN:
|
||||
// Ignore but .hh files but warn
|
||||
this->CMP0100Warn = true;
|
||||
CM_FALLTHROUGH;
|
||||
case cmPolicies::OLD:
|
||||
// Ignore .hh files
|
||||
break;
|
||||
case cmPolicies::REQUIRED_IF_USED:
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// Process .hh file
|
||||
this->CMP0100Accept = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Common directories
|
||||
@@ -733,15 +748,26 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
return muf;
|
||||
};
|
||||
|
||||
auto addMUFile = [&](MUFileHandle&& muf, bool isHeader) {
|
||||
auto addMUHeader = [this](MUFileHandle&& muf, cm::string_view extension) {
|
||||
cmSourceFile* sf = muf->SF;
|
||||
const bool muIt = (muf->MocIt || muf->UicIt);
|
||||
if (this->CMP0100Accept || (extension != "hh")) {
|
||||
// Accept
|
||||
if (muIt && muf->Generated) {
|
||||
this->AutogenTarget.FilesGenerated.emplace_back(muf.get());
|
||||
}
|
||||
this->AutogenTarget.Headers.emplace(sf, std::move(muf));
|
||||
} else if (muIt && this->CMP0100Warn) {
|
||||
// Store file for warning message
|
||||
this->AutogenTarget.CMP0100HeadersWarn.push_back(sf);
|
||||
}
|
||||
};
|
||||
|
||||
auto addMUSource = [this](MUFileHandle&& muf) {
|
||||
if ((muf->MocIt || muf->UicIt) && muf->Generated) {
|
||||
this->AutogenTarget.FilesGenerated.emplace_back(muf.get());
|
||||
}
|
||||
if (isHeader) {
|
||||
this->AutogenTarget.Headers.emplace(muf->SF, std::move(muf));
|
||||
} else {
|
||||
this->AutogenTarget.Sources.emplace(muf->SF, std::move(muf));
|
||||
}
|
||||
this->AutogenTarget.Sources.emplace(muf->SF, std::move(muf));
|
||||
};
|
||||
|
||||
// Scan through target files
|
||||
@@ -763,11 +789,10 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
|
||||
// Register files that will be scanned by moc or uic
|
||||
if (this->MocOrUicEnabled()) {
|
||||
// FIXME: Add a policy to include .hh files.
|
||||
if (cm->IsHeaderExtension(extLower) && extLower != "hh") {
|
||||
addMUFile(makeMUFile(sf, fullPath, true), true);
|
||||
if (cm->IsHeaderExtension(extLower)) {
|
||||
addMUHeader(makeMUFile(sf, fullPath, true), extLower);
|
||||
} else if (cm->IsSourceExtension(extLower)) {
|
||||
addMUFile(makeMUFile(sf, fullPath, true), false);
|
||||
addMUSource(makeMUFile(sf, fullPath, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,8 +826,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
|
||||
// For source files find additional headers and private headers
|
||||
if (this->MocOrUicEnabled()) {
|
||||
std::vector<MUFileHandle> extraHeaders;
|
||||
extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2);
|
||||
// Header search suffixes and extensions
|
||||
static std::initializer_list<cm::string_view> const suffixes{ "", "_p" };
|
||||
auto const& exts = cm->GetHeaderExtensions();
|
||||
@@ -847,16 +870,12 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
if (!muf.UicIt) {
|
||||
eMuf->UicIt = false;
|
||||
}
|
||||
extraHeaders.emplace_back(std::move(eMuf));
|
||||
addMUHeader(std::move(eMuf), ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Move generated files to main headers list
|
||||
for (auto& eMuf : extraHeaders) {
|
||||
addMUFile(std::move(eMuf), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Scan through all source files in the makefile to extract moc and uic
|
||||
@@ -876,19 +895,18 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
std::string const& extLower =
|
||||
cmSystemTools::LowerCase(sf->GetExtension());
|
||||
|
||||
// FIXME: Add a policy to include .hh files.
|
||||
if (cm->IsHeaderExtension(extLower) && extLower != "hh") {
|
||||
if (cm->IsHeaderExtension(extLower)) {
|
||||
if (!cmContains(this->AutogenTarget.Headers, sf)) {
|
||||
auto muf = makeMUFile(sf, fullPath, false);
|
||||
if (muf->SkipMoc || muf->SkipUic) {
|
||||
this->AutogenTarget.Headers.emplace(sf, std::move(muf));
|
||||
addMUHeader(std::move(muf), extLower);
|
||||
}
|
||||
}
|
||||
} else if (cm->IsSourceExtension(extLower)) {
|
||||
if (!cmContains(this->AutogenTarget.Headers, sf)) {
|
||||
if (!cmContains(this->AutogenTarget.Sources, sf)) {
|
||||
auto muf = makeMUFile(sf, fullPath, false);
|
||||
if (muf->SkipMoc || muf->SkipUic) {
|
||||
this->AutogenTarget.Sources.emplace(sf, std::move(muf));
|
||||
addMUSource(std::move(muf));
|
||||
}
|
||||
}
|
||||
} else if (this->Uic.Enabled && (extLower == kw.ui)) {
|
||||
@@ -946,6 +964,35 @@ bool cmQtAutoGenInitializer::InitScanFiles()
|
||||
}
|
||||
}
|
||||
|
||||
// Generate CMP0100 warning
|
||||
if (this->MocOrUicEnabled() &&
|
||||
!this->AutogenTarget.CMP0100HeadersWarn.empty()) {
|
||||
cm::string_view property;
|
||||
if (this->Moc.Enabled && this->Uic.Enabled) {
|
||||
property = "SKIP_AUTOGEN";
|
||||
} else if (this->Moc.Enabled) {
|
||||
property = "SKIP_AUTOMOC";
|
||||
} else if (this->Uic.Enabled) {
|
||||
property = "SKIP_AUTOUIC";
|
||||
}
|
||||
std::string files;
|
||||
for (cmSourceFile* sf : this->AutogenTarget.CMP0100HeadersWarn) {
|
||||
files += cmStrCat(" ", Quoted(sf->GetFullPath()), '\n');
|
||||
}
|
||||
this->Makefile->IssueMessage(
|
||||
MessageType::AUTHOR_WARNING,
|
||||
cmStrCat(
|
||||
cmPolicies::GetPolicyWarning(cmPolicies::CMP0100), '\n',
|
||||
"For compatibility, CMake is excluding the header file(s):\n", files,
|
||||
"from processing by ",
|
||||
cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false),
|
||||
". If any of the files should be processed, set CMP0100 to NEW. "
|
||||
"If any of the files should not be processed, "
|
||||
"explicitly exclude them by setting the source file property ",
|
||||
property, ":\n set_property(SOURCE file.hh PROPERTY ", property,
|
||||
" ON)\n"));
|
||||
}
|
||||
|
||||
// Process qrc files
|
||||
if (!this->Rcc.Qrcs.empty()) {
|
||||
const bool modernQt = (this->QtVersion.Major >= 5);
|
||||
|
||||
@@ -159,6 +159,8 @@ private:
|
||||
bool MultiConfig = false;
|
||||
bool CMP0071Accept = false;
|
||||
bool CMP0071Warn = false;
|
||||
bool CMP0100Accept = false;
|
||||
bool CMP0100Warn = false;
|
||||
std::string ConfigDefault;
|
||||
std::vector<std::string> ConfigsList;
|
||||
std::string TargetsFolder;
|
||||
@@ -192,6 +194,7 @@ private:
|
||||
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
|
||||
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
|
||||
std::vector<MUFile*> FilesGenerated;
|
||||
std::vector<cmSourceFile*> CMP0100HeadersWarn;
|
||||
} AutogenTarget;
|
||||
|
||||
/** moc variables. */
|
||||
|
||||
Reference in New Issue
Block a user