summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2017-02-15 18:19:37 (GMT)
committerBrad King <brad.king@kitware.com>2017-02-21 15:12:51 (GMT)
commit815a05cf12499b42acea70b5a9534e10e1701417 (patch)
tree62f6e647e22600e510582427287438bf2dd00a3b
parent3270091210c0cfdddb133209b232a1d0a1fa48da (diff)
downloadCMake-815a05cf12499b42acea70b5a9534e10e1701417.zip
CMake-815a05cf12499b42acea70b5a9534e10e1701417.tar.gz
CMake-815a05cf12499b42acea70b5a9534e10e1701417.tar.bz2
Autogen: Overhaul FindMatchingHeader function
-rw-r--r--Source/cmQtAutoGenerators.cxx147
-rw-r--r--Source/cmQtAutoGenerators.h7
2 files changed, 83 insertions, 71 deletions
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 580265b..97d1299 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -74,42 +74,6 @@ static void SettingWrite(std::ostream& ostr, const char* key,
}
}
-static std::string FindMatchingHeader(
- const std::string& absPath, const std::string& mocSubDir,
- const std::string& basename,
- const std::vector<std::string>& headerExtensions)
-{
- std::string header;
- for (std::vector<std::string>::const_iterator ext = headerExtensions.begin();
- ext != headerExtensions.end(); ++ext) {
- std::string sourceFilePath = absPath + basename + "." + (*ext);
- if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) {
- header = sourceFilePath;
- break;
- }
- // Try subdirectory instead
- if (!mocSubDir.empty()) {
- sourceFilePath = mocSubDir + basename + "." + (*ext);
- if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) {
- header = sourceFilePath;
- break;
- }
- }
- }
-
- return header;
-}
-
-static std::string ExtractSubDir(const std::string& absPath,
- const std::string& currentMoc)
-{
- std::string subDir;
- if (currentMoc.find_first_of('/') != std::string::npos) {
- subDir = absPath + cmsys::SystemTools::GetFilenamePath(currentMoc) + '/';
- }
- return subDir;
-}
-
static bool FileNameIsUnique(const std::string& filePath,
const std::map<std::string, std::string>& fileMap)
{
@@ -807,38 +771,38 @@ bool cmQtAutoGenerators::ParseContentForMoc(
if (strstr(contentChars, "moc") != CM_NULLPTR) {
// Iterate over all included moc files
while (this->RegExpMocInclude.find(contentChars)) {
- const std::string currentMoc = this->RegExpMocInclude.match(1);
- // Basename of the current moc include
- std::string basename =
- cmsys::SystemTools::GetFilenameWithoutLastExtension(currentMoc);
+ const std::string incString = this->RegExpMocInclude.match(1);
+ // Basename of the moc include
+ const std::string incBasename =
+ cmsys::SystemTools::GetFilenameWithoutLastExtension(incString);
+ std::string incSubDir;
+ if (incString.find_first_of('/') != std::string::npos) {
+ incSubDir = cmsys::SystemTools::GetFilenamePath(incString) + '/';
+ }
// If the moc include is of the moc_foo.cpp style we expect
// the Q_OBJECT class declaration in a header file.
// If the moc include is of the foo.moc style we need to look for
// a Q_OBJECT macro in the current source file, if it contains the
// macro we generate the moc file from the source file.
- if (cmHasLiteralPrefix(basename, "moc_")) {
+ if (cmHasLiteralPrefix(incBasename, "moc_")) {
// Include: moc_FOO.cxx
- // basename should be the part of the moc filename used for
- // finding the correct header, so we need to remove the moc_ part
- basename = basename.substr(4);
- const std::string mocSubDir =
- ExtractSubDir(scannedFileAbsPath, currentMoc);
+ // Remove the moc_ part
+ const std::string incRealBasename = incBasename.substr(4);
const std::string headerToMoc = FindMatchingHeader(
- scannedFileAbsPath, mocSubDir, basename, headerExtensions);
-
+ scannedFileAbsPath, incRealBasename, incSubDir, headerExtensions);
if (!headerToMoc.empty()) {
- mocsIncluded[headerToMoc] = currentMoc;
- if (relaxed && (basename == scannedFileBasename)) {
+ mocsIncluded[headerToMoc] = incString;
+ if (relaxed && (incRealBasename == scannedFileBasename)) {
ownMocUnderscoreIncluded = true;
- ownMocUnderscoreFile = currentMoc;
+ ownMocUnderscoreFile = incString;
ownMocHeaderFile = headerToMoc;
}
} else {
std::ostringstream err;
err << "AutoMoc: Error: " << absFilename << "\n"
- << "The file includes the moc file \"" << currentMoc
- << "\", but could not find header \"" << basename << '{'
+ << "The file includes the moc file \"" << incString
+ << "\", but could not find header \"" << incRealBasename << '{'
<< JoinExts(headerExtensions) << "}\"\n";
this->LogError(err.str());
return false;
@@ -848,31 +812,31 @@ bool cmQtAutoGenerators::ParseContentForMoc(
std::string fileToMoc;
if (relaxed) {
// Mode: Relaxed
- if (!requiresMoc || basename != scannedFileBasename) {
- const std::string mocSubDir =
- ExtractSubDir(scannedFileAbsPath, currentMoc);
+ if (!requiresMoc || (incBasename != scannedFileBasename)) {
const std::string headerToMoc = FindMatchingHeader(
- scannedFileAbsPath, mocSubDir, basename, headerExtensions);
+ scannedFileAbsPath, incBasename, incSubDir, headerExtensions);
if (!headerToMoc.empty()) {
// This is for KDE4 compatibility:
fileToMoc = headerToMoc;
- if (!requiresMoc && basename == scannedFileBasename) {
+ if (!requiresMoc && (incBasename == scannedFileBasename)) {
std::ostringstream err;
err << "AutoMoc: Warning: " << absFilename << "\n"
- << "The file includes the moc file \"" << currentMoc
+ << "The file includes the moc file \"" << incString
<< "\", but does not contain a " << macroName
<< " macro. Running moc on "
- << "\"" << headerToMoc << "\" ! Include \"moc_" << basename
+ << "\"" << headerToMoc << "\" ! Include \"moc_"
+ << incBasename
<< ".cpp\" for a compatibility with "
"strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n";
this->LogWarning(err.str());
} else {
std::ostringstream err;
err << "AutoMoc: Warning: " << absFilename << "\n"
- << "The file includes the moc file \"" << currentMoc
- << "\" instead of \"moc_" << basename
+ << "The file includes the moc file \"" << incString
+ << "\" instead of \"moc_" << incBasename
<< ".cpp\". Running moc on "
- << "\"" << headerToMoc << "\" ! Include \"moc_" << basename
+ << "\"" << headerToMoc << "\" ! Include \"moc_"
+ << incBasename
<< ".cpp\" for compatibility with "
"strict mode (see CMAKE_AUTOMOC_RELAXED_MODE).\n";
this->LogWarning(err.str());
@@ -880,7 +844,7 @@ bool cmQtAutoGenerators::ParseContentForMoc(
} else {
std::ostringstream err;
err << "AutoMoc: Error: " << absFilename << "\n"
- << "The file includes the moc file \"" << currentMoc
+ << "The file includes the moc file \"" << incString
<< "\", which seems to be the moc file from a different "
"source file. CMake also could not find a matching "
"header.\n";
@@ -894,7 +858,7 @@ bool cmQtAutoGenerators::ParseContentForMoc(
}
} else {
// Mode: Strict
- if (basename == scannedFileBasename) {
+ if (incBasename == scannedFileBasename) {
// Include self
fileToMoc = absFilename;
ownDotMocIncluded = true;
@@ -902,7 +866,7 @@ bool cmQtAutoGenerators::ParseContentForMoc(
// Don't allow FOO.moc include other than self in strict mode
std::ostringstream err;
err << "AutoMoc: Error: " << absFilename << "\n"
- << "The file includes the moc file \"" << currentMoc
+ << "The file includes the moc file \"" << incString
<< "\", which seems to be the moc file from a different "
"source file. This is not supported. Include \""
<< scannedFileBasename
@@ -912,7 +876,7 @@ bool cmQtAutoGenerators::ParseContentForMoc(
}
}
if (!fileToMoc.empty()) {
- mocsIncluded[fileToMoc] = currentMoc;
+ mocsIncluded[fileToMoc] = incString;
}
}
// Forward content pointer
@@ -920,11 +884,11 @@ bool cmQtAutoGenerators::ParseContentForMoc(
}
}
- // In this case, check whether the scanned file itself contains a Q_OBJECT.
- // If this is the case, the moc_foo.cpp should probably be generated from
- // foo.cpp instead of foo.h, because otherwise it won't build.
- // But warn, since this is not how it is supposed to be used.
if (requiresMoc && !ownDotMocIncluded) {
+ // In this case, check whether the scanned file itself contains a Q_OBJECT.
+ // If this is the case, the moc_foo.cpp should probably be generated from
+ // foo.cpp instead of foo.h, because otherwise it won't build.
+ // But warn, since this is not how it is supposed to be used.
if (relaxed && ownMocUnderscoreIncluded) {
// This is for KDE4 compatibility:
std::ostringstream err;
@@ -1620,6 +1584,47 @@ std::string cmQtAutoGenerators::ChecksumedPath(const std::string& sourceFile,
}
/**
+ * @brief Tries to find the header file to the given file base path by
+ * appending different header extensions
+ * @return True on success
+ */
+bool cmQtAutoGenerators::FindHeader(
+ std::string& header, const std::string& testBasePath,
+ const std::vector<std::string>& headerExtensions) const
+{
+ for (std::vector<std::string>::const_iterator ext = headerExtensions.begin();
+ ext != headerExtensions.end(); ++ext) {
+ std::string testFilePath(testBasePath);
+ testFilePath += '.';
+ testFilePath += (*ext);
+ if (cmsys::SystemTools::FileExists(testFilePath.c_str())) {
+ header = testFilePath;
+ return true;
+ }
+ }
+ return false;
+}
+
+std::string cmQtAutoGenerators::FindMatchingHeader(
+ const std::string& basePath, const std::string& baseName,
+ const std::string& subDir,
+ const std::vector<std::string>& headerExtensions) const
+{
+ std::string header;
+ do {
+ if (!subDir.empty()) {
+ if (FindHeader(header, basePath + subDir + baseName, headerExtensions)) {
+ break;
+ }
+ }
+ if (FindHeader(header, basePath + baseName, headerExtensions)) {
+ break;
+ }
+ } while (false);
+ return header;
+}
+
+/**
* @brief Generates the parent directory of the given file on demand
* @return True on success
*/
diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h
index a466b77..50df9f8 100644
--- a/Source/cmQtAutoGenerators.h
+++ b/Source/cmQtAutoGenerators.h
@@ -119,6 +119,13 @@ private:
const char* baseSuffix) const;
bool MakeParentDirectory(const std::string& filename);
+ bool FindHeader(std::string& header, const std::string& testBasePath,
+ const std::vector<std::string>& headerExtensions) const;
+ std::string FindMatchingHeader(
+ const std::string& basePath, const std::string& baseName,
+ const std::string& subDir,
+ const std::vector<std::string>& headerExtensions) const;
+
// - Target names
std::string OriginTargetName;
std::string AutogenTargetName;