Commit ac14cbf0 authored by Brad King's avatar Brad King

Allow add_dependencies() on INTERFACE libraries (#15414)

Revert commit v3.0.0-rc1~175^2~20 (add_dependencies: Disallow use with
INTERFACE_LIBRARY, 2013-12-25).  Teach our dependency analysis to
transitively follow INTERFACE target utility dependencies as was done or
IMPORTED targets in commit v2.8.6~127^2~1 (Allow add_dependencies() on
imported targets, 2010-11-19).  Extend the InterfaceLibrary test with a
case to cover header generation for a header-only INTERFACE library via
a custom target.
parent 817d31db
......@@ -13,8 +13,8 @@ is one created by one of the :command:`add_executable`,
:command:`add_library`, or :command:`add_custom_target` commands.
Dependencies added to an :ref:`imported target <Imported Targets>`
are followed transitively in its place since the target itself does
not build.
or an :ref:`interface library <Interface Libraries>` are followed
transitively in its place since the target itself does not build.
See the ``DEPENDS`` option of :command:`add_custom_target` and
:command:`add_custom_command` commands for adding file-level
......
add_dependencies-INTERFACE-libraries
------------------------------------
* The :command:`add_dependencies` command learned to allow dependencies
to be added to :ref:`interface libraries <Interface Libraries>`.
Dependencies added to an interface library are followed transitively
in its place since the target itself does not build.
......@@ -33,15 +33,6 @@ bool cmAddDependenciesCommand
}
if(cmTarget* target = this->Makefile->FindTargetToUse(target_name))
{
if (target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
std::ostringstream e;
e << "Cannot add target-level dependencies to INTERFACE library "
"target \"" << target_name << "\".\n";
this->SetError(e.str());
return false;
}
std::vector<std::string>::const_iterator s = args.begin();
++s; // skip over target_name
for (; s != args.end(); ++s)
......
......@@ -418,9 +418,11 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
cmTarget const* dependee,
bool linking)
{
if(dependee->IsImported())
if(dependee->IsImported() ||
dependee->GetType() == cmTarget::INTERFACE_LIBRARY)
{
// Skip imported targets but follow their utility dependencies.
// Skip IMPORTED and INTERFACE targets but follow their utility
// dependencies.
std::set<cmLinkItem> const& utils = dependee->GetUtilityItems();
for(std::set<cmLinkItem>::const_iterator i = utils.begin();
i != utils.end(); ++i)
......
......@@ -3,6 +3,11 @@ set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
add_library(headeriface INTERFACE)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h"
"#define IFACE_HEADER_BUILDDIR\n"
)
add_custom_target(headeriface_gen
COMMENT "Generating iface_header_builddir.h"
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/iface_header_builddir.h.in
${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h
VERBATIM
)
add_dependencies(headeriface headeriface_gen)
......@@ -7,5 +7,4 @@ run_cmake(whitelist)
run_cmake(invalid_signature)
run_cmake(global-interface)
run_cmake(genex_link)
run_cmake(add_dependencies)
run_cmake(add_custom_command-TARGET)
CMake Error at add_dependencies.cmake:4 \(add_dependencies\):
add_dependencies Cannot add target-level dependencies to INTERFACE library
target "iface".
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
add_library(foo empty.cpp)
add_library(iface INTERFACE)
add_dependencies(iface foo)
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