summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2019-09-13 13:17:24 (GMT)
committerSebastian Holtermann <sebholt@xwmw.org>2019-09-16 16:18:48 (GMT)
commitd018d27c101869e4e2449f938df89d4f97c5b73c (patch)
tree11778bf70bbbaad961178c5adccb1a090390a10c /Source
parent77983c814725317e990315be8bc8d5b93fa6ffbd (diff)
downloadCMake-d018d27c101869e4e2449f938df89d4f97c5b73c.zip
CMake-d018d27c101869e4e2449f938df89d4f97c5b73c.tar.gz
CMake-d018d27c101869e4e2449f938df89d4f97c5b73c.tar.bz2
Autogen: Add moc path prefix generation (AUTOMOC_PATH_PREFIX)
The new `AUTOMOC_PATH_PREFIX` boolean target property enables automatic generation of the path prefix `-p` option for `moc`. `AUTOMOC_PATH_PREFIX` is initialized from the variable `CMAKE_AUTOMOC_PATH_PREFIX`, which is ON by default. When `AUTOMOC_PATH_PREFIX` is enabled, CMake tests if a `moc`ed header file is in one of the include directories. If so, then the `-p` option, with the relative path of the header parent directory to the respective include directory, is added to the `moc` command. If the header file is not in an include directory, the `-p` option is omitted. Closes: #18815 "AUTOMOC: generated files include full relative path, breaking certain reproducible builds"
Diffstat (limited to 'Source')
-rw-r--r--Source/cmQtAutoGenInitializer.cxx2
-rw-r--r--Source/cmQtAutoMocUic.cxx110
-rw-r--r--Source/cmQtAutoMocUic.h7
-rw-r--r--Source/cmTarget.cxx1
4 files changed, 83 insertions, 37 deletions
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 89ef588..1404554 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1376,6 +1376,8 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
ofs.Write("AM_MOC_OPTIONS",
this->GenTarget->GetSafeProperty("AUTOMOC_MOC_OPTIONS"));
ofs.Write("AM_MOC_RELAXED_MODE", MfDef("CMAKE_AUTOMOC_RELAXED_MODE"));
+ ofs.Write("AM_MOC_PATH_PREFIX",
+ this->GenTarget->GetSafeProperty("AUTOMOC_PATH_PREFIX"));
ofs.Write("AM_MOC_MACRO_NAMES",
this->GenTarget->GetSafeProperty("AUTOMOC_MACRO_NAMES"));
ofs.Write("AM_MOC_DEPEND_FILTERS",
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 7d6ad47..4e4875e 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -279,12 +279,10 @@ void cmQtAutoMocUic::JobMocPredefsT::Process()
{
// Compose command
std::vector<std::string> cmd = MocConst().PredefsCmd;
- // Add includes
- cmAppend(cmd, MocConst().Includes);
// Add definitions
- for (std::string const& def : MocConst().Definitions) {
- cmd.emplace_back("-D" + def);
- }
+ cmAppend(cmd, MocConst().OptionsDefinitions);
+ // Add includes
+ cmAppend(cmd, MocConst().OptionsIncludes);
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
LogCommandError(GenT::MOC,
@@ -1385,17 +1383,50 @@ void cmQtAutoMocUic::JobCompileMocT::Process()
// Compose moc command
std::vector<std::string> cmd;
- cmd.push_back(MocConst().Executable);
- // Add options
- cmAppend(cmd, MocConst().AllOptions);
- // Add predefs include
- if (!MocConst().PredefsFileAbs.empty()) {
- cmd.emplace_back("--include");
- cmd.push_back(MocConst().PredefsFileAbs);
+ {
+ // Reserve large enough
+ cmd.reserve(MocConst().OptionsDefinitions.size() +
+ MocConst().OptionsIncludes.size() +
+ MocConst().OptionsExtra.size() + 16);
+ cmd.push_back(MocConst().Executable);
+ // Add definitions
+ cmAppend(cmd, MocConst().OptionsDefinitions);
+ // Add includes
+ cmAppend(cmd, MocConst().OptionsIncludes);
+ // Add predefs include
+ if (!MocConst().PredefsFileAbs.empty()) {
+ cmd.emplace_back("--include");
+ cmd.push_back(MocConst().PredefsFileAbs);
+ }
+ // Add path prefix on demand
+ if (MocConst().PathPrefix && Mapping->SourceFile->IsHeader) {
+ for (std::string const& dir : MocConst().IncludePaths) {
+ cm::string_view prefix = sourceFile;
+ if (cmHasPrefix(prefix, dir)) {
+ prefix.remove_prefix(dir.size());
+ if (cmHasPrefix(prefix, '/')) {
+ prefix.remove_prefix(1);
+ auto slashPos = prefix.rfind('/');
+ if (slashPos != cm::string_view::npos) {
+ cmd.emplace_back("-p");
+ cmd.emplace_back(prefix.substr(0, slashPos));
+ } else {
+ cmd.emplace_back("-p");
+ cmd.emplace_back("./");
+ }
+ break;
+ }
+ }
+ }
+ }
+ // Add extra options
+ cmAppend(cmd, MocConst().OptionsExtra);
+ // Add output file
+ cmd.emplace_back("-o");
+ cmd.push_back(outputFile);
+ // Add source file
+ cmd.push_back(sourceFile);
}
- cmd.emplace_back("-o");
- cmd.push_back(outputFile);
- cmd.push_back(sourceFile);
// Execute moc command
cmWorkerPool::ProcessResultT result;
@@ -1654,8 +1685,11 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
}
MocConst_.Definitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
MocConst_.IncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
- MocConst_.Options = InfoGetList("AM_MOC_OPTIONS");
+ MocConst_.OptionsExtra = InfoGetList("AM_MOC_OPTIONS");
+
MocConst_.RelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
+ MocConst_.PathPrefix = InfoGetBool("AM_MOC_PATH_PREFIX");
+
for (std::string const& item : InfoGetList("AM_MOC_MACRO_NAMES")) {
MocConst_.MacroFilters.emplace_back(
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
@@ -1846,9 +1880,9 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
// Compose moc includes list
{
+ // Compute framework paths
std::set<std::string> frameworkPaths;
for (std::string const& path : MocConst().IncludePaths) {
- MocConst_.Includes.push_back("-I" + path);
// Extract framework path
if (cmHasLiteralSuffix(path, ".framework/Headers")) {
// Go up twice to get to the framework root
@@ -1858,26 +1892,26 @@ bool cmQtAutoMocUic::Init(cmMakefile* makefile)
pathComponents.begin(), pathComponents.end() - 2));
}
}
+ // Reserve options
+ MocConst_.OptionsIncludes.reserve(MocConst().IncludePaths.size() +
+ frameworkPaths.size() * 2);
+ // Append includes
+ for (std::string const& path : MocConst().IncludePaths) {
+ MocConst_.OptionsIncludes.emplace_back("-I" + path);
+ }
// Append framework includes
for (std::string const& path : frameworkPaths) {
- MocConst_.Includes.emplace_back("-F");
- MocConst_.Includes.push_back(path);
+ MocConst_.OptionsIncludes.emplace_back("-F");
+ MocConst_.OptionsIncludes.push_back(path);
}
}
- // Setup single list with all options
+
+ // Compose moc definitions list
{
- // Add includes
- MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
- MocConst().Includes.begin(),
- MocConst().Includes.end());
- // Add definitions
+ MocConst_.OptionsDefinitions.reserve(MocConst().Definitions.size());
for (std::string const& def : MocConst().Definitions) {
- MocConst_.AllOptions.push_back("-D" + def);
+ MocConst_.OptionsDefinitions.emplace_back("-D" + def);
}
- // Add options
- MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
- MocConst().Options.begin(),
- MocConst().Options.end());
}
}
@@ -1971,10 +2005,18 @@ void cmQtAutoMocUic::SettingsFileRead()
if (MocConst_.Enabled) {
cryptoHash.Initialize();
cha(MocConst().Executable);
- std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(),
- cha);
- std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(),
- cha);
+ for (auto const& item : MocConst().OptionsDefinitions) {
+ cha(item);
+ }
+ for (auto const& item : MocConst().OptionsIncludes) {
+ cha(item);
+ }
+ for (auto const& item : MocConst().OptionsExtra) {
+ cha(item);
+ }
+ for (auto const& item : MocConst().PredefsCmd) {
+ cha(item);
+ }
for (auto const& filter : MocConst().DependFilters) {
cha(filter.Key);
}
diff --git a/Source/cmQtAutoMocUic.h b/Source/cmQtAutoMocUic.h
index 71cd5f5..43123f2 100644
--- a/Source/cmQtAutoMocUic.h
+++ b/Source/cmQtAutoMocUic.h
@@ -212,16 +212,17 @@ public:
bool Enabled = false;
bool SettingsChanged = false;
bool RelaxedMode = false;
+ bool PathPrefix = false;
cmFileTime ExecutableTime;
std::string Executable;
std::string CompFileAbs;
std::string PredefsFileAbs;
std::unordered_set<std::string> SkipList;
std::vector<std::string> IncludePaths;
- std::vector<std::string> Includes;
std::vector<std::string> Definitions;
- std::vector<std::string> Options;
- std::vector<std::string> AllOptions;
+ std::vector<std::string> OptionsIncludes;
+ std::vector<std::string> OptionsDefinitions;
+ std::vector<std::string> OptionsExtra;
std::vector<std::string> PredefsCmd;
std::vector<KeyExpT> DependFilters;
std::vector<KeyExpT> MacroFilters;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 6637e32..86873ed 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -312,6 +312,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("AUTOMOC_MACRO_NAMES");
initProp("AUTOMOC_MOC_OPTIONS");
initProp("AUTOUIC_OPTIONS");
+ initProp("AUTOMOC_PATH_PREFIX");
initProp("AUTOUIC_SEARCH_PATHS");
initProp("AUTORCC_OPTIONS");
initProp("LINK_DEPENDS_NO_SHARED");