From 850b4d990c1bf15b70cc5dab9794066ab0f1d948 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 5 Apr 2023 16:09:12 -0400 Subject: IWYU: Add mapping for 'std::remove_reference::type' IWYU sometimes thinks that `cmCMakeLanguageCommand.cxx` mentions this type and suggests including `` for it. The type is only used internally by standard library functions. Work around the problem by mapping the offending name to a file that we always include. --- Utilities/IWYU/mapping.imp | 1 + 1 file changed, 1 insertion(+) diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp index 1afad43..6443632 100644 --- a/Utilities/IWYU/mapping.imp +++ b/Utilities/IWYU/mapping.imp @@ -99,6 +99,7 @@ { symbol: [ "std::enable_if > >::type", private, "\"cmConfigure.h\"", public ] }, { symbol: [ "std::enable_if > >::type", private, "\"cmConfigure.h\"", public ] }, { symbol: [ "__gnu_cxx::__enable_if::__type", private, "\"cmConfigure.h\"", public ] }, + { symbol: [ "std::remove_reference::type", private, "\"cmConfigure.h\"", public ] }, # Wrappers for 3rd-party libraries { include: [ "@<.*curl/curlver.h>", private, "", public ] }, -- cgit v0.12 From 2daba01ddf3f79bd4718680ef322f39366eeefef Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 5 Apr 2023 15:46:26 -0400 Subject: cmGeneratorTarget: Avoid incidental include-what-you-use warning Avoid `warning: Extra tokens on pragma line` from IWYU. --- Source/cmGeneratorTarget.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index bc5505f..81e95a7 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8977,10 +8977,10 @@ std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile( cmGeneratedFileStream fout(filename); fout.SetCopyIfDifferent(true); - // IWYU pragma: associated allows include what you use to + // The IWYU "associated" pragma tells include-what-you-use to // consider the headerFile as part of the entire language // unit within include-what-you-use and as a result allows - // one to get IWYU advice for headers :) + // one to get IWYU advice for headers. fout << "#include <" << headerFilename << "> // IWYU pragma: associated\n"; fout.close(); -- cgit v0.12 From 7cecb6353e0018fc2b4d0de83c209c0465b585ce Mon Sep 17 00:00:00 2001 From: Orkun Tokdemir Date: Mon, 3 Apr 2023 16:55:13 +0200 Subject: cmGeneratorTarget: Factor out EvaluatedTargetProperty infrastructure Make it available outside the `cmGeneratorTarget` implementation. In particular, we will later use it in `cmQtAutoGenInitializer`. --- Source/CMakeLists.txt | 2 + Source/cmEvaluatedTargetProperty.cxx | 111 +++++++++++++++++ Source/cmEvaluatedTargetProperty.h | 80 +++++++++++++ Source/cmGeneratorTarget.cxx | 226 ++++++----------------------------- Source/cmGeneratorTarget.h | 22 ++++ bootstrap | 1 + 6 files changed, 253 insertions(+), 189 deletions(-) create mode 100644 Source/cmEvaluatedTargetProperty.cxx create mode 100644 Source/cmEvaluatedTargetProperty.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3ae0bc6..dcc7174 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -193,6 +193,8 @@ add_library( cmDyndepCollation.h cmELF.h cmELF.cxx + cmEvaluatedTargetProperty.cxx + cmEvaluatedTargetProperty.h cmExprParserHelper.cxx cmExportBuildAndroidMKGenerator.h cmExportBuildAndroidMKGenerator.cxx diff --git a/Source/cmEvaluatedTargetProperty.cxx b/Source/cmEvaluatedTargetProperty.cxx new file mode 100644 index 0000000..1173690 --- /dev/null +++ b/Source/cmEvaluatedTargetProperty.cxx @@ -0,0 +1,111 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmEvaluatedTargetProperty.h" + +#include +#include + +#include "cmGeneratorExpressionContext.h" +#include "cmGeneratorTarget.h" +#include "cmLinkItem.h" +#include "cmStringAlgorithms.h" + +struct cmGeneratorExpressionDAGChecker; + +EvaluatedTargetPropertyEntry::EvaluatedTargetPropertyEntry( + cmLinkImplItem const& item, cmListFileBacktrace bt) + : LinkImplItem(item) + , Backtrace(std::move(bt)) +{ +} + +EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, + cmGeneratorTarget::TargetPropertyEntry& entry) +{ + EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace()); + cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config, + thisTarget, dagChecker, lang), + ee.Values); + if (entry.GetHadContextSensitiveCondition()) { + ee.ContextDependent = true; + } + return ee; +} + +EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, + std::vector> const& + in) +{ + EvaluatedTargetPropertyEntries out; + out.Entries.reserve(in.size()); + for (auto const& entry : in) { + out.Entries.emplace_back(EvaluateTargetPropertyEntry( + thisTarget, config, lang, dagChecker, *entry)); + } + return out; +} + +namespace { +void addInterfaceEntry(cmGeneratorTarget const* headTarget, + std::string const& config, std::string const& prop, + std::string const& lang, + cmGeneratorExpressionDAGChecker* dagChecker, + EvaluatedTargetPropertyEntries& entries, + cmGeneratorTarget::LinkInterfaceFor interfaceFor, + std::vector const& libraries) +{ + for (cmLinkImplItem const& lib : libraries) { + if (lib.Target) { + EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); + // Pretend $ appeared in our + // caller's property and hand-evaluate it as if it were compiled. + // Create a context as cmCompiledGeneratorExpression::Evaluate does. + cmGeneratorExpressionContext context( + headTarget->GetLocalGenerator(), config, false, headTarget, headTarget, + true, lib.Backtrace, lang); + cmExpandList(lib.Target->EvaluateInterfaceProperty( + prop, &context, dagChecker, interfaceFor), + ee.Values); + ee.ContextDependent = context.HadContextSensitiveCondition; + entries.Entries.emplace_back(std::move(ee)); + } + } +} +} + +void AddInterfaceEntries(cmGeneratorTarget const* headTarget, + std::string const& config, std::string const& prop, + std::string const& lang, + cmGeneratorExpressionDAGChecker* dagChecker, + EvaluatedTargetPropertyEntries& entries, + IncludeRuntimeInterface searchRuntime, + cmGeneratorTarget::LinkInterfaceFor interfaceFor) +{ + if (searchRuntime == IncludeRuntimeInterface::Yes) { + if (cmLinkImplementation const* impl = + headTarget->GetLinkImplementation(config, interfaceFor)) { + entries.HadContextSensitiveCondition = + impl->HadContextSensitiveCondition; + + auto runtimeLibIt = impl->LanguageRuntimeLibraries.find(lang); + if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) { + addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries, + interfaceFor, runtimeLibIt->second); + } + addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries, + interfaceFor, impl->Libraries); + } + } else { + if (cmLinkImplementationLibraries const* impl = + headTarget->GetLinkImplementationLibraries(config, interfaceFor)) { + entries.HadContextSensitiveCondition = + impl->HadContextSensitiveCondition; + addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries, + interfaceFor, impl->Libraries); + } + } +} diff --git a/Source/cmEvaluatedTargetProperty.h b/Source/cmEvaluatedTargetProperty.h new file mode 100644 index 0000000..e413ab0 --- /dev/null +++ b/Source/cmEvaluatedTargetProperty.h @@ -0,0 +1,80 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include +#include +#include + +#include "cmGeneratorTarget.h" +#include "cmListFileCache.h" + +class cmLinkImplItem; +struct cmGeneratorExpressionDAGChecker; + +// Represent a target property entry after evaluating generator expressions +// and splitting up lists. +struct EvaluatedTargetPropertyEntry +{ + EvaluatedTargetPropertyEntry(cmLinkImplItem const& item, + cmListFileBacktrace bt); + + // Move-only. + EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default; + EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry const&) = delete; + EvaluatedTargetPropertyEntry& operator=(EvaluatedTargetPropertyEntry&&) = + delete; + EvaluatedTargetPropertyEntry& operator=( + EvaluatedTargetPropertyEntry const&) = delete; + + cmLinkImplItem const& LinkImplItem; + cmListFileBacktrace Backtrace; + std::vector Values; + bool ContextDependent = false; +}; + +EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, + cmGeneratorTarget::TargetPropertyEntry& entry); + +struct EvaluatedTargetPropertyEntries +{ + std::vector Entries; + bool HadContextSensitiveCondition = false; +}; + +EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, + std::vector> const& + in); + +// IncludeRuntimeInterface is used to break the cycle in computing +// the necessary transitive dependencies of targets that can occur +// now that we have implicit language runtime targets. +// +// To determine the set of languages that a target has we need to iterate +// all the sources which includes transitive INTERFACE sources. +// Therefore we can't determine what language runtimes are needed +// for a target until after all sources are computed. +// +// Therefore while computing the applicable INTERFACE_SOURCES we +// must ignore anything in LanguageRuntimeLibraries or we would +// create a cycle ( INTERFACE_SOURCES requires LanguageRuntimeLibraries, +// LanguageRuntimeLibraries requires INTERFACE_SOURCES). +// +enum class IncludeRuntimeInterface +{ + Yes, + No +}; + +void AddInterfaceEntries(cmGeneratorTarget const* headTarget, + std::string const& config, std::string const& prop, + std::string const& lang, + cmGeneratorExpressionDAGChecker* dagChecker, + EvaluatedTargetPropertyEntries& entries, + IncludeRuntimeInterface searchRuntime, + cmGeneratorTarget::LinkInterfaceFor interfaceFor = + cmGeneratorTarget::LinkInterfaceFor::Usage); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 81e95a7..90cddb5 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -27,6 +27,7 @@ #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommandGenerator.h" +#include "cmEvaluatedTargetProperty.h" #include "cmFileSet.h" #include "cmFileTimes.h" #include "cmGeneratedFileStream.h" @@ -89,31 +90,38 @@ cmTargetPropertyComputer::ComputeLocation( return tgt->GetLocation(config); } -class cmGeneratorTarget::TargetPropertyEntry -{ -protected: - static cmLinkImplItem NoLinkImplItem; +cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem; +class TargetPropertyEntryString : public cmGeneratorTarget::TargetPropertyEntry +{ public: - TargetPropertyEntry(cmLinkImplItem const& item) - : LinkImplItem(item) + TargetPropertyEntryString(BT propertyValue, + cmLinkImplItem const& item = NoLinkImplItem) + : cmGeneratorTarget::TargetPropertyEntry(item) + , PropertyValue(std::move(propertyValue)) { } - virtual ~TargetPropertyEntry() = default; - virtual const std::string& Evaluate( - cmLocalGenerator* lg, const std::string& config, - cmGeneratorTarget const* headTarget, - cmGeneratorExpressionDAGChecker* dagChecker, - std::string const& language) const = 0; + const std::string& Evaluate(cmLocalGenerator*, const std::string&, + cmGeneratorTarget const*, + cmGeneratorExpressionDAGChecker*, + std::string const&) const override + { + return this->PropertyValue.Value; + } - virtual cmListFileBacktrace GetBacktrace() const = 0; - virtual std::string const& GetInput() const = 0; - virtual bool GetHadContextSensitiveCondition() const { return false; } + cmListFileBacktrace GetBacktrace() const override + { + return this->PropertyValue.Backtrace; + } + std::string const& GetInput() const override + { + return this->PropertyValue.Value; + } - cmLinkImplItem const& LinkImplItem; +private: + BT PropertyValue; }; -cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem; class TargetPropertyEntryGenex : public cmGeneratorTarget::TargetPropertyEntry { @@ -150,37 +158,6 @@ private: const std::unique_ptr ge; }; -class TargetPropertyEntryString : public cmGeneratorTarget::TargetPropertyEntry -{ -public: - TargetPropertyEntryString(BT propertyValue, - cmLinkImplItem const& item = NoLinkImplItem) - : cmGeneratorTarget::TargetPropertyEntry(item) - , PropertyValue(std::move(propertyValue)) - { - } - - const std::string& Evaluate(cmLocalGenerator*, const std::string&, - cmGeneratorTarget const*, - cmGeneratorExpressionDAGChecker*, - std::string const&) const override - { - return this->PropertyValue.Value; - } - - cmListFileBacktrace GetBacktrace() const override - { - return this->PropertyValue.Backtrace; - } - std::string const& GetInput() const override - { - return this->PropertyValue.Value; - } - -private: - BT PropertyValue; -}; - class TargetPropertyEntryFileSet : public cmGeneratorTarget::TargetPropertyEntry { @@ -263,6 +240,18 @@ std::unique_ptr< cm::make_unique(propertyValue)); } +cmGeneratorTarget::TargetPropertyEntry::TargetPropertyEntry( + cmLinkImplItem const& item) + : LinkImplItem(item) +{ +} + +bool cmGeneratorTarget::TargetPropertyEntry::GetHadContextSensitiveCondition() + const +{ + return false; +} + static void CreatePropertyGeneratorExpressions( cmake& cmakeInstance, cmBTStringRange entries, std::vector>& items, @@ -274,69 +263,6 @@ static void CreatePropertyGeneratorExpressions( } } -namespace { -// Represent a target property entry after evaluating generator expressions -// and splitting up lists. -struct EvaluatedTargetPropertyEntry -{ - EvaluatedTargetPropertyEntry(cmLinkImplItem const& item, - cmListFileBacktrace bt) - : LinkImplItem(item) - , Backtrace(std::move(bt)) - { - } - - // Move-only. - EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default; - EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry const&) = delete; - EvaluatedTargetPropertyEntry& operator=(EvaluatedTargetPropertyEntry&&) = - delete; - EvaluatedTargetPropertyEntry& operator=( - EvaluatedTargetPropertyEntry const&) = delete; - - cmLinkImplItem const& LinkImplItem; - cmListFileBacktrace Backtrace; - std::vector Values; - bool ContextDependent = false; -}; - -EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( - cmGeneratorTarget const* thisTarget, std::string const& config, - std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, - cmGeneratorTarget::TargetPropertyEntry& entry) -{ - EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace()); - cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config, - thisTarget, dagChecker, lang), - ee.Values); - if (entry.GetHadContextSensitiveCondition()) { - ee.ContextDependent = true; - } - return ee; -} - -struct EvaluatedTargetPropertyEntries -{ - std::vector Entries; - bool HadContextSensitiveCondition = false; -}; - -EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries( - cmGeneratorTarget const* thisTarget, std::string const& config, - std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector> const& - in) -{ - EvaluatedTargetPropertyEntries out; - out.Entries.reserve(in.size()); - for (auto const& entry : in) { - out.Entries.emplace_back(EvaluateTargetPropertyEntry( - thisTarget, config, lang, dagChecker, *entry)); - } - return out; -} -} - cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) : Target(t) { @@ -1607,84 +1533,6 @@ void AddLangSpecificImplicitIncludeDirectories( } } -void addInterfaceEntry(cmGeneratorTarget const* headTarget, - std::string const& config, std::string const& prop, - std::string const& lang, - cmGeneratorExpressionDAGChecker* dagChecker, - EvaluatedTargetPropertyEntries& entries, - LinkInterfaceFor interfaceFor, - std::vector const& libraries) -{ - for (cmLinkImplItem const& lib : libraries) { - if (lib.Target) { - EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); - // Pretend $ appeared in our - // caller's property and hand-evaluate it as if it were compiled. - // Create a context as cmCompiledGeneratorExpression::Evaluate does. - cmGeneratorExpressionContext context( - headTarget->GetLocalGenerator(), config, false, headTarget, headTarget, - true, lib.Backtrace, lang); - cmExpandList(lib.Target->EvaluateInterfaceProperty( - prop, &context, dagChecker, interfaceFor), - ee.Values); - ee.ContextDependent = context.HadContextSensitiveCondition; - entries.Entries.emplace_back(std::move(ee)); - } - } -} - -// IncludeRuntimeInterface is used to break the cycle in computing -// the necessary transitive dependencies of targets that can occur -// now that we have implicit language runtime targets. -// -// To determine the set of languages that a target has we need to iterate -// all the sources which includes transitive INTERFACE sources. -// Therefore we can't determine what language runtimes are needed -// for a target until after all sources are computed. -// -// Therefore while computing the applicable INTERFACE_SOURCES we -// must ignore anything in LanguageRuntimeLibraries or we would -// create a cycle ( INTERFACE_SOURCES requires LanguageRuntimeLibraries, -// LanguageRuntimeLibraries requires INTERFACE_SOURCES). -// -enum class IncludeRuntimeInterface -{ - Yes, - No -}; -void AddInterfaceEntries( - cmGeneratorTarget const* headTarget, std::string const& config, - std::string const& prop, std::string const& lang, - cmGeneratorExpressionDAGChecker* dagChecker, - EvaluatedTargetPropertyEntries& entries, - IncludeRuntimeInterface searchRuntime, - LinkInterfaceFor interfaceFor = LinkInterfaceFor::Usage) -{ - if (searchRuntime == IncludeRuntimeInterface::Yes) { - if (cmLinkImplementation const* impl = - headTarget->GetLinkImplementation(config, interfaceFor)) { - entries.HadContextSensitiveCondition = - impl->HadContextSensitiveCondition; - - auto runtimeLibIt = impl->LanguageRuntimeLibraries.find(lang); - if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) { - addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries, - interfaceFor, runtimeLibIt->second); - } - addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries, - interfaceFor, impl->Libraries); - } - } else { - if (cmLinkImplementationLibraries const* impl = - headTarget->GetLinkImplementationLibraries(config, interfaceFor)) { - entries.HadContextSensitiveCondition = - impl->HadContextSensitiveCondition; - addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries, - interfaceFor, impl->Libraries); - } - } -} - void AddObjectEntries(cmGeneratorTarget const* headTarget, std::string const& config, cmGeneratorExpressionDAGChecker* dagChecker, diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 256ca3b..87227fd 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -1291,3 +1291,25 @@ private: }; mutable std::map Configs; }; + +class cmGeneratorTarget::TargetPropertyEntry +{ +protected: + static cmLinkImplItem NoLinkImplItem; + +public: + TargetPropertyEntry(cmLinkImplItem const& item); + virtual ~TargetPropertyEntry() = default; + + virtual const std::string& Evaluate( + cmLocalGenerator* lg, const std::string& config, + cmGeneratorTarget const* headTarget, + cmGeneratorExpressionDAGChecker* dagChecker, + std::string const& language) const = 0; + + virtual cmListFileBacktrace GetBacktrace() const = 0; + virtual std::string const& GetInput() const = 0; + virtual bool GetHadContextSensitiveCondition() const; + + cmLinkImplItem const& LinkImplItem; +}; diff --git a/bootstrap b/bootstrap index 83f4814..88438df 100755 --- a/bootstrap +++ b/bootstrap @@ -337,6 +337,7 @@ CMAKE_CXX_SOURCES="\ cmELF \ cmEnableLanguageCommand \ cmEnableTestingCommand \ + cmEvaluatedTargetProperty \ cmExecProgramCommand \ cmExecuteProcessCommand \ cmExpandedCommandArgument \ -- cgit v0.12 From 69cf9700e6873a86094fe66c5091c21b909e1969 Mon Sep 17 00:00:00 2001 From: Orkun Tokdemir Date: Mon, 3 Apr 2023 16:52:13 +0200 Subject: Autogen: Defer setup until Generate step It is better to set variables up once all target dependencies are known. --- Source/cmGlobalGenerator.cxx | 22 ++++++++++++++-------- Source/cmGlobalGenerator.h | 6 ++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index eb3f433..3563a1a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1544,8 +1544,9 @@ bool cmGlobalGenerator::Compute() } #ifndef CMAKE_BOOTSTRAP - cmQtAutoGenGlobalInitializer qtAutoGen(this->LocalGenerators); - if (!qtAutoGen.InitializeCustomTargets()) { + this->QtAutoGen = + cm::make_unique(this->LocalGenerators); + if (!this->QtAutoGen->InitializeCustomTargets()) { return false; } #endif @@ -1565,12 +1566,6 @@ bool cmGlobalGenerator::Compute() } } -#ifndef CMAKE_BOOTSTRAP - if (!qtAutoGen.SetupCustomTargets()) { - return false; - } -#endif - for (const auto& localGen : this->LocalGenerators) { cmMakefile* mf = localGen->GetMakefile(); for (const auto& g : mf->GetInstallGenerators()) { @@ -1635,6 +1630,17 @@ void cmGlobalGenerator::Generate() this->CMakeInstance->UpdateProgress("Generating", 0.1f); +#ifndef CMAKE_BOOTSTRAP + if (!this->QtAutoGen->SetupCustomTargets()) { + if (!cmSystemTools::GetErrorOccurredFlag()) { + this->GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, + "Problem setting up custom targets for QtAutoGen"); + } + return; + } +#endif + // Generate project files for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) { this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile()); diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 0e0624a..dde3648 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -50,6 +50,7 @@ class cmLinkLineComputer; class cmLocalGenerator; class cmMakefile; class cmOutputConverter; +class cmQtAutoGenGlobalInitializer; class cmSourceFile; class cmState; class cmStateDirectory; @@ -683,6 +684,11 @@ protected: cmake* CMakeInstance; std::vector> Makefiles; LocalGeneratorVector LocalGenerators; + +#ifndef CMAKE_BOOTSTRAP + std::unique_ptr QtAutoGen; +#endif + cmMakefile* CurrentConfigureMakefile; // map from project name to vector of local generators in that project std::map> ProjectMap; -- cgit v0.12 From c5c3aff1f5aa36d44f3c639726dd36eedc28f823 Mon Sep 17 00:00:00 2001 From: Orkun Tokdemir Date: Mon, 3 Apr 2023 16:55:56 +0200 Subject: Autogen: Add INTERFACE_AUTOMOC_MACRO_NAMES target property Add this target property to specify macro names that propagate to dependents as `AUTOMOC_MACRO_NAMES`. The dependents will automatically generate MOC files for source files that contain the inherited macro names. Co-Authored-By: Craig Scott Fixes: #19679 --- Auxiliary/vim/syntax/cmake.vim | 1 + Help/manual/cmake-properties.7.rst | 1 + Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst | 8 +- Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst | 89 ++++++++++++++++++++++ Help/release/dev/automoc-macro-names.rst | 5 ++ Source/cmExportBuildFileGenerator.cxx | 3 + Source/cmExportInstallFileGenerator.cxx | 3 + Source/cmQtAutoGenInitializer.cxx | 19 +++++ .../MocInterfaceMacroNames/CMakeLists.txt | 61 +++++++++++++++ .../MocInterfaceMacroNames/CheckAutogenJson.cmake | 27 +++++++ .../CheckExportTargets.cmake | 45 +++++++++++ Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp | 4 + .../MocInterfaceMacroNames/shared_lib.cpp | 6 ++ .../MocInterfaceMacroNames/static_lib.cpp | 3 + Tests/QtAutogen/Tests.cmake | 1 + 15 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst create mode 100644 Help/release/dev/automoc-macro-names.rst create mode 100644 Tests/QtAutogen/MocInterfaceMacroNames/CMakeLists.txt create mode 100644 Tests/QtAutogen/MocInterfaceMacroNames/CheckAutogenJson.cmake create mode 100644 Tests/QtAutogen/MocInterfaceMacroNames/CheckExportTargets.cmake create mode 100644 Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp create mode 100644 Tests/QtAutogen/MocInterfaceMacroNames/shared_lib.cpp create mode 100644 Tests/QtAutogen/MocInterfaceMacroNames/static_lib.cpp diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index 3a44d7a..d6b5b19 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -220,6 +220,7 @@ syn keyword cmakeProperty contained \ INSTALL_RPATH \ INSTALL_RPATH_USE_LINK_PATH \ INTERFACE_AUTOUIC_OPTIONS + \ INTERFACE_AUTOMOC_MACRO_NAMES \ INTERFACE_COMPILE_DEFINITIONS \ INTERFACE_COMPILE_FEATURES \ INTERFACE_COMPILE_OPTIONS diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 8559b0b..c0e2ee2 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -273,6 +273,7 @@ Properties on Targets /prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH /prop_tgt/INSTALL_RPATH /prop_tgt/INSTALL_RPATH_USE_LINK_PATH + /prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES /prop_tgt/INTERFACE_AUTOUIC_OPTIONS /prop_tgt/INTERFACE_COMPILE_DEFINITIONS /prop_tgt/INTERFACE_COMPILE_FEATURES diff --git a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst index 072e7f7..a4a9ba2 100644 --- a/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst +++ b/Help/prop_tgt/AUTOMOC_MACRO_NAMES.rst @@ -3,7 +3,7 @@ AUTOMOC_MACRO_NAMES .. versionadded:: 3.10 -A :ref:`semicolon-separated list ` list of macro names used by +A :ref:`semicolon-separated list ` of macro names used by :prop_tgt:`AUTOMOC` to determine if a C++ file needs to be processed by ``moc``. This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON`` @@ -21,6 +21,8 @@ then the file will be processed by ``moc``. By default ``AUTOMOC_MACRO_NAMES`` is initialized from :variable:`CMAKE_AUTOMOC_MACRO_NAMES`. +See also the :prop_tgt:`INTERFACE_AUTOMOC_MACRO_NAMES` target property. + See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. @@ -29,6 +31,8 @@ Example In this case the ``Q_OBJECT`` macro is hidden inside another macro called ``CUSTOM_MACRO``. To let CMake know that source files that contain -``CUSTOM_MACRO`` need to be ``moc`` processed, we call:: +``CUSTOM_MACRO`` need to be ``moc`` processed, we call: + +.. code-block:: cmake set_property(TARGET tgt APPEND PROPERTY AUTOMOC_MACRO_NAMES "CUSTOM_MACRO") diff --git a/Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst b/Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst new file mode 100644 index 0000000..502775c --- /dev/null +++ b/Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst @@ -0,0 +1,89 @@ +INTERFACE_AUTOMOC_MACRO_NAMES +----------------------------- + +.. versionadded:: 3.27 + +A :ref:`semicolon-separated list ` of macro names for +:prop_tgt:`AUTOMOC` to be propagated to consumers. + +When a target with :prop_tgt:`AUTOMOC` enabled links to a library that sets +``INTERFACE_AUTOMOC_MACRO_NAMES``, the target inherits the listed macro names +and merges them with those specified in its own :prop_tgt:`AUTOMOC_MACRO_NAMES` +property. The target will then automatically generate MOC files for source +files that contain the inherited macro names too, not just the macro names +specified in its own :prop_tgt:`AUTOMOC_MACRO_NAMES` property. + +By default ``INTERFACE_AUTOMOC_MACRO_NAMES`` is empty. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. + +Example 1 +^^^^^^^^^ + +In this example, ``myapp`` inherits the macro names ``STATIC_LIB_1`` and +``STATIC_LIB_2`` from ``static_lib``. The ``moc`` tool will then automatically +be run on any of the ``myapp`` sources which contain ``STATIC_LIB_1`` or +``STATIC_LIB_2``. + +.. code-block:: cmake + + set(AUTOMOC ON) + add_executable(myapp main.cpp) + target_link_libraries(myapp PRIVATE static_lib) + + add_library(static_lib STATIC static.cpp) + set_property(TARGET static_lib PROPERTY + INTERFACE_AUTOMOC_MACRO_NAMES "STATIC_LIB_1;STATIC_LIB_2" + ) + +Example 2 +^^^^^^^^^ + +In this example, the ``INTERFACE_AUTOMOC_MACRO_NAMES`` target property of the +various ``*_deep_lib`` libraries will propagate to ``shared_lib``, +``static_lib`` and ``interface_lib``. Because the linking relationships are +specified as ``PUBLIC`` and ``INTERFACE``, those macro names will also further +propagate transitively up to ``app``. + +.. code-block:: cmake + + set(AUTOMOC ON) + + add_library(shared_deep_lib SHARED deep_lib.cpp) + add_library(static_deep_lib STATIC deep_lib.cpp) + add_library(interface_deep_lib INTERFACE) + + set_property(TARGET shared_deep_lib PROPERTY + INTERFACE_AUTOMOC_MACRO_NAMES "SHARED_LINK_LIB" + ) + set_property(TARGET static_deep_lib PROPERTY + INTERFACE_AUTOMOC_MACRO_NAMES "STATIC_LINK_LIB" + ) + set_property(TARGET interface_deep_lib PROPERTY + INTERFACE_AUTOMOC_MACRO_NAMES "INTERFACE_LINK_LIB" + ) + + add_library(shared_lib SHARED lib.cpp) + add_library(static_lib STATIC lib.cpp) + add_library(interface_lib INTERFACE) + + # PUBLIC and INTERFACE here ensure the macro names propagate to any + # consumers of shared_lib, static_lib or interface_lib too + target_link_libraries(shared_lib PUBLIC shared_deep_lib) + target_link_libraries(static_lib PUBLIC static_deep_lib) + target_link_libraries(interface_lib INTERFACE interface_deep_lib) + + # This consumer will receive all three of the above custom macro names as + # transitive usage requirements + add_executable(app main.cpp) + target_link_libraries(app PRIVATE shared_lib static_lib interface_lib) + +In the above: + +* ``shared_lib`` sources will be processed by ``moc`` if they contain + ``SHARED_LINK_LIB``. +* ``static_lib`` sources will be processed by ``moc`` if they contain + ``STATIC_LINK_LIB``. +* ``app`` sources will be processed by ``moc`` if they contain + ``SHARED_LINK_LIB``, ``STATIC_LINK_LIB`` or ``INTERFACE_LINK_LIB``. diff --git a/Help/release/dev/automoc-macro-names.rst b/Help/release/dev/automoc-macro-names.rst new file mode 100644 index 0000000..9c037b3 --- /dev/null +++ b/Help/release/dev/automoc-macro-names.rst @@ -0,0 +1,5 @@ +automoc-macro-names +------------------- + +* The :prop_tgt:`INTERFACE_AUTOMOC_MACRO_NAMES` target property was added to + specify macro names for ``moc`` as a transitive usage requirement. diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index caf8ac2..437ae69 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -106,6 +106,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gte, cmGeneratorExpression::BuildInterface, properties); + this->PopulateInterfaceProperty("INTERFACE_AUTOMOC_MACRO_NAMES", gte, + cmGeneratorExpression::BuildInterface, + properties); this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gte, cmGeneratorExpression::BuildInterface, properties); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index def8227..51c91f3 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -110,6 +110,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->PopulateInterfaceProperty("INTERFACE_AUTOUIC_OPTIONS", gt, cmGeneratorExpression::InstallInterface, properties); + this->PopulateInterfaceProperty("INTERFACE_AUTOMOC_MACRO_NAMES", gt, + cmGeneratorExpression::InstallInterface, + properties); this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gt, cmGeneratorExpression::InstallInterface, properties); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index ba4c4d8..782c154 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -28,8 +28,10 @@ #include "cmAlgorithms.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" +#include "cmEvaluatedTargetProperty.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorExpression.h" +#include "cmGeneratorExpressionDAGChecker.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmLinkItem.h" @@ -1691,6 +1693,23 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo() info.SetArray("MOC_OPTIONS", this->Moc.Options); info.SetBool("MOC_RELAXED_MODE", this->Moc.RelaxedMode); info.SetBool("MOC_PATH_PREFIX", this->Moc.PathPrefix); + + cmGeneratorExpressionDAGChecker dagChecker( + this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr); + EvaluatedTargetPropertyEntries InterfaceAutoMocMacroNamesEntries; + + AddInterfaceEntries(this->GenTarget, this->ConfigDefault, + "INTERFACE_AUTOMOC_MACRO_NAMES", "CXX", &dagChecker, + InterfaceAutoMocMacroNamesEntries, + IncludeRuntimeInterface::Yes); + + for (auto const& entry : InterfaceAutoMocMacroNamesEntries.Entries) { + this->Moc.MacroNames.insert(this->Moc.MacroNames.end(), + entry.Values.begin(), entry.Values.end()); + } + this->Moc.MacroNames.erase(cmRemoveDuplicates(this->Moc.MacroNames), + this->Moc.MacroNames.end()); + info.SetArray("MOC_MACRO_NAMES", this->Moc.MacroNames); info.SetArrayArray( "MOC_DEPEND_FILTERS", this->Moc.DependFilters, diff --git a/Tests/QtAutogen/MocInterfaceMacroNames/CMakeLists.txt b/Tests/QtAutogen/MocInterfaceMacroNames/CMakeLists.txt new file mode 100644 index 0000000..7744d78 --- /dev/null +++ b/Tests/QtAutogen/MocInterfaceMacroNames/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.16) +project(MocInterfaceMacroNames) + +include("../AutogenCoreTest.cmake") + +set(CMAKE_AUTOMOC ON) + +add_executable(dummy dummy.cpp) +target_link_libraries(dummy PRIVATE static_lib interface_lib shared_lib) + +add_library(shared_lib SHARED shared_lib.cpp) +set_target_properties(shared_lib PROPERTIES INTERFACE_AUTOMOC_MACRO_NAMES "SHARED_LIB_MACRO") + +add_library(interface_lib INTERFACE) +set_target_properties(interface_lib PROPERTIES INTERFACE_AUTOMOC_MACRO_NAMES "INTERFACE_LIB_MACRO") + +add_library(static_lib STATIC static_lib.cpp) +set_target_properties(static_lib PROPERTIES INTERFACE_AUTOMOC_MACRO_NAMES "STATIC_LIB_MACRO") + +set(AUTOGEN_INFO_FILE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/dummy_autogen.dir/AutogenInfo.json") +set(CHECK_AUTOGEN_JSON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CheckAutogenJson.cmake") +message(STATUS "AutogenInfo.json: ${AUTOGEN_INFO_FILE}") + +add_custom_command(TARGET dummy POST_BUILD + COMMAND ${CMAKE_COMMAND} -DFILE_PATH=${AUTOGEN_INFO_FILE} -P ${CHECK_AUTOGEN_JSON_PATH} +) + +install(TARGETS shared_lib EXPORT shared_lib) +install(TARGETS interface_lib EXPORT interface_lib) +install(TARGETS static_lib EXPORT static_lib) + +install(EXPORT shared_lib FILE shared_libTargets.cmake DESTINATION lib/cmake/shared_lib) +install(EXPORT interface_lib FILE interface_libTargets.cmake DESTINATION lib/cmake/interface_lib) +install(EXPORT static_lib FILE static_libTargets.cmake DESTINATION lib/cmake/static_lib) + +set(CHECK_EXPORT_TARGETS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CheckExportTargets.cmake") +set(EXPORT_FOLDER_PATH "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Export") + +add_custom_command(TARGET dummy POST_BUILD + COMMAND ${CMAKE_COMMAND} -DFOLDER_PATH=${EXPORT_FOLDER_PATH} -P ${CHECK_EXPORT_TARGETS_PATH} +) + +# check if INTERFACE_AUTOMOC_MACRO_NAMES were transferred to the *_link libraries correctly +add_executable(dummy_link dummy.cpp) +target_link_libraries(dummy_link PRIVATE static_link_lib interface_link_lib shared_link_lib) + +add_library(shared_link_lib SHARED shared_lib.cpp) +target_link_libraries(shared_link_lib PUBLIC shared_lib) + +add_library(interface_link_lib INTERFACE) +target_link_libraries(interface_link_lib INTERFACE interface_lib) + +add_library(static_link_lib STATIC static_lib.cpp) +target_link_libraries(static_link_lib PUBLIC static_lib) + +set(AUTOGEN_INFO_FILE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/dummy_link_autogen.dir/AutogenInfo.json") +message(STATUS "AutogenInfo.json: ${AUTOGEN_INFO_FILE}") + +add_custom_command(TARGET dummy_link POST_BUILD + COMMAND ${CMAKE_COMMAND} -DFILE_PATH=${AUTOGEN_INFO_FILE} -P ${CHECK_AUTOGEN_JSON_PATH} +) diff --git a/Tests/QtAutogen/MocInterfaceMacroNames/CheckAutogenJson.cmake b/Tests/QtAutogen/MocInterfaceMacroNames/CheckAutogenJson.cmake new file mode 100644 index 0000000..338f345 --- /dev/null +++ b/Tests/QtAutogen/MocInterfaceMacroNames/CheckAutogenJson.cmake @@ -0,0 +1,27 @@ + + +set(expected_values "SHARED_LIB_MACRO" "INTERFACE_LIB_MACRO" "STATIC_LIB_MACRO") +function(checkAutoMocMacroNames FILE_PATH) + message(STATUS "Checking for auto moc macro names in ${FILE_PATH}") + file(READ ${FILE_PATH} FILE_CONTENT) + string(JSON MOC_MACRO_NAMES_ARR GET ${FILE_CONTENT} MOC_MACRO_NAMES) + # get the length of MOC_MACRO_NAMES in JSON + string(JSON MOC_MACRO_NAMES_LENGTH LENGTH ${MOC_MACRO_NAMES_ARR}) + if(${MOC_MACRO_NAMES_LENGTH} EQUAL 0) + message(FATAL_ERROR "MOC_MACRO_NAMES is empty") + endif() + message(STATUS "MOC_MACRO_NAMES: ${MOC_MACRO_NAMES_ARR}") + + math(EXPR last_index "${MOC_MACRO_NAMES_LENGTH} - 1") + set(reverse_index ${last_index}) + foreach(expected_value IN LISTS expected_values) + string(JSON element GET ${MOC_MACRO_NAMES_ARR} ${reverse_index}) + # check if element equals to expected value + if(NOT ${element} STREQUAL ${expected_value}) + message(FATAL_ERROR "MOC_MACRO_NAMES is expected to contain ${expected_value} but contains ${element}") + endif() + math(EXPR reverse_index "${reverse_index} - 1") + endforeach() +endfunction() + +checkAutoMocMacroNames(${FILE_PATH}) diff --git a/Tests/QtAutogen/MocInterfaceMacroNames/CheckExportTargets.cmake b/Tests/QtAutogen/MocInterfaceMacroNames/CheckExportTargets.cmake new file mode 100644 index 0000000..9db23f6 --- /dev/null +++ b/Tests/QtAutogen/MocInterfaceMacroNames/CheckExportTargets.cmake @@ -0,0 +1,45 @@ + +set(TARGET_NAMES "static_lib" "shared_lib" "interface_lib") +set(static_lib_FOUND "0") +set(shared_lib_FOUND "0") +set(interface_lib_FOUND "0") + +macro(checkExportTargets FOLDER_PATH) + message("Checking folder: ${FOLDER_PATH}") + file(GLOB sources_list LIST_DIRECTORIES true RELATIVE ${FOLDER_PATH} ${FOLDER_PATH}/*) + message("Found files and folders: ${sources_list}") + foreach(source ${sources_list}) + set(SOURCE_ABS "${FOLDER_PATH}/${source}") + if(IS_DIRECTORY ${SOURCE_ABS}) + message("Found subfolder: ${source}") + checkExportTargets(${SOURCE_ABS}) + else() + message("Found file: ${source}") + foreach(TARGET_NAME ${TARGET_NAMES}) + set(TARGETS_FILE "${TARGET_NAME}Targets.cmake") + if(${source} STREQUAL ${TARGETS_FILE}) + message("Found ${TARGETS_FILE} in ${FOLDER_PATH}") + string(TOUPPER ${TARGET_NAME} TARGET_NAME_UPPER) + set(expected_macro "${TARGET_NAME_UPPER}_MACRO") + set(expected_string "INTERFACE_AUTOMOC_MACRO_NAMES \"${expected_macro}\"") + file(READ ${FOLDER_PATH}/${source} contents) + if (NOT contents MATCHES ${expected_string}) + message(FATAL_ERROR "Expected ${expected_string} in ${FOLDER_PATH}/${source}") + else() + message("Found ${expected_string} in ${FOLDER_PATH}/${source}") + set(${TARGET_NAME}_FOUND "1") + endif() + endif() + endforeach() + endif() + endforeach() +endmacro() + +checkExportTargets(${FOLDER_PATH}) + +foreach(TARGET_NAME ${TARGET_NAMES}) + # check if the target found equals the expected value + if(NOT ${TARGET_NAME}_FOUND STREQUAL "1") + message(FATAL_ERROR "Did not find ${TARGET_NAME}Targets.cmake") + endif() +endforeach() diff --git a/Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp b/Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/Tests/QtAutogen/MocInterfaceMacroNames/shared_lib.cpp b/Tests/QtAutogen/MocInterfaceMacroNames/shared_lib.cpp new file mode 100644 index 0000000..3a5c482 --- /dev/null +++ b/Tests/QtAutogen/MocInterfaceMacroNames/shared_lib.cpp @@ -0,0 +1,6 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + void foo() +{ +} diff --git a/Tests/QtAutogen/MocInterfaceMacroNames/static_lib.cpp b/Tests/QtAutogen/MocInterfaceMacroNames/static_lib.cpp new file mode 100644 index 0000000..3695dc9 --- /dev/null +++ b/Tests/QtAutogen/MocInterfaceMacroNames/static_lib.cpp @@ -0,0 +1,3 @@ +void foo() +{ +} diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake index b507ab5..412d511 100644 --- a/Tests/QtAutogen/Tests.cmake +++ b/Tests/QtAutogen/Tests.cmake @@ -7,6 +7,7 @@ ADD_AUTOGEN_TEST(GlobalAutogenTarget) ADD_AUTOGEN_TEST(GlobalAutogenExecutable) ADD_AUTOGEN_TEST(LowMinimumVersion lowMinimumVersion) ADD_AUTOGEN_TEST(ManySources manySources) +ADD_AUTOGEN_TEST(MocInterfaceMacroNames) ADD_AUTOGEN_TEST(MocOnly mocOnly) ADD_AUTOGEN_TEST(MocOptions mocOptions) ADD_AUTOGEN_TEST(ObjectLibrary someProgram) -- cgit v0.12