mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Autogen: Reduce the number of targets under Visual Studio
Commit 680fbb112a (Autogen: Enable depfile support for Visual Studio and
Xcode generators) disabled the PRE_BUILD optimization when a depfile is
used, because a PRE_BUILD event cannot carry depfile dependencies. Since
then, every target with AUTOMOC or AUTOUIC enabled gains an
'<ORIGIN>_autogen' and an '<ORIGIN>_autogen_timestamp_deps' target,
which the Visual Studio generators turn into two extra projects per
target in the generated solution.
Attach the autogen custom command to the origin target instead. The
custom command still carries the depfile, and the dependencies of the
origin target provide the ordering that
'<ORIGIN>_autogen_timestamp_deps' provides otherwise, because MSBuild
builds all referenced projects before any step of the referencing
project.
Use the conditions of the PRE_BUILD event, so that the
'<ORIGIN>_autogen' target keeps existing wherever it existed before
depfiles were enabled for the Visual Studio generators. In particular,
projects that name the target in add_dependencies() keep working.
Ninja and the Makefile generators keep the separate targets. Extra
targets have no cost for them, and '<ORIGIN>_autogen' has always existed
there.
The Xcode generator gained the same two targets per origin target in
4.4, but attaching the custom command there needs some more thoughts on
the per-config timestamp file first: Xcode rejects targets whose sources
vary by configuration, and with AUTOGEN_BETTER_GRAPH_MULTI_CONFIG the
timestamp file is per configuration.
Fixes: #28034
Fixes: #28033
This commit is contained in:
@@ -231,31 +231,58 @@ Target dependencies may be added to the ``<ORIGIN>_autogen`` target by adding
|
||||
them to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property.
|
||||
|
||||
.. note::
|
||||
If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or
|
||||
:ref:`Makefile Generators`, see :ref:`<ORIGIN>_autogen_timestamp_deps`.
|
||||
If Qt 5.15 or later is used and a depfile is used to track the ``moc``
|
||||
dependencies, see :ref:`<ORIGIN>_autogen_timestamp_deps`. When using the
|
||||
:ref:`Visual Studio Generators`, the ``<ORIGIN>_autogen`` target may not be
|
||||
created at all, see `Visual Studio Generators`_ below.
|
||||
|
||||
.. _`<ORIGIN>_autogen_timestamp_deps`:
|
||||
|
||||
The ``<ORIGIN>_autogen_timestamp_deps`` target
|
||||
==============================================
|
||||
|
||||
If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or
|
||||
:ref:`Makefile Generators`, the ``<ORIGIN>_autogen_timestamp_deps`` target is
|
||||
also created in addition to the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
|
||||
If Qt 5.15 or later is used and the generator is :generator:`Ninja`, a
|
||||
:ref:`Makefile <Makefile Generators>` generator, a
|
||||
:ref:`Visual Studio <Visual Studio Generators>` generator or
|
||||
:generator:`Xcode`, the ``moc`` dependencies are tracked with a depfile. In
|
||||
that case the ``<ORIGIN>_autogen_timestamp_deps`` target is also created in
|
||||
addition to the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
|
||||
target. This target does not have any sources or commands to execute, but it
|
||||
has dependencies that were previously inherited by the pre-Qt 5.15
|
||||
:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
|
||||
These dependencies will serve as a list of order-only dependencies for the
|
||||
custom command, without forcing the custom command to re-execute.
|
||||
|
||||
.. versionadded:: 4.4
|
||||
Depfile support for the :ref:`Visual Studio Generators` and
|
||||
:generator:`Xcode`. Earlier versions used a depfile only for the
|
||||
:generator:`Ninja` and :ref:`Makefile Generators`.
|
||||
|
||||
.. note::
|
||||
When using the :ref:`Visual Studio Generators`, neither this target nor the
|
||||
:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target is created in the common
|
||||
case, see `Visual Studio Generators`_ below.
|
||||
|
||||
Visual Studio Generators
|
||||
========================
|
||||
|
||||
When using the :ref:`Visual Studio Generators`, CMake
|
||||
generates a ``PRE_BUILD`` :command:`custom command <add_custom_command>`
|
||||
instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
|
||||
When using the :ref:`Visual Studio Generators`, CMake adds the ``moc`` and
|
||||
``uic`` step to the ``<ORIGIN>`` project itself instead of creating the
|
||||
:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
|
||||
:command:`custom target <add_custom_target>` (for :prop_tgt:`AUTOMOC` and
|
||||
:prop_tgt:`AUTOUIC`). This isn't always possible though and an
|
||||
:prop_tgt:`AUTOUIC`). With Qt 5.15 or later, the step is a
|
||||
:command:`custom command <add_custom_command>` with a depfile, and therefore
|
||||
runs only when one of its dependencies changed. With earlier Qt versions it is
|
||||
a ``PRE_BUILD`` command that runs on every build of ``<ORIGIN>``.
|
||||
|
||||
.. versionchanged:: 4.4.3
|
||||
With Qt 5.15 or later, the ``moc`` and ``uic`` step is a custom command in
|
||||
the ``<ORIGIN>`` project. CMake 4.4.0 through 4.4.2 created the
|
||||
:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` and
|
||||
:ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
targets instead.
|
||||
|
||||
This isn't always possible though and an
|
||||
:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
|
||||
:command:`custom target <add_custom_target>` is used, when either
|
||||
|
||||
@@ -266,6 +293,10 @@ instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`
|
||||
- :prop_tgt:`AUTOGEN_TARGET_DEPENDS` lists a source file
|
||||
- :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled
|
||||
|
||||
With Qt 5.15 or later, the
|
||||
:ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>` target
|
||||
is created along with it.
|
||||
|
||||
qtmain.lib on Windows
|
||||
=====================
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@ Switch for forwarding origin target dependencies to the corresponding
|
||||
|
||||
.. note::
|
||||
|
||||
If Qt 5.15 or later is used and the generator is either :generator:`Ninja`
|
||||
or :ref:`Makefile Generators`, origin target dependencies are forwarded to
|
||||
the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
target instead of :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`.
|
||||
If the
|
||||
:ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
target is created, origin target dependencies are forwarded to it instead
|
||||
of :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`. When using the
|
||||
:ref:`Visual Studio Generators`, the ``moc`` and ``uic`` step may be part
|
||||
of the ``<ORIGIN>`` target itself, in which case they need no forwarding.
|
||||
See the :manual:`cmake-qt(7)` manual for details.
|
||||
|
||||
Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property
|
||||
``ON`` have a corresponding :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target
|
||||
|
||||
@@ -6,10 +6,13 @@ Additional target dependencies of the corresponding
|
||||
|
||||
.. note::
|
||||
|
||||
If Qt 5.15 or later is used and the generator is either :generator:`Ninja`
|
||||
or :ref:`Makefile Generators`, additional target dependencies are added to
|
||||
the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
target instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
|
||||
If the
|
||||
:ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
target is created, additional target dependencies are added to it instead
|
||||
of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. When using the
|
||||
:ref:`Visual Studio Generators`, the ``moc`` and ``uic`` step may be part
|
||||
of the ``<ORIGIN>`` target itself, in which case the dependencies are added
|
||||
to ``<ORIGIN>``. See the :manual:`cmake-qt(7)` manual for details.
|
||||
|
||||
|
||||
Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property
|
||||
|
||||
@@ -8,10 +8,13 @@ Switch for forwarding origin target dependencies to the corresponding
|
||||
|
||||
.. note::
|
||||
|
||||
If Qt 5.15 or later is used and the generator is either :generator:`Ninja`
|
||||
or :ref:`Makefile Generators`, additional target dependencies are added to
|
||||
the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
target instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target.
|
||||
If the
|
||||
:ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>`
|
||||
target is created, additional target dependencies are added to it instead
|
||||
of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. When using the
|
||||
:ref:`Visual Studio Generators`, the ``moc`` and ``uic`` step may be part
|
||||
of the ``<ORIGIN>`` target itself, in which case the dependencies are added
|
||||
to ``<ORIGIN>``. See the :manual:`cmake-qt(7)` manual for details.
|
||||
|
||||
This variable is used to initialize the :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`
|
||||
property on all the targets. See that target property for additional
|
||||
|
||||
@@ -1373,6 +1373,16 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
gen.find("Visual Studio") != std::string::npos || gen == "Xcode");
|
||||
}();
|
||||
|
||||
// Under VS, attach the autogen custom command to the origin target instead
|
||||
// of creating separate targets, to reduce the number of targets loaded into
|
||||
// the IDE. The dependencies of the origin target then provide the ordering
|
||||
// that '_autogen_timestamp_deps' provides otherwise. The conditions match
|
||||
// those of the PRE_BUILD event below, so that the '_autogen' target keeps
|
||||
// existing wherever it did before depfiles were enabled for VS.
|
||||
bool const attachToOrigin = useDepfile &&
|
||||
this->AutogenTarget.DependFiles.empty() &&
|
||||
!this->AutogenTarget.GlobalTarget && this->GlobalGen->IsVisualStudio();
|
||||
|
||||
// Files provided by the autogen target
|
||||
std::vector<std::string> autogenByproducts;
|
||||
std::vector<std::string> timestampByproducts;
|
||||
@@ -1406,6 +1416,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
}
|
||||
}
|
||||
|
||||
if (attachToOrigin) {
|
||||
// Without an autogen target the timestamp command provides all byproducts.
|
||||
cm::append(timestampByproducts, autogenByproducts);
|
||||
autogenByproducts.clear();
|
||||
}
|
||||
|
||||
// Compose target comment
|
||||
std::string autogenComment;
|
||||
{
|
||||
@@ -1517,8 +1533,9 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
} else {
|
||||
|
||||
// Add link library target dependencies to the autogen target
|
||||
// dependencies
|
||||
if (this->AutogenTarget.DependOrigin) {
|
||||
// dependencies. Not needed when attaching to the origin target, which
|
||||
// already depends on its own link libraries.
|
||||
if (this->AutogenTarget.DependOrigin && !attachToOrigin) {
|
||||
// add_dependencies/addUtility do not support generator expressions.
|
||||
// We depend only on the libraries found in all configs therefore.
|
||||
std::map<cmGeneratorTarget const*, std::size_t> targetsPartOfAllConfigs;
|
||||
@@ -1555,41 +1572,43 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
if (useDepfile) {
|
||||
// Create a custom command that generates a timestamp file and
|
||||
// has a depfile assigned. The depfile is created by JobDepFilesMergeT.
|
||||
//
|
||||
// Also create an additional '_autogen_timestamp_deps' that the custom
|
||||
// command will depend on. It will have no sources or commands to
|
||||
// execute, but it will have dependencies that would originally be
|
||||
// assigned to the pre-Qt 5.15 'autogen' target. These dependencies will
|
||||
// serve as a list of order-only dependencies for the custom command,
|
||||
// without forcing the custom command to re-execute.
|
||||
//
|
||||
// The dependency tree would then look like
|
||||
// '_autogen_timestamp_deps (order-only)' <- '/timestamp' file <-
|
||||
// '_autogen' target.
|
||||
auto const timestampTargetName =
|
||||
cmStrCat(this->GenTarget->GetName(), "_autogen_timestamp_deps");
|
||||
if (!attachToOrigin) {
|
||||
// Also create an additional '_autogen_timestamp_deps' that the custom
|
||||
// command will depend on. It will have no sources or commands to
|
||||
// execute, but it will have dependencies that would originally be
|
||||
// assigned to the pre-Qt 5.15 'autogen' target. These dependencies
|
||||
// will serve as a list of order-only dependencies for the custom
|
||||
// command, without forcing the custom command to re-execute.
|
||||
//
|
||||
// The dependency tree would then look like
|
||||
// '_autogen_timestamp_deps (order-only)' <- '/timestamp' file <-
|
||||
// '_autogen' target.
|
||||
auto const timestampTargetName =
|
||||
cmStrCat(this->GenTarget->GetName(), "_autogen_timestamp_deps");
|
||||
|
||||
auto cc = cm::make_unique<cmCustomCommand>();
|
||||
cc->SetWorkingDirectory(this->Dir.Work.c_str());
|
||||
cc->SetDepends(dependencies);
|
||||
cc->SetEscapeOldStyle(false);
|
||||
timestampTarget = this->LocalGen->AddUtilityCommand(timestampTargetName,
|
||||
true, std::move(cc));
|
||||
auto cc = cm::make_unique<cmCustomCommand>();
|
||||
cc->SetWorkingDirectory(this->Dir.Work.c_str());
|
||||
cc->SetDepends(dependencies);
|
||||
cc->SetEscapeOldStyle(false);
|
||||
timestampTarget = this->LocalGen->AddUtilityCommand(
|
||||
timestampTargetName, true, std::move(cc));
|
||||
|
||||
this->LocalGen->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(timestampTarget, this->LocalGen));
|
||||
this->LocalGen->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(timestampTarget, this->LocalGen));
|
||||
|
||||
// Set FOLDER property on the timestamp target, so it appears in the
|
||||
// appropriate folder in an IDE or in the file api.
|
||||
if (!this->TargetsFolder.empty()) {
|
||||
timestampTarget->SetProperty("FOLDER", this->TargetsFolder);
|
||||
// Set FOLDER property on the timestamp target, so it appears in the
|
||||
// appropriate folder in an IDE or in the file api.
|
||||
if (!this->TargetsFolder.empty()) {
|
||||
timestampTarget->SetProperty("FOLDER", this->TargetsFolder);
|
||||
}
|
||||
|
||||
// Make '/timestamp' file depend on '_autogen_timestamp_deps'.
|
||||
dependencies.clear();
|
||||
dependencies.push_back(timestampTargetName);
|
||||
}
|
||||
|
||||
// Make '/timestamp' file depend on '_autogen_timestamp_deps' and on the
|
||||
// moc and uic executables (whichever are enabled).
|
||||
dependencies.clear();
|
||||
dependencies.push_back(timestampTargetName);
|
||||
|
||||
// Make '/timestamp' file depend on the moc and uic executables
|
||||
// (whichever are enabled).
|
||||
AddAutogenExecutableToDependencies(this->Moc, dependencies);
|
||||
AddAutogenExecutableToDependencies(this->Uic, dependencies);
|
||||
std::string outputFile;
|
||||
@@ -1634,7 +1653,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
{ cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
|
||||
this->AddGeneratedSource(outputFile, this->Moc);
|
||||
}
|
||||
cc = cm::make_unique<cmCustomCommand>();
|
||||
auto cc = cm::make_unique<cmCustomCommand>();
|
||||
cc->SetOutputs(outputFile);
|
||||
cc->SetByproducts(timestampByproducts);
|
||||
cc->SetDepends(dependencies);
|
||||
@@ -1651,48 +1670,57 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
|
||||
autogenComment.clear();
|
||||
}
|
||||
|
||||
// Create autogen target
|
||||
auto cc = cm::make_unique<cmCustomCommand>();
|
||||
cc->SetWorkingDirectory(this->Dir.Work.c_str());
|
||||
cc->SetByproducts(autogenByproducts);
|
||||
cc->SetDepends(dependencies);
|
||||
cc->SetCommandLines(commandLines);
|
||||
cc->SetEscapeOldStyle(false);
|
||||
cc->SetComment(autogenComment.c_str());
|
||||
cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
|
||||
this->AutogenTarget.Name, true, std::move(cc));
|
||||
// Create autogen generator target
|
||||
this->LocalGen->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(autogenTarget, this->LocalGen));
|
||||
|
||||
// Order the autogen target(s) just before the original target.
|
||||
cmTarget* orderTarget = timestampTarget ? timestampTarget : autogenTarget;
|
||||
// Forward origin utilities to autogen target
|
||||
if (this->AutogenTarget.DependOrigin) {
|
||||
for (BT<std::pair<std::string, bool>> const& depName :
|
||||
this->GenTarget->GetUtilities()) {
|
||||
orderTarget->AddUtility(depName.Value.first, false, this->Makefile);
|
||||
if (attachToOrigin) {
|
||||
// Add additional autogen target dependencies to the origin target
|
||||
for (cmTarget const* depTarget : this->AutogenTarget.DependTargets) {
|
||||
this->GenTarget->Target->AddUtility(depTarget->GetName(), false,
|
||||
this->Makefile);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Create autogen target
|
||||
auto cc = cm::make_unique<cmCustomCommand>();
|
||||
cc->SetWorkingDirectory(this->Dir.Work.c_str());
|
||||
cc->SetByproducts(autogenByproducts);
|
||||
cc->SetDepends(dependencies);
|
||||
cc->SetCommandLines(commandLines);
|
||||
cc->SetEscapeOldStyle(false);
|
||||
cc->SetComment(autogenComment.c_str());
|
||||
cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
|
||||
this->AutogenTarget.Name, true, std::move(cc));
|
||||
// Create autogen generator target
|
||||
this->LocalGen->AddGeneratorTarget(
|
||||
cm::make_unique<cmGeneratorTarget>(autogenTarget, this->LocalGen));
|
||||
|
||||
// Add additional autogen target dependencies to autogen target
|
||||
for (cmTarget const* depTarget : this->AutogenTarget.DependTargets) {
|
||||
orderTarget->AddUtility(depTarget->GetName(), false, this->Makefile);
|
||||
}
|
||||
// Order the autogen target(s) just before the original target.
|
||||
cmTarget* orderTarget =
|
||||
timestampTarget ? timestampTarget : autogenTarget;
|
||||
// Forward origin utilities to autogen target
|
||||
if (this->AutogenTarget.DependOrigin) {
|
||||
for (BT<std::pair<std::string, bool>> const& depName :
|
||||
this->GenTarget->GetUtilities()) {
|
||||
orderTarget->AddUtility(depName.Value.first, false, this->Makefile);
|
||||
}
|
||||
}
|
||||
|
||||
// Set FOLDER property in autogen target
|
||||
if (!this->TargetsFolder.empty()) {
|
||||
autogenTarget->SetProperty("FOLDER", this->TargetsFolder);
|
||||
}
|
||||
// Add additional autogen target dependencies to autogen target
|
||||
for (cmTarget const* depTarget : this->AutogenTarget.DependTargets) {
|
||||
orderTarget->AddUtility(depTarget->GetName(), false, this->Makefile);
|
||||
}
|
||||
|
||||
// Add autogen target to the origin target dependencies
|
||||
this->GenTarget->Target->AddUtility(this->AutogenTarget.Name, false,
|
||||
this->Makefile);
|
||||
// Set FOLDER property in autogen target
|
||||
if (!this->TargetsFolder.empty()) {
|
||||
autogenTarget->SetProperty("FOLDER", this->TargetsFolder);
|
||||
}
|
||||
|
||||
// Add autogen target to the global autogen target dependencies
|
||||
if (this->AutogenTarget.GlobalTarget) {
|
||||
this->GlobalInitializer->AddToGlobalAutoGen(this->LocalGen,
|
||||
this->AutogenTarget.Name);
|
||||
// Add autogen target to the origin target dependencies
|
||||
this->GenTarget->Target->AddUtility(this->AutogenTarget.Name, false,
|
||||
this->Makefile);
|
||||
|
||||
// Add autogen target to the global autogen target dependencies
|
||||
if (this->AutogenTarget.GlobalTarget) {
|
||||
this->GlobalInitializer->AddToGlobalAutoGen(this->LocalGen,
|
||||
this->AutogenTarget.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
enable_language(CXX)
|
||||
|
||||
find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
add_library(simple_lib STATIC simple_lib.cpp)
|
||||
|
||||
# A plain AUTOMOC target gets the autogen custom command attached to itself.
|
||||
add_library(plain_lib STATIC app_qt.cpp)
|
||||
target_link_libraries(plain_lib PRIVATE simple_lib Qt${with_qt_version}::Core)
|
||||
|
||||
# A target that depends on a GENERATED file keeps the separate autogen targets.
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated_dep.h
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/generated_dep.h)
|
||||
add_library(gen_dep_lib STATIC app_qt.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/generated_dep.h)
|
||||
target_link_libraries(gen_dep_lib PRIVATE Qt${with_qt_version}::Core)
|
||||
target_include_directories(gen_dep_lib PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_property(TARGET gen_dep_lib PROPERTY
|
||||
AUTOGEN_TARGET_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/autogen_dep.txt)
|
||||
@@ -84,4 +84,68 @@ Automatic MOC for target sub_exe_2")
|
||||
endif()
|
||||
endblock()
|
||||
endif()
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Visual Studio"
|
||||
AND QtCore_VERSION VERSION_GREATER_EQUAL 5.15.0)
|
||||
block()
|
||||
macro(check_project_exists target expected)
|
||||
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/${target}.vcxproj")
|
||||
set(actual TRUE)
|
||||
else()
|
||||
set(actual FALSE)
|
||||
endif()
|
||||
if("${actual}" STREQUAL "${expected}")
|
||||
set(check_result "PASSED")
|
||||
set(message_type "STATUS")
|
||||
else()
|
||||
set(check_result "FAILED")
|
||||
set(message_type "FATAL_ERROR")
|
||||
endif()
|
||||
message(${message_type}
|
||||
"QtAutoMocVsTargets-\"${target}.vcxproj\" exists is ${actual}, expected ${expected} - ${check_result}")
|
||||
endmacro()
|
||||
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/QtAutoMocVsTargets-build)
|
||||
run_cmake_with_options(QtAutoMocVsTargets ${RunCMake_TEST_OPTIONS})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
|
||||
# A plain AUTOMOC target does not get extra projects.
|
||||
check_project_exists(plain_lib TRUE)
|
||||
check_project_exists(plain_lib_autogen FALSE)
|
||||
check_project_exists(plain_lib_autogen_timestamp_deps FALSE)
|
||||
# A target with a GENERATED dependency keeps them.
|
||||
check_project_exists(gen_dep_lib_autogen TRUE)
|
||||
check_project_exists(gen_dep_lib_autogen_timestamp_deps TRUE)
|
||||
|
||||
# The first build must run AUTOMOC. Assert it, so that the checks below
|
||||
# cannot pass just because the message is missing from the build output.
|
||||
set(RunCMake_TEST_EXPECT_stdout "Automatic MOC for target plain_lib")
|
||||
run_cmake_command(QtAutoMocVsTargets-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
unset(RunCMake_TEST_EXPECT_stdout)
|
||||
|
||||
set(RunCMake_TEST_NOT_EXPECT_stdout "Automatic MOC for target plain_lib|\
|
||||
Automatic MOC for target gen_dep_lib")
|
||||
# Assert that the depfile prevents AUTOMOC from running again.
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't execute AUTOMOC again")
|
||||
run_cmake_command(QtAutoMocVsTargets-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
# Touch the source file of a library that 'plain_lib' links. This must
|
||||
# not cause a rerun of AUTOMOC.
|
||||
file(TOUCH "${RunCMake_SOURCE_DIR}/simple_lib.cpp")
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't execute AUTOMOC for a dependency change")
|
||||
run_cmake_command(QtAutoMocVsTargets-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
# Files in AUTOGEN_TARGET_DEPENDS are order-only dependencies. Touching
|
||||
# one must not cause a rerun of AUTOMOC either.
|
||||
file(TOUCH "${RunCMake_SOURCE_DIR}/autogen_dep.txt")
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION "-Don't execute AUTOMOC for an AUTOGEN_TARGET_DEPENDS file")
|
||||
run_cmake_command(QtAutoMocVsTargets-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
unset(RunCMake_TEST_NOT_EXPECT_stdout)
|
||||
|
||||
# Another configuration has its own timestamp file, so it builds again.
|
||||
set(RunCMake_TEST_EXPECT_stdout "Automatic MOC for target plain_lib")
|
||||
set(RunCMake_TEST_VARIANT_DESCRIPTION "-Release")
|
||||
run_cmake_command(QtAutoMocVsTargets-build ${CMAKE_COMMAND} --build . --config Release)
|
||||
unset(RunCMake_TEST_EXPECT_stdout)
|
||||
unset(RunCMake_TEST_VARIANT_DESCRIPTION)
|
||||
endblock()
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
A file listed in AUTOGEN_TARGET_DEPENDS.
|
||||
Reference in New Issue
Block a user