This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "CMake".
The branch, next has been updated via 356a3f60095d1f5132f590833737fed4db766580 (commit) via 971ed4b2e00015f7d848cdd8140ff8fa8de81a3d (commit) via 77ea7ee6dbc7c3be7870432a68dbff9747201768 (commit) via 6bb656e760f07958a47c14aa730f792b9ec48cb4 (commit) via 2d2b6da3b6f238947eade0755b32309baa1d6539 (commit) via 191c41b31463b0ea3f633d5e0d10d6239380b0ff (commit) via 7b824667604b3abc89e3562587a0ced0acd4891f (commit) via da61ea9bc515b8286dcfbe0e3e62fca4cef8b3b0 (commit) from efa58e5e4cc5107eb06ecd85fd160630c986b53d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=356a3f60095d1f5132f590833737fed4db766580 commit 356a3f60095d1f5132f590833737fed4db766580 Merge: efa58e5 971ed4b Author: Brad King <brad.k...@kitware.com> AuthorDate: Wed Apr 20 13:37:32 2016 -0400 Commit: CMake Topic Stage <kwro...@kitware.com> CommitDate: Wed Apr 20 13:37:32 2016 -0400 Merge topic 'autogen-updates' into next 971ed4b2 Tests: QtAutogen: Same source name in different directories test 77ea7ee6 Autogen: Generate qrc_NAME.cpp files in subdirectories (#16068) 6bb656e7 Autogen: Generate not included moc files in subdirectories (#12873) 2d2b6da3 Autogen: Check added for name collisions of generated qrc_NAME.cpp files 191c41b3 Autogen: Check added for name collisions of generated ui_NAME.h files 7b824667 Autogen: Check added for name collisions of generated moc files da61ea9b Help: Improve AUTOMOC documentation layout https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=971ed4b2e00015f7d848cdd8140ff8fa8de81a3d commit 971ed4b2e00015f7d848cdd8140ff8fa8de81a3d Author: Sebastian Holtermann <sebh...@xwmw.org> AuthorDate: Wed Apr 13 18:36:39 2016 +0200 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Tests: QtAutogen: Same source name in different directories test The test features multiple .cpp and .qrc files with the same name in different subdirectories. This requires AUTOMOC and AUTORCC to generate files with names that respect the path information of the source files. diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index d5aca55..4875165 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -110,6 +110,10 @@ set_target_properties( AUTOMOC TRUE ) +# Test AUTOMOC and AUTORCC on source files with the same name +# but in different subdirectories +add_subdirectory(same_name) + include(GenerateExportHeader) # The order is relevant here. B depends on A, and B headers depend on A # headers both subdirectories use CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE and we diff --git a/Tests/QtAutogen/same_name/CMakeLists.txt b/Tests/QtAutogen/same_name/CMakeLists.txt new file mode 100644 index 0000000..54bf048 --- /dev/null +++ b/Tests/QtAutogen/same_name/CMakeLists.txt @@ -0,0 +1,20 @@ +# Test AUTOMOC and AUTORCC on source files with the same name +# but in different subdirectories + +add_executable(same_name + aaa/bbb/item.cpp + aaa/bbb/data.qrc + aaa/item.cpp + aaa/data.qrc + bbb/aaa/item.cpp + bbb/aaa/data.qrc + bbb/item.cpp + bbb/data.qrc + ccc/item.cpp + ccc/data.qrc + main.cpp + data.qrc +) +target_include_directories(same_name PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(same_name ${QT_LIBRARIES}) +set_target_properties( same_name PROPERTIES AUTOMOC TRUE AUTORCC TRUE ) diff --git a/Tests/QtAutogen/same_name/aaa/bbb/data.qrc b/Tests/QtAutogen/same_name/aaa/bbb/data.qrc new file mode 100644 index 0000000..0ea3537 --- /dev/null +++ b/Tests/QtAutogen/same_name/aaa/bbb/data.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="aaa/bbb"> + <file>item.hpp</file> + <file>item.cpp</file> +</qresource> +</RCC> diff --git a/Tests/QtAutogen/same_name/aaa/bbb/item.cpp b/Tests/QtAutogen/same_name/aaa/bbb/item.cpp new file mode 100644 index 0000000..d715116 --- /dev/null +++ b/Tests/QtAutogen/same_name/aaa/bbb/item.cpp @@ -0,0 +1,12 @@ +#include "item.hpp" + +namespace aaa { +namespace bbb { + +void +Item::go ( ) +{ +} + +} +} diff --git a/Tests/QtAutogen/same_name/aaa/bbb/item.hpp b/Tests/QtAutogen/same_name/aaa/bbb/item.hpp new file mode 100644 index 0000000..c82309d --- /dev/null +++ b/Tests/QtAutogen/same_name/aaa/bbb/item.hpp @@ -0,0 +1,19 @@ +#ifndef SDA_SDB_ITEM_HPP +#define SDA_SDB_ITEM_HPP + +#include <QObject> + +namespace aaa { +namespace bbb { + +class Item : public QObject +{ + Q_OBJECT + Q_SLOT + void go ( ); +}; + +} +} + +#endif diff --git a/Tests/QtAutogen/same_name/aaa/data.qrc b/Tests/QtAutogen/same_name/aaa/data.qrc new file mode 100644 index 0000000..379af60 --- /dev/null +++ b/Tests/QtAutogen/same_name/aaa/data.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="aaa/"> + <file>item.hpp</file> + <file>item.cpp</file> +</qresource> +</RCC> diff --git a/Tests/QtAutogen/same_name/aaa/item.cpp b/Tests/QtAutogen/same_name/aaa/item.cpp new file mode 100644 index 0000000..7887d76 --- /dev/null +++ b/Tests/QtAutogen/same_name/aaa/item.cpp @@ -0,0 +1,10 @@ +#include "item.hpp" + +namespace aaa { + +void +Item::go ( ) +{ +} + +} diff --git a/Tests/QtAutogen/same_name/aaa/item.hpp b/Tests/QtAutogen/same_name/aaa/item.hpp new file mode 100644 index 0000000..3c24275 --- /dev/null +++ b/Tests/QtAutogen/same_name/aaa/item.hpp @@ -0,0 +1,17 @@ +#ifndef SDA_ITEM_HPP +#define SDA_ITEM_HPP + +#include <QObject> + +namespace aaa { + +class Item : public QObject +{ + Q_OBJECT + Q_SLOT + void go ( ); +}; + +} + +#endif diff --git a/Tests/QtAutogen/same_name/bbb/aaa/data.qrc b/Tests/QtAutogen/same_name/bbb/aaa/data.qrc new file mode 100644 index 0000000..da98009 --- /dev/null +++ b/Tests/QtAutogen/same_name/bbb/aaa/data.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="bbb/aaa/"> + <file>item.hpp</file> + <file>item.cpp</file> +</qresource> +</RCC> diff --git a/Tests/QtAutogen/same_name/bbb/aaa/item.cpp b/Tests/QtAutogen/same_name/bbb/aaa/item.cpp new file mode 100644 index 0000000..36d5b6d --- /dev/null +++ b/Tests/QtAutogen/same_name/bbb/aaa/item.cpp @@ -0,0 +1,12 @@ +#include "item.hpp" + +namespace bbb { +namespace aaa { + +void +Item::go ( ) +{ +} + +} +} diff --git a/Tests/QtAutogen/same_name/bbb/aaa/item.hpp b/Tests/QtAutogen/same_name/bbb/aaa/item.hpp new file mode 100644 index 0000000..35a3686 --- /dev/null +++ b/Tests/QtAutogen/same_name/bbb/aaa/item.hpp @@ -0,0 +1,19 @@ +#ifndef SDB_SDA_ITEM_HPP +#define SDB_SDA_ITEM_HPP + +#include <QObject> + +namespace bbb { +namespace aaa { + +class Item : public QObject +{ + Q_OBJECT + Q_SLOT + void go ( ); +}; + +} +} + +#endif diff --git a/Tests/QtAutogen/same_name/bbb/data.qrc b/Tests/QtAutogen/same_name/bbb/data.qrc new file mode 100644 index 0000000..5b080f5 --- /dev/null +++ b/Tests/QtAutogen/same_name/bbb/data.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="bbb/"> + <file>item.hpp</file> + <file>item.cpp</file> +</qresource> +</RCC> diff --git a/Tests/QtAutogen/same_name/bbb/item.cpp b/Tests/QtAutogen/same_name/bbb/item.cpp new file mode 100644 index 0000000..064295b --- /dev/null +++ b/Tests/QtAutogen/same_name/bbb/item.cpp @@ -0,0 +1,10 @@ +#include "item.hpp" + +namespace bbb { + +void +Item::go ( ) +{ +} + +} diff --git a/Tests/QtAutogen/same_name/bbb/item.hpp b/Tests/QtAutogen/same_name/bbb/item.hpp new file mode 100644 index 0000000..eda84a2 --- /dev/null +++ b/Tests/QtAutogen/same_name/bbb/item.hpp @@ -0,0 +1,17 @@ +#ifndef SDB_ITEM_HPP +#define SDB_ITEM_HPP + +#include <QObject> + +namespace bbb { + +class Item : public QObject +{ + Q_OBJECT + Q_SLOT + void go ( ); +}; + +} + +#endif diff --git a/Tests/QtAutogen/same_name/ccc/data.qrc b/Tests/QtAutogen/same_name/ccc/data.qrc new file mode 100644 index 0000000..f934c39 --- /dev/null +++ b/Tests/QtAutogen/same_name/ccc/data.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="ccc/"> + <file>item.hpp</file> + <file>item.cpp</file> +</qresource> +</RCC> diff --git a/Tests/QtAutogen/same_name/ccc/item.cpp b/Tests/QtAutogen/same_name/ccc/item.cpp new file mode 100644 index 0000000..2584881 --- /dev/null +++ b/Tests/QtAutogen/same_name/ccc/item.cpp @@ -0,0 +1,26 @@ +#include "item.hpp" + +namespace ccc { + +void +Item::go ( ) +{ +} + +class MocTest : public QObject +{ + Q_OBJECT; + Q_SLOT + void go ( ); +}; + +void +MocTest::go() +{ +} + +} + +// Include own moc files +#include "moc_item.cpp" +#include "item.moc" diff --git a/Tests/QtAutogen/same_name/ccc/item.hpp b/Tests/QtAutogen/same_name/ccc/item.hpp new file mode 100644 index 0000000..6386dc6 --- /dev/null +++ b/Tests/QtAutogen/same_name/ccc/item.hpp @@ -0,0 +1,17 @@ +#ifndef SDC_ITEM_HPP +#define SDC_ITEM_HPP + +#include <QObject> + +namespace ccc { + +class Item : public QObject +{ + Q_OBJECT + Q_SLOT + void go ( ); +}; + +} + +#endif diff --git a/Tests/QtAutogen/same_name/data.qrc b/Tests/QtAutogen/same_name/data.qrc new file mode 100644 index 0000000..4ce0b4e --- /dev/null +++ b/Tests/QtAutogen/same_name/data.qrc @@ -0,0 +1,5 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>main.cpp</file> +</qresource> +</RCC> diff --git a/Tests/QtAutogen/same_name/main.cpp b/Tests/QtAutogen/same_name/main.cpp new file mode 100644 index 0000000..166466e --- /dev/null +++ b/Tests/QtAutogen/same_name/main.cpp @@ -0,0 +1,16 @@ +#include "aaa/item.hpp" +#include "aaa/bbb/item.hpp" +#include "bbb/item.hpp" +#include "bbb/aaa/item.hpp" +#include "ccc/item.hpp" + +int main(int argv, char **args) +{ + // Object instances + ::aaa::Item aaa_item; + ::aaa::bbb::Item aaa_bbb_item; + ::bbb::Item bbb_item; + ::bbb::aaa::Item bbb_aaa_item; + ::ccc::Item ccc_item; + return 0; +} https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=77ea7ee6dbc7c3be7870432a68dbff9747201768 commit 77ea7ee6dbc7c3be7870432a68dbff9747201768 Author: Sebastian Holtermann <sebh...@xwmw.org> AuthorDate: Tue Apr 19 11:02:48 2016 +0200 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Autogen: Generate qrc_NAME.cpp files in subdirectories (#16068) A qrc_NAME.cpp file generated from NAME.qrc in the directory CMAKE_CURRENT_SOURCE_DIR/SUBDIR will be generated in the directory CMAKE_CURRENT_BINARY_DIR/TARGETNAME_automoc.dir/SUBDIR diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 4cab81f..ea9ea7c 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -25,6 +25,87 @@ # include "cmGlobalVisualStudioGenerator.h" #endif +static std::string GetAutogenTargetName( + cmGeneratorTarget const* target) +{ + std::string autogenTargetName = target->GetName(); + autogenTargetName += "_automoc"; + return autogenTargetName; +} + +static std::string GetAutogenTargetDir( + cmGeneratorTarget const* target) +{ + cmMakefile* makefile = target->Target->GetMakefile(); + std::string targetDir = makefile->GetCurrentBinaryDirectory(); + targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); + targetDir += "/"; + targetDir += GetAutogenTargetName(target); + targetDir += ".dir/"; + return targetDir; +} + +static std::string GetAutogenTargetBuildDir( + cmGeneratorTarget const* target) +{ + cmMakefile* makefile = target->Target->GetMakefile(); + std::string targetDir = makefile->GetCurrentBinaryDirectory(); + targetDir += "/"; + targetDir += GetAutogenTargetName(target); + targetDir += ".dir/"; + return targetDir; +} + +static std::string GetSourceRelativePath( + cmGeneratorTarget const* target, + const std::string& fileName) +{ + std::string pathRel; + // Test if the file is child to any of the known directories + { + const std::string fileNameReal = cmsys::SystemTools::GetRealPath(fileName); + std::string parentDirectory; + bool match ( false ); + { + std::string testDirs[4]; + { + cmMakefile* makefile = target->Target->GetMakefile(); + testDirs[0] = makefile->GetCurrentSourceDirectory(); + testDirs[1] = makefile->GetCurrentBinaryDirectory(); + testDirs[2] = makefile->GetHomeDirectory(); + testDirs[3] = makefile->GetHomeOutputDirectory(); + } + for(int ii=0; ii != sizeof(testDirs)/sizeof(std::string); ++ii ) + { + const ::std::string testDir = cmsys::SystemTools::GetRealPath( + testDirs[ii]); + if (!testDir.empty() + && cmsys::SystemTools::IsSubDirectory(fileNameReal, testDir) ) + { + parentDirectory = testDir; + match = true; + break; + } + } + } + // Use root as fallback parent directory + if (!match) + { + cmsys::SystemTools::SplitPathRootComponent(fileNameReal, + &parentDirectory); + } + pathRel = cmsys::SystemTools::RelativePath( + parentDirectory, cmsys::SystemTools::GetParentDirectory(fileNameReal)); + } + // Sanitize relative path + if (!pathRel.empty()) + { + pathRel += '/'; + cmSystemTools::ReplaceString(pathRel, "..", "__"); + } + return pathRel; +} + static void SetupSourceFiles(cmGeneratorTarget const* target, std::vector<std::string>& skipMoc, std::vector<std::string>& mocSources, @@ -61,13 +142,16 @@ static void SetupSourceFiles(cmGeneratorTarget const* target, if (ext == "qrc" && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { + + std::string rcc_output_dir = GetAutogenTargetBuildDir(target); + rcc_output_dir += GetSourceRelativePath(target,absFile); + cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); + std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(absFile); - std::string rcc_output_dir = target->GetSupportDirectory(); - cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); std::string rcc_output_file = rcc_output_dir; - rcc_output_file += "/qrc_" + basename + ".cpp"; + rcc_output_file += "qrc_" + basename + ".cpp"; makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", rcc_output_file.c_str(), false); makefile->GetOrCreateSource(rcc_output_file, true); @@ -433,26 +517,6 @@ static void MergeRccOptions(std::vector<std::string> &opts, opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); } -std::string GetAutogenTargetName( - cmGeneratorTarget const* target) -{ - std::string autogenTargetName = target->GetName(); - autogenTargetName += "_automoc"; - return autogenTargetName; -} - -std::string GetAutogenTargetDir( - cmGeneratorTarget const* target) -{ - cmMakefile* makefile = target->Target->GetMakefile(); - std::string targetDir = makefile->GetCurrentBinaryDirectory(); - targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); - targetDir += "/"; - targetDir += GetAutogenTargetName(target); - targetDir += ".dir/"; - return targetDir; -} - static void copyTargetProperty(cmTarget* destinationTarget, cmTarget* sourceTarget, const std::string& propertyName) @@ -858,14 +922,18 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( if (ext == "qrc" && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { - std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(absFile); - - std::string rcc_output_dir = target->GetSupportDirectory(); - cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); - std::string rcc_output_file = rcc_output_dir; - rcc_output_file += "/qrc_" + basename + ".cpp"; - rcc_output.push_back(rcc_output_file); + + { + std::string rcc_output_dir = GetAutogenTargetBuildDir(target); + rcc_output_dir += GetSourceRelativePath(target,absFile); + cmSystemTools::MakeDirectory(rcc_output_dir.c_str()); + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFile); + std::string rcc_output_file = rcc_output_dir; + rcc_output_file += "qrc_" + basename + ".cpp"; + rcc_output.push_back(rcc_output_file); + } if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 5299bf7..c6ee751 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1399,8 +1399,11 @@ bool cmQtAutoGenerators::GenerateQrcFiles() { std::string basename = cmsys::SystemTools:: GetFilenameWithoutLastExtension(*si); - std::string qrcOutputFile = "CMakeFiles/" + this->OriginTargetName - + ".dir/qrc_" + basename + ".cpp"; + std::string qrcOutputFile = this->TargetBuildSubDir + + this->SourceRelativePath ( *si ) + + "qrc_" + basename + ".cpp"; + //std::string qrcOutputFile = "CMakeFiles/" + this->OriginTargetName + // + ".dir/qrc_" + basename + ".cpp"; qrcGenMap[*si] = qrcOutputFile; } } @@ -1438,8 +1441,10 @@ bool cmQtAutoGenerators::GenerateQrc ( const std::string& qrcInputFile, const std::string& qrcOutputFile ) { - const std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(qrcInputFile); + std::string relName = this->SourceRelativePath ( qrcInputFile ); + cmSystemTools::ReplaceString(relName, "/", "_"); + relName += cmsys::SystemTools::GetFilenameWithoutLastExtension(qrcInputFile); + const ::std::string qrcBuildFile = this->Builddir + qrcOutputFile; int sourceNewerThanQrc = 0; @@ -1469,7 +1474,7 @@ bool cmQtAutoGenerators::GenerateQrc ( } command.push_back("-name"); - command.push_back(basename); + command.push_back(relName); command.push_back("-o"); command.push_back(qrcBuildFile); command.push_back(qrcInputFile); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6bb656e760f07958a47c14aa730f792b9ec48cb4 commit 6bb656e760f07958a47c14aa730f792b9ec48cb4 Author: Sebastian Holtermann <sebh...@xwmw.org> AuthorDate: Tue Apr 19 10:15:31 2016 +0200 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Autogen: Generate not included moc files in subdirectories (#12873) Not included moc files generated from a source file in CMAKE_CURRENT_SOURCE_DIR/SUBDIR will be generated in the directory CMAKE_CURRENT_BINARY_DIR/TARGETNAME_automoc.dir/SUBDIR/ diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index f5bdac3..5299bf7 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -410,11 +410,12 @@ cmQtAutoGenerators::WriteOldMocDefinitionsFile( void cmQtAutoGenerators::Init() { + this->TargetBuildSubDir = this->TargetName; + this->TargetBuildSubDir += ".dir/"; + this->OutMocCppFilenameRel = this->TargetName; this->OutMocCppFilenameRel += ".cpp"; - - this->OutMocCppFilename = this->Builddir; - this->OutMocCppFilename += this->OutMocCppFilenameRel; + this->OutMocCppFilenameAbs = this->Builddir + this->OutMocCppFilenameRel; std::vector<std::string> cdefList; cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList); @@ -507,7 +508,7 @@ static std::string ReadAll(const std::string& filename) bool cmQtAutoGenerators::RunAutogen(cmMakefile* makefile) { - if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) + if (!cmsys::SystemTools::FileExists(this->OutMocCppFilenameAbs.c_str()) || (this->OldCompileSettingsStr != this->CurrentCompileSettingsStr)) { this->GenerateAll = true; @@ -1047,14 +1048,15 @@ void cmQtAutoGenerators::ParseHeaders(const std::set<std::string>& absHeaders, std::cout << "AUTOGEN: Checking " << headerName << std::endl; } - const std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(headerName); - - const std::string currentMoc = "moc_" + basename + ".cpp"; std::string macroName; if (requiresMocing(contents, macroName)) { //std::cout << "header contains Q_OBJECT macro"; + const std::string parentDir = this->TargetBuildSubDir + + this->SourceRelativePath ( headerName ); + const std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(headerName); + const std::string currentMoc = parentDir + "moc_" + basename + ".cpp"; notIncludedMocs[headerName] = currentMoc; } } @@ -1145,7 +1147,7 @@ bool cmQtAutoGenerators::GenerateMocFiles( if (!automocCppChanged) { // compare contents of the _automoc.cpp file - const std::string oldContents = ReadAll(this->OutMocCppFilename); + const std::string oldContents = ReadAll(this->OutMocCppFilenameAbs); if (oldContents == automocSource) { // nothing changed: don't touch the _automoc.cpp file @@ -1168,7 +1170,7 @@ bool cmQtAutoGenerators::GenerateMocFiles( } { cmsys::ofstream outfile; - outfile.open(this->OutMocCppFilename.c_str(), + outfile.open(this->OutMocCppFilenameAbs.c_str(), std::ios::trunc); outfile << automocSource; outfile.close(); @@ -1492,6 +1494,53 @@ bool cmQtAutoGenerators::GenerateQrc ( return true; } +std::string cmQtAutoGenerators::SourceRelativePath(const std::string& filename) +{ + std::string pathRel; + + // Test if the file is child to any of the known directories + { + std::string fileNameReal = cmsys::SystemTools::GetRealPath( filename ); + std::string parentDirectory; + bool match ( false ); + { + const ::std::string* testDirs[4]; + testDirs[0] = &(this->Srcdir); + testDirs[1] = &(this->Builddir); + testDirs[2] = &(this->ProjectSourceDir); + testDirs[3] = &(this->ProjectBinaryDir); + for(int ii=0; ii != sizeof(testDirs)/sizeof(const ::std::string*); ++ii ) + { + const ::std::string testDir = cmsys::SystemTools::GetRealPath( + *(testDirs[ii])); + if (cmsys::SystemTools::IsSubDirectory(fileNameReal, + testDir) ) + { + parentDirectory = testDir; + match = true; + break; + } + } + } + // Use root as fallback parent directory + if ( !match ) + { + cmsys::SystemTools::SplitPathRootComponent(fileNameReal, + &parentDirectory); + } + pathRel = cmsys::SystemTools::RelativePath( + parentDirectory, cmsys::SystemTools::GetParentDirectory(fileNameReal)); + } + + // Sanitize relative path + if (!pathRel.empty()) + { + pathRel += '/'; + cmSystemTools::ReplaceString(pathRel, "..", "__"); + } + return pathRel; +} + /** * @brief Collects name collisions as output/input pairs * @return True if there were collisions diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index d529bf9..422e1ed 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -78,6 +78,8 @@ private: void Init(); + std::string SourceRelativePath(const std::string& filename); + bool NameCollisionTest(const std::map<std::string, std::string >& genFiles, std::multimap<std::string, std::string>& collisions ); void NameCollisionLog( @@ -114,8 +116,9 @@ private: std::string CurrentCompileSettingsStr; std::string OldCompileSettingsStr; + std::string TargetBuildSubDir; std::string OutMocCppFilenameRel; - std::string OutMocCppFilename; + std::string OutMocCppFilenameAbs; std::list<std::string> MocIncludes; std::list<std::string> MocDefinitions; std::vector<std::string> MocOptions; https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2d2b6da3b6f238947eade0755b32309baa1d6539 commit 2d2b6da3b6f238947eade0755b32309baa1d6539 Author: Sebastian Holtermann <sebh...@xwmw.org> AuthorDate: Mon Apr 18 20:36:04 2016 +0200 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Autogen: Check added for name collisions of generated qrc_NAME.cpp files diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index e3ea479..f5bdac3 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1403,6 +1403,20 @@ bool cmQtAutoGenerators::GenerateQrcFiles() } } + // look for name collisions + { + std::multimap<std::string, std::string> collisions; + if( this->NameCollisionTest ( qrcGenMap, collisions ) ) + { + std::cerr << "AUTOGEN: error: The same qrc_NAME.cpp file" + " will be generated from different sources." << std::endl + << "To avoid this error rename the source .qrc files." + << std::endl; + this->NameCollisionLog ( collisions ); + ::exit(EXIT_FAILURE); + } + } + // generate qrc files for(std::map<std::string, std::string>::const_iterator si = qrcGenMap.begin(); si != qrcGenMap.end(); ++si) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=191c41b31463b0ea3f633d5e0d10d6239380b0ff commit 191c41b31463b0ea3f633d5e0d10d6239380b0ff Author: Sebastian Holtermann <sebh...@xwmw.org> AuthorDate: Mon Apr 18 20:32:44 2016 +0200 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Autogen: Check added for name collisions of generated ui_NAME.h files diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index b44ef61..e3ea479 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1243,6 +1243,7 @@ bool cmQtAutoGenerators::GenerateUiFiles( { // single map with input / output names std::map<std::string, std::map<std::string, std::string> > uiGenMap; + std::map<std::string, std::string> testMap; for(std::map<std::string, std::vector<std::string> >::const_iterator it = includedUis.begin(); it != includedUis.end(); ++it) { @@ -1260,9 +1261,24 @@ bool cmQtAutoGenerators::GenerateUiFiles( const std::string uiInputFile = sourcePath + uiFileName + ".ui"; const std::string uiOutputFile = "ui_" + uiFileName + ".h"; sourceMap[uiInputFile] = uiOutputFile; + testMap[uiInputFile] = uiOutputFile; } } + // look for name collisions + { + std::multimap<std::string, std::string> collisions; + if( this->NameCollisionTest ( testMap, collisions ) ) + { + std::cerr << "AUTOGEN: error: The same ui_NAME.h file will be generated " + "from different sources." << std::endl + << "To avoid this error rename the source files." << std::endl; + this->NameCollisionLog ( collisions ); + ::exit(EXIT_FAILURE); + } + } + testMap.clear(); + // generate ui files for(std::map<std::string, std::map<std::string, std::string> >:: const_iterator it = uiGenMap.begin(); it != uiGenMap.end(); ++it) https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7b824667604b3abc89e3562587a0ced0acd4891f commit 7b824667604b3abc89e3562587a0ced0acd4891f Author: Sebastian Holtermann <sebh...@xwmw.org> AuthorDate: Mon Apr 18 20:09:23 2016 +0200 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Autogen: Check added for name collisions of generated moc files The test exits with an error if two or more source files would generate the same moc file. diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index bd1ace8..8143ba9 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -13,7 +13,13 @@ source files at build time and invoke moc accordingly. * If an ``#include`` statement like ``#include "moc_foo.cpp"`` is found, the ``Q_OBJECT`` class declaration is expected in the header, and - ``moc`` is run on the header file. + ``moc`` is run on the header file. A ``moc_foo.cpp`` file will be + generated from the source's header into the + :variable:`CMAKE_CURRENT_BINARY_DIR` directory. This allows the + compiler to find the included ``moc_foo.cpp`` file regardless of the + location the original source. However, if multiple source files + in different directories do this then their generated moc files would + collide. In this case a diagnostic will be issued. * If an ``#include`` statement like ``#include "foo.moc"`` is found, then a ``Q_OBJECT`` is expected in the current source file and ``moc`` diff --git a/Help/release/dev/automoc-diagnostics.rst b/Help/release/dev/automoc-diagnostics.rst new file mode 100644 index 0000000..439d2ff --- /dev/null +++ b/Help/release/dev/automoc-diagnostics.rst @@ -0,0 +1,6 @@ +automoc-diagnostics +------------------- + +* :prop_tgt:`AUTOMOC` now diagnoses name collisions when multiple source + files in different directories use ``#include <moc_foo.cpp>`` with the + same name (because the generated ``moc_foo.cpp`` files would collide. diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index c07a0a6..b44ef61 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1067,6 +1067,26 @@ bool cmQtAutoGenerators::GenerateMocFiles( const std::map<std::string, std::string>& includedMocs, const std::map<std::string, std::string>& notIncludedMocs ) { + // look for name collisions + { + std::multimap<std::string, std::string> collisions; + // Test merged map of included and notIncluded + std::map<std::string, std::string> mergedMocs ( includedMocs ); + mergedMocs.insert ( notIncludedMocs.begin(), notIncludedMocs.end() ); + if( this->NameCollisionTest ( mergedMocs, collisions ) ) + { + std::cerr << + "AUTOGEN: error: " + "The same moc file will be generated " + "from different sources." << std::endl << + "To avoid this error either" << std::endl << + "- rename the source files or" << std::endl << + "- do not include the (moc_NAME.cpp|NAME.moc) file" << std::endl; + this->NameCollisionLog ( collisions ); + ::exit(EXIT_FAILURE); + } + } + // generate moc files that are included by source files. for(std::map<std::string, std::string>::const_iterator it = includedMocs.begin(); it != includedMocs.end(); ++it) @@ -1442,6 +1462,58 @@ bool cmQtAutoGenerators::GenerateQrc ( return true; } +/** + * @brief Collects name collisions as output/input pairs + * @return True if there were collisions + */ +bool cmQtAutoGenerators::NameCollisionTest( + const std::map<std::string, std::string >& genFiles, + std::multimap<std::string, std::string>& collisions) +{ + typedef std::map<std::string, std::string>::iterator Iter; + typedef std::map<std::string, std::string>::value_type VType; + // Create local copy + std::map<std::string, std::string > localGen ( genFiles ); + for(Iter ait = localGen.begin(); ait != localGen.end(); ++ait ) + { + bool skip_aname ( false ); + Iter bit = (++Iter(ait)); + while ( bit != localGen.end() ) + { + if(ait->second == bit->second) + { + if ( !skip_aname ) + { + skip_aname = true; + collisions.insert(VType(ait->second, ait->first)); + } + collisions.insert(VType(bit->second, bit->first)); + bit = localGen.erase ( bit ); + } + else + { + ++bit; + } + } + } + + return !collisions.empty(); +} + +void cmQtAutoGenerators::NameCollisionLog( + const std::multimap<std::string, std::string>& collisions) +{ + typedef std::multimap<std::string, std::string>::const_iterator Iter; + + std::stringstream sbuf; + for(Iter it = collisions.begin(); it != collisions.end(); ++it ) + { + sbuf << it->first << " : " << it->second << std::endl; + } + sbuf.flush(); + std::cerr << sbuf.str(); +} + void cmQtAutoGenerators::LogCommand(const std::vector<std::string>& command) { std::stringstream sbuf; diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 68ab480..d529bf9 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -78,6 +78,11 @@ private: void Init(); + bool NameCollisionTest(const std::map<std::string, std::string >& genFiles, + std::multimap<std::string, std::string>& collisions ); + void NameCollisionLog( + const std::multimap<std::string, std::string>& collisions ); + void LogCommand(const std::vector<std::string>& command); std::string JoinExts(const std::vector<std::string>& lst); https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=da61ea9bc515b8286dcfbe0e3e62fca4cef8b3b0 commit da61ea9bc515b8286dcfbe0e3e62fca4cef8b3b0 Author: Brad King <brad.k...@kitware.com> AuthorDate: Fri Apr 15 14:04:28 2016 -0400 Commit: Brad King <brad.k...@kitware.com> CommitDate: Wed Apr 20 13:37:12 2016 -0400 Help: Improve AUTOMOC documentation layout diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 045ebb2..bd1ace8 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -6,22 +6,29 @@ Should the target be processed with automoc (for Qt projects). AUTOMOC is a boolean specifying whether CMake will handle the Qt ``moc`` preprocessor automatically, i.e. without having to use the :module:`QT4_WRAP_CPP() <FindQt4>` or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are -supported. When this property is set ``ON``, CMake will scan the -source files at build time and invoke moc accordingly. If an ``#include`` -statement like ``#include "moc_foo.cpp"`` is found, the ``Q_OBJECT`` class -declaration is expected in the header, and ``moc`` is run on the header -file. If an ``#include`` statement like ``#include "foo.moc"`` is found, then -a ``Q_OBJECT`` is expected in the current source file and ``moc`` is run on -the file itself. Additionally, header files with the same base name (like -``foo.h``) or ``_p`` appended to the base name (like ``foo_p.h``) are parsed -for ``Q_OBJECT`` macros, and if found, ``moc`` is also executed on those files. -``AUTOMOC`` checks multiple header alternative extensions, such as -``hpp``, ``hxx`` etc when searching for headers. -The resulting moc files, which are not included as shown above in any -of the source files are included in a generated -``<targetname>_automoc.cpp`` file, which is compiled as part of the -target. This property is initialized by the value of the -:variable:`CMAKE_AUTOMOC` variable if it is set when a target is created. +supported. + +When this property is set ``ON``, CMake will scan the +source files at build time and invoke moc accordingly. + +* If an ``#include`` statement like ``#include "moc_foo.cpp"`` is found, + the ``Q_OBJECT`` class declaration is expected in the header, and + ``moc`` is run on the header file. + +* If an ``#include`` statement like ``#include "foo.moc"`` is found, + then a ``Q_OBJECT`` is expected in the current source file and ``moc`` + is run on the file itself. Additionally, header files with the same + base name (like ``foo.h``) or ``_p`` appended to the base name (like + ``foo_p.h``) are parsed for ``Q_OBJECT`` macros, and if found, ``moc`` + is also executed on those files. ``AUTOMOC`` checks multiple header + alternative extensions, such as ``hpp``, ``hxx`` etc when searching + for headers. The resulting moc files, which are not included as shown + above in any of the source files are included in a generated + ``<targetname>_automoc.cpp`` file, which is compiled as part of the + target. + +This property is initialized by the value of the :variable:`CMAKE_AUTOMOC` +variable if it is set when a target is created. Additional command line options for moc can be set via the :prop_tgt:`AUTOMOC_MOC_OPTIONS` property. ----------------------------------------------------------------------- Summary of changes: Help/prop_tgt/AUTOMOC.rst | 45 ++++--- Help/release/dev/automoc-diagnostics.rst | 6 + Source/cmQtAutoGeneratorInitializer.cxx | 130 ++++++++++++++----- Source/cmQtAutoGenerators.cxx | 186 +++++++++++++++++++++++++--- Source/cmQtAutoGenerators.h | 10 +- Tests/QtAutogen/CMakeLists.txt | 4 + Tests/QtAutogen/same_name/CMakeLists.txt | 20 +++ Tests/QtAutogen/same_name/aaa/bbb/data.qrc | 6 + Tests/QtAutogen/same_name/aaa/bbb/item.cpp | 12 ++ Tests/QtAutogen/same_name/aaa/bbb/item.hpp | 19 +++ Tests/QtAutogen/same_name/aaa/data.qrc | 6 + Tests/QtAutogen/same_name/aaa/item.cpp | 10 ++ Tests/QtAutogen/same_name/aaa/item.hpp | 17 +++ Tests/QtAutogen/same_name/bbb/aaa/data.qrc | 6 + Tests/QtAutogen/same_name/bbb/aaa/item.cpp | 12 ++ Tests/QtAutogen/same_name/bbb/aaa/item.hpp | 19 +++ Tests/QtAutogen/same_name/bbb/data.qrc | 6 + Tests/QtAutogen/same_name/bbb/item.cpp | 10 ++ Tests/QtAutogen/same_name/bbb/item.hpp | 17 +++ Tests/QtAutogen/same_name/ccc/data.qrc | 6 + Tests/QtAutogen/same_name/ccc/item.cpp | 26 ++++ Tests/QtAutogen/same_name/ccc/item.hpp | 17 +++ Tests/QtAutogen/same_name/data.qrc | 5 + Tests/QtAutogen/same_name/main.cpp | 16 +++ 24 files changed, 548 insertions(+), 63 deletions(-) create mode 100644 Help/release/dev/automoc-diagnostics.rst create mode 100644 Tests/QtAutogen/same_name/CMakeLists.txt create mode 100644 Tests/QtAutogen/same_name/aaa/bbb/data.qrc create mode 100644 Tests/QtAutogen/same_name/aaa/bbb/item.cpp create mode 100644 Tests/QtAutogen/same_name/aaa/bbb/item.hpp create mode 100644 Tests/QtAutogen/same_name/aaa/data.qrc create mode 100644 Tests/QtAutogen/same_name/aaa/item.cpp create mode 100644 Tests/QtAutogen/same_name/aaa/item.hpp create mode 100644 Tests/QtAutogen/same_name/bbb/aaa/data.qrc create mode 100644 Tests/QtAutogen/same_name/bbb/aaa/item.cpp create mode 100644 Tests/QtAutogen/same_name/bbb/aaa/item.hpp create mode 100644 Tests/QtAutogen/same_name/bbb/data.qrc create mode 100644 Tests/QtAutogen/same_name/bbb/item.cpp create mode 100644 Tests/QtAutogen/same_name/bbb/item.hpp create mode 100644 Tests/QtAutogen/same_name/ccc/data.qrc create mode 100644 Tests/QtAutogen/same_name/ccc/item.cpp create mode 100644 Tests/QtAutogen/same_name/ccc/item.hpp create mode 100644 Tests/QtAutogen/same_name/data.qrc create mode 100644 Tests/QtAutogen/same_name/main.cpp hooks/post-receive -- CMake _______________________________________________ Cmake-commits mailing list Cmake-commits@cmake.org http://public.kitware.com/mailman/listinfo/cmake-commits