mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-01-26 19:09:06 +00:00
Merge topic 'automoc-macro-names'
c5c3aff1f5 Autogen: Add INTERFACE_AUTOMOC_MACRO_NAMES target property 69cf9700e6 Autogen: Defer setup until Generate step 7cecb6353e cmGeneratorTarget: Factor out EvaluatedTargetProperty infrastructure 2daba01ddf cmGeneratorTarget: Avoid incidental include-what-you-use warning 850b4d990c IWYU: Add mapping for 'std::remove_reference<Defer &>::type' Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !8391
This commit is contained in:
commit
e245b4df75
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3,7 +3,7 @@ AUTOMOC_MACRO_NAMES
|
||||
|
||||
.. versionadded:: 3.10
|
||||
|
||||
A :ref:`semicolon-separated list <CMake Language Lists>` list of macro names used by
|
||||
A :ref:`semicolon-separated list <CMake Language Lists>` 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")
|
||||
|
||||
89
Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst
Normal file
89
Help/prop_tgt/INTERFACE_AUTOMOC_MACRO_NAMES.rst
Normal file
@ -0,0 +1,89 @@
|
||||
INTERFACE_AUTOMOC_MACRO_NAMES
|
||||
-----------------------------
|
||||
|
||||
.. versionadded:: 3.27
|
||||
|
||||
A :ref:`semicolon-separated list <CMake Language Lists>` 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``.
|
||||
5
Help/release/dev/automoc-macro-names.rst
Normal file
5
Help/release/dev/automoc-macro-names.rst
Normal file
@ -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.
|
||||
@ -193,6 +193,8 @@ add_library(
|
||||
cmDyndepCollation.h
|
||||
cmELF.h
|
||||
cmELF.cxx
|
||||
cmEvaluatedTargetProperty.cxx
|
||||
cmEvaluatedTargetProperty.h
|
||||
cmExprParserHelper.cxx
|
||||
cmExportBuildAndroidMKGenerator.h
|
||||
cmExportBuildAndroidMKGenerator.cxx
|
||||
|
||||
111
Source/cmEvaluatedTargetProperty.cxx
Normal file
111
Source/cmEvaluatedTargetProperty.cxx
Normal file
@ -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 <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#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<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> 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<cmLinkImplItem> const& libraries)
|
||||
{
|
||||
for (cmLinkImplItem const& lib : libraries) {
|
||||
if (lib.Target) {
|
||||
EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
|
||||
// Pretend $<TARGET_PROPERTY:lib.Target,prop> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Source/cmEvaluatedTargetProperty.h
Normal file
80
Source/cmEvaluatedTargetProperty.h
Normal file
@ -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 <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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<std::string> 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<EvaluatedTargetPropertyEntry> Entries;
|
||||
bool HadContextSensitiveCondition = false;
|
||||
};
|
||||
|
||||
EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
|
||||
cmGeneratorTarget const* thisTarget, std::string const& config,
|
||||
std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
|
||||
std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> 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);
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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<cmGeneratorTarget>(
|
||||
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<std::string> 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<std::string> PropertyValue;
|
||||
};
|
||||
cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
|
||||
|
||||
class TargetPropertyEntryGenex : public cmGeneratorTarget::TargetPropertyEntry
|
||||
{
|
||||
@ -150,37 +158,6 @@ private:
|
||||
const std::unique_ptr<cmCompiledGeneratorExpression> ge;
|
||||
};
|
||||
|
||||
class TargetPropertyEntryString : public cmGeneratorTarget::TargetPropertyEntry
|
||||
{
|
||||
public:
|
||||
TargetPropertyEntryString(BT<std::string> 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<std::string> PropertyValue;
|
||||
};
|
||||
|
||||
class TargetPropertyEntryFileSet
|
||||
: public cmGeneratorTarget::TargetPropertyEntry
|
||||
{
|
||||
@ -263,6 +240,18 @@ std::unique_ptr<
|
||||
cm::make_unique<TargetPropertyEntryString>(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<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& 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<std::string> 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<EvaluatedTargetPropertyEntry> Entries;
|
||||
bool HadContextSensitiveCondition = false;
|
||||
};
|
||||
|
||||
EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
|
||||
cmGeneratorTarget const* thisTarget, std::string const& config,
|
||||
std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
|
||||
std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> 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<cmLinkImplItem> const& libraries)
|
||||
{
|
||||
for (cmLinkImplItem const& lib : libraries) {
|
||||
if (lib.Target) {
|
||||
EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
|
||||
// Pretend $<TARGET_PROPERTY:lib.Target,prop> 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,
|
||||
@ -8977,10 +8825,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();
|
||||
|
||||
|
||||
@ -1291,3 +1291,25 @@ private:
|
||||
};
|
||||
mutable std::map<std::string, InfoByConfig> 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;
|
||||
};
|
||||
|
||||
@ -1544,8 +1544,9 @@ bool cmGlobalGenerator::Compute()
|
||||
}
|
||||
|
||||
#ifndef CMAKE_BOOTSTRAP
|
||||
cmQtAutoGenGlobalInitializer qtAutoGen(this->LocalGenerators);
|
||||
if (!qtAutoGen.InitializeCustomTargets()) {
|
||||
this->QtAutoGen =
|
||||
cm::make_unique<cmQtAutoGenGlobalInitializer>(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());
|
||||
|
||||
@ -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<std::unique_ptr<cmMakefile>> Makefiles;
|
||||
LocalGeneratorVector LocalGenerators;
|
||||
|
||||
#ifndef CMAKE_BOOTSTRAP
|
||||
std::unique_ptr<cmQtAutoGenGlobalInitializer> QtAutoGen;
|
||||
#endif
|
||||
|
||||
cmMakefile* CurrentConfigureMakefile;
|
||||
// map from project name to vector of local generators in that project
|
||||
std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
|
||||
|
||||
@ -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,
|
||||
|
||||
61
Tests/QtAutogen/MocInterfaceMacroNames/CMakeLists.txt
Normal file
61
Tests/QtAutogen/MocInterfaceMacroNames/CMakeLists.txt
Normal file
@ -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}
|
||||
)
|
||||
@ -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})
|
||||
@ -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()
|
||||
4
Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp
Normal file
4
Tests/QtAutogen/MocInterfaceMacroNames/dummy.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
6
Tests/QtAutogen/MocInterfaceMacroNames/shared_lib.cpp
Normal file
6
Tests/QtAutogen/MocInterfaceMacroNames/shared_lib.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void foo()
|
||||
{
|
||||
}
|
||||
3
Tests/QtAutogen/MocInterfaceMacroNames/static_lib.cpp
Normal file
3
Tests/QtAutogen/MocInterfaceMacroNames/static_lib.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
void foo()
|
||||
{
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -99,6 +99,7 @@
|
||||
{ symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<60, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1000> > >::type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "__gnu_cxx::__enable_if<true, bool>::__type", private, "\"cmConfigure.h\"", public ] },
|
||||
{ symbol: [ "std::remove_reference<Defer &>::type", private, "\"cmConfigure.h\"", public ] },
|
||||
|
||||
# Wrappers for 3rd-party libraries
|
||||
{ include: [ "@<.*curl/curlver.h>", private, "<cm3p/curl/curl.h>", public ] },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user