Commit 7bed0507 authored by Brad King's avatar Brad King Committed by Kitware Robot
Browse files

Merge topic 'autogen_origin_depends'

47f9c15c Autogen: Update <ORIGIN>_autogen target documentation
336893d9 Autogen: Separate AUTOGEN_TARGET_DEPENDS tests into own tests suite
846043dd Autogen: Rename MocDepends test to AutogenOriginDependsOn
b71a9598 Autogen: Add test for AUTOGEN_ORIGIN_DEPENDS=OFF
f74c4065 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS release notes
0669de5d Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS documentation
b5e895b5

 Autogen: Add (CMAKE_)AUTOGEN_ORIGIN_DEPENDS support
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !2518
parents d80aaad4 47f9c15c
......@@ -124,6 +124,7 @@ Properties on Targets
/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG
/prop_tgt/ARCHIVE_OUTPUT_NAME
/prop_tgt/AUTOGEN_BUILD_DIR
/prop_tgt/AUTOGEN_ORIGIN_DEPENDS
/prop_tgt/AUTOGEN_PARALLEL
/prop_tgt/AUTOGEN_TARGET_DEPENDS
/prop_tgt/AUTOMOC_COMPILER_PREDEFINES
......
......@@ -44,14 +44,10 @@ Qt Build Tools
Qt relies on some bundled tools for code generation, such as ``moc`` for
meta-object code generation, ``uic`` for widget layout and population,
and ``rcc`` for virtual filesystem content generation. These tools may be
and ``rcc`` for virtual file system content generation. These tools may be
automatically invoked by :manual:`cmake(1)` if the appropriate conditions
are met. The automatic tool invocation may be used with both Qt 4 and Qt 5.
The tools are executed as part of a synthesized custom target generated by
CMake. Target dependencies may be added to that custom target by adding them
to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property.
AUTOMOC
^^^^^^^
......@@ -214,19 +210,31 @@ overrides options from the :prop_tgt:`AUTORCC_OPTIONS` target property.
Source files can be excluded from :prop_tgt:`AUTORCC` processing by
enabling :prop_sf:`SKIP_AUTORCC` or the broader :prop_sf:`SKIP_AUTOGEN`.
The ``<ORIGIN>_autogen`` target
===============================
The ``moc`` and ``uic`` tools are executed as part of a synthesized
``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` generated by
CMake. By default that ``<ORIGIN>_autogen`` target inherits the dependencies
of the ``<ORIGIN>`` target (see :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`).
Target dependencies may be added to the ``<ORIGIN>_autogen`` target by adding
them to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property.
Visual Studio Generators
========================
When using the :manual:`Visual Studio generators <cmake-generators(7)>`,
CMake uses a ``PRE_BUILD`` :command:`custom command <add_custom_command>` for
:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
If the :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` processing depends on files,
a :command:`custom target <add_custom_target>` is used instead.
This happens when
- The origin target depends on :prop_sf:`GENERATED` files which aren't excluded
from :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` by :prop_sf:`SKIP_AUTOMOC`,
:prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` or :policy:`CMP0071`
When using the :manual:`Visual Studio generators <cmake-generators(7)>`, CMake
generates a ``PRE_BUILD`` :command:`custom command <add_custom_command>`
instead of the ``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>`
(for :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`).
This isn't always possible though and
an ``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` is used,
when either
- the ``<ORIGIN>`` target depends on :prop_sf:`GENERATED` files which aren't
excluded from :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` by
:prop_sf:`SKIP_AUTOMOC`, :prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN`
or :policy:`CMP0071`
- :prop_tgt:`AUTOGEN_TARGET_DEPENDS` lists a source file
qtmain.lib on Windows
......
......@@ -309,6 +309,7 @@ Variables that Control the Build
/variable/CMAKE_ANDROID_STL_TYPE
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS
/variable/CMAKE_AUTOGEN_PARALLEL
/variable/CMAKE_AUTOGEN_VERBOSE
/variable/CMAKE_AUTOMOC
......
AUTOGEN_ORIGIN_DEPENDS
----------------------
Switch for forwarding origin target dependencies to the corresponding
``_autogen`` target.
Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property
``ON`` have a corresponding ``_autogen`` target which is used to auto generate
``moc`` and ``uic`` files. As this ``_autogen`` target is created at
generate-time, it is not possible to define dependencies of it,
such as to create inputs for the ``moc`` or ``uic`` executable.
The dependencies of the ``_autogen`` target are composed from
- the origin target dependencies
(by default enabled via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`)
- user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS`
:prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` decides whether the origin target
dependencies should be forwarded to the ``_autogen`` target or not.
By default :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` is initialized from
:variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` which is ``ON`` by default.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.
......@@ -9,9 +9,15 @@ Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property
generate-time, it is not possible to define dependencies of it,
such as to create inputs for the ``moc`` or ``uic`` executable.
The :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set instead to a
list of dependencies of the ``_autogen`` target. Dependencies can be target
names or file names.
The dependencies of the ``_autogen`` target are composed from
- the origin target dependencies
(by default enabled via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`)
- user defined dependencies from :prop_tgt:`AUTOGEN_TARGET_DEPENDS`
The :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property can be set to a
list of additional dependencies for the ``_autogen`` target. Dependencies
can be target names or file names.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.
......
......@@ -3,8 +3,8 @@ AUTOMOC
Should the target be processed with automoc (for Qt projects).
AUTOMOC is a boolean specifying whether CMake will handle the Qt ``moc``
preprocessor automatically, i.e. without having to use the
:prop_tgt:`AUTOMOC` is a boolean specifying whether CMake will handle the Qt
``moc`` preprocessor automatically, i.e. without having to use the
:module:`QT4_WRAP_CPP() <FindQt4>` or QT5_WRAP_CPP() macro.
Currently Qt4 and Qt5 are supported.
......
......@@ -3,7 +3,7 @@ AUTORCC
Should the target be processed with autorcc (for Qt projects).
``AUTORCC`` is a boolean specifying whether CMake will handle
:prop_tgt:`AUTORCC` is a boolean specifying whether CMake will handle
the Qt ``rcc`` code generator automatically, i.e. without having to use
the :module:`QT4_ADD_RESOURCES() <FindQt4>` or ``QT5_ADD_RESOURCES()``
macro. Currently Qt4 and Qt5 are supported.
......
......@@ -3,7 +3,7 @@ AUTOUIC
Should the target be processed with autouic (for Qt projects).
``AUTOUIC`` is a boolean specifying whether CMake will handle
:prop_tgt:`AUTOUIC` is a boolean specifying whether CMake will handle
the Qt ``uic`` code generator automatically, i.e. without having to use
the :module:`QT4_WRAP_UI() <FindQt4>` or ``QT5_WRAP_UI()`` macro. Currently
Qt4 and Qt5 are supported.
......
autogen-origin-depends
----------------------
* A new :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` variable and
:prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` target property may be set to enable or
disable forwarding of the origin target dependencies to the corresponding
``_autogen`` target.
CMAKE_AUTOGEN_ORIGIN_DEPENDS
----------------------------
Switch for forwarding origin target dependencies to the corresponding
``_autogen`` targets.
This variable is used to initialize the :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`
property on all the targets. See that target property for additional
information.
By default :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` is ``ON``.
......@@ -23,6 +23,8 @@ set(CMAKE_DL_LIBS "dl")
set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE")
......
......@@ -322,6 +322,9 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Autogen target: Compute user defined dependencies
{
this->AutogenTarget.DependOrigin =
this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
std::string const deps =
this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
......@@ -904,7 +907,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Add link library target dependencies to the autogen target
// dependencies
{
if (this->AutogenTarget.DependOrigin) {
// 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> commonTargets;
......@@ -941,8 +944,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
new cmGeneratorTarget(autogenTarget, localGen));
// Forward origin utilities to autogen target
for (BT<std::string> const& depName : this->Target->GetUtilities()) {
autogenTarget->AddUtility(depName.Value, makefile);
if (this->AutogenTarget.DependOrigin) {
for (BT<std::string> const& depName : this->Target->GetUtilities()) {
autogenTarget->AddUtility(depName.Value, makefile);
}
}
// Add additional autogen target dependencies to autogen target
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
......
......@@ -107,6 +107,7 @@ private:
std::string SettingsFile;
std::map<std::string, std::string> ConfigSettingsFile;
// Dependencies
bool DependOrigin = false;
std::set<std::string> DependFiles;
std::set<cmTarget*> DependTargets;
// Sources to process
......
......@@ -239,6 +239,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->SetPropertyDefault("AUTOMOC", nullptr);
this->SetPropertyDefault("AUTOUIC", nullptr);
this->SetPropertyDefault("AUTORCC", nullptr);
this->SetPropertyDefault("AUTOGEN_ORIGIN_DEPENDS", nullptr);
this->SetPropertyDefault("AUTOGEN_PARALLEL", nullptr);
this->SetPropertyDefault("AUTOMOC_COMPILER_PREDEFINES", nullptr);
this->SetPropertyDefault("AUTOMOC_DEPEND_FILTERS", nullptr);
......
cmake_minimum_required(VERSION 3.11)
project(AutogenOriginDependsOff)
include("../AutogenTest.cmake")
set(CSD ${CMAKE_CURRENT_SOURCE_DIR})
set(CBD ${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CSD})
include_directories(${CBD})
# A GENERATED file ensures there will be an _autogen target in VS
add_custom_command (
OUTPUT "${CBD}/config.hpp"
COMMAND ${CMAKE_COMMAND} -E copy "${CSD}/config.hpp.in" "${CBD}/config.hpp"
)
# Library "a_mc" provides a header that holds a string with the content of
# mocs_compilation.cpp from a_qt. It therefore must depend on a_qt_autogen.
add_custom_target ( a_mc
COMMAND ${CMAKE_COMMAND} -E sleep 2
COMMAND ${CMAKE_COMMAND}
"-DMCF=${CBD}/a_qt_autogen/mocs_compilation.cpp"
"-DCF_IN=${CSD}/a_mc.hpp.in"
"-DCF_OUT=${CBD}/a_mc.hpp"
-P ${CSD}/configure_content.cmake
)
add_dependencies ( a_mc a_qt_autogen )
# Library "a_qt"
# - depends on a GENERATED file
# - AUTOMOC enabled
# - depends on a target (a_mc) that depends on a_qt_qutogen
add_library ( a_qt a_qt.cpp "${CBD}/config.hpp" )
add_dependencies ( a_qt a_mc )
target_link_libraries ( a_qt ${QT_QTCORE_TARGET})
set_target_properties ( a_qt PROPERTIES AUTOMOC TRUE)
# Disable AUTOGEN_ORIGIN_DEPENDS to avoid loop dependencies
set_target_properties ( a_qt PROPERTIES AUTOGEN_ORIGIN_DEPENDS OFF)
# Library "b_mc" provides a header that holds a string function that returns
# the content of mocs_compilation.cpp from b_qt.
# It therefore must depend on b_qt_autogen.
add_custom_command (
OUTPUT ${CBD}/b_mc.cpp
DEPENDS b_qt_autogen
COMMAND ${CMAKE_COMMAND} -E sleep 2
COMMAND ${CMAKE_COMMAND}
"-DMCF=${CBD}/b_qt_autogen/mocs_compilation.cpp"
"-DCF_IN=${CSD}/b_mc.cpp.in"
"-DCF_OUT=${CBD}/b_mc.cpp"
-P ${CSD}/configure_content.cmake
)
add_library ( b_mc ${CSD}/b_mc.hpp ${CBD}/b_mc.cpp )
# Library "b_qt"
# - depends on a GENERATED file
# - AUTOMOC enabled
# - depends on a library (b_mc) that depends on b_qt_qutogen
add_library ( b_qt b_qt.cpp "${CBD}/config.hpp" )
target_link_libraries ( b_qt b_mc )
target_link_libraries ( b_qt ${QT_QTCORE_TARGET})
set_target_properties ( b_qt PROPERTIES AUTOMOC TRUE)
# Disable AUTOGEN_ORIGIN_DEPENDS to avoid loop dependencies
set_target_properties ( b_qt PROPERTIES AUTOGEN_ORIGIN_DEPENDS OFF)
# The main target depends on both libraries which depend on the _autogen
# target of the main target.
add_executable ( autogenOriginDependsOff main.cpp )
target_link_libraries ( autogenOriginDependsOff a_qt b_qt )
#ifndef A_MC_HPP
#define A_MC_HPP
namespace a_mc {
char const* mocs_compilation = "@MOCS_COMPILATION@";
}
#endif
#include "a_qt.hpp"
#include <a_mc.hpp>
namespace a_qt {
/// @brief A source local QObject based class
class Source_QObject : public QObject
{
Q_OBJECT
public:
Source_QObject() {}
~Source_QObject() {}
std::string str;
};
std::string mocs_compilation()
{
// Create and destroy QObject based classes
Header_QObject header_obj;
Source_QObject source_obj;
return std::string(a_mc::mocs_compilation);
}
}
#include "a_qt.moc"
#ifndef A_QT_HPP
#define A_QT_HPP
#include <QObject>
#include <config.hpp>
#include <string>
namespace a_qt {
/// @brief A header local QObject based class
class Header_QObject : public QObject
{
Q_OBJECT
public:
Header_QObject() {}
~Header_QObject() {}
std::string str;
};
/// @brief Function that returns the content of mocs_compilation.cpp
extern std::string mocs_compilation();
}
#endif
#include <b_mc.hpp>
namespace b_mc {
char const* mocs_compilation()
{
return "@MOCS_COMPILATION@";
}
}
#ifndef B_MC_HPP
#define B_MC_HPP
namespace b_mc {
extern char const* mocs_compilation();
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment