Allow add_dependencies() on imported targets (#10395)
Imported targets do not themselves build, but we can follow dependencies through them to find real targets. This allows imported targets to depend on custom targets that provide the underlying files at build time.
This commit is contained in:
parent
bc7395c096
commit
e01cce2869
|
@ -24,11 +24,7 @@ bool cmAddDependenciesCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string target_name = args[0];
|
std::string target_name = args[0];
|
||||||
|
if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str()))
|
||||||
cmTarget* target =
|
|
||||||
this->GetMakefile()->GetLocalGenerator()->
|
|
||||||
GetGlobalGenerator()->FindTarget(0, target_name.c_str());
|
|
||||||
if(target)
|
|
||||||
{
|
{
|
||||||
std::vector<std::string>::const_iterator s = args.begin();
|
std::vector<std::string>::const_iterator s = args.begin();
|
||||||
++s; // skip over target_name
|
++s; // skip over target_name
|
||||||
|
|
|
@ -62,6 +62,8 @@ public:
|
||||||
"top-level target is one created by ADD_EXECUTABLE, ADD_LIBRARY, "
|
"top-level target is one created by ADD_EXECUTABLE, ADD_LIBRARY, "
|
||||||
"or ADD_CUSTOM_TARGET. Adding dependencies with this command "
|
"or ADD_CUSTOM_TARGET. Adding dependencies with this command "
|
||||||
"can be used to make sure one target is built before another target. "
|
"can be used to make sure one target is built before another target. "
|
||||||
|
"Dependencies added to an IMPORTED target are followed transitively "
|
||||||
|
"in its place since the target itself does not build. "
|
||||||
"See the DEPENDS option of ADD_CUSTOM_TARGET "
|
"See the DEPENDS option of ADD_CUSTOM_TARGET "
|
||||||
"and ADD_CUSTOM_COMMAND for adding file-level dependencies in custom "
|
"and ADD_CUSTOM_COMMAND for adding file-level dependencies in custom "
|
||||||
"rules. See the OBJECT_DEPENDS option in "
|
"rules. See the OBJECT_DEPENDS option in "
|
||||||
|
|
|
@ -246,13 +246,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||||
|
|
||||||
// Check the target's makefile first.
|
// Check the target's makefile first.
|
||||||
cmTarget* dependee =
|
cmTarget* dependee =
|
||||||
depender->GetMakefile()->FindTarget(dependee_name);
|
depender->GetMakefile()->FindTargetToUse(dependee_name);
|
||||||
|
|
||||||
// Then search globally.
|
|
||||||
if(!dependee)
|
|
||||||
{
|
|
||||||
dependee = this->GlobalGenerator->FindTarget(0, dependee_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip targets that will not really be linked. This is probably a
|
// Skip targets that will not really be linked. This is probably a
|
||||||
// name conflict between an external library and an executable
|
// name conflict between an external library and an executable
|
||||||
|
@ -264,15 +258,31 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||||
dependee = 0;
|
dependee = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found then skip then the dependee.
|
if(dependee)
|
||||||
if(!dependee)
|
|
||||||
{
|
{
|
||||||
return;
|
this->AddTargetDepend(depender_index, dependee, linking);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No imported targets should have been found.
|
//----------------------------------------------------------------------------
|
||||||
assert(!dependee->IsImported());
|
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||||
|
cmTarget* dependee,
|
||||||
|
bool linking)
|
||||||
|
{
|
||||||
|
if(dependee->IsImported())
|
||||||
|
{
|
||||||
|
// Skip imported targets but follow their utility dependencies.
|
||||||
|
std::set<cmStdString> const& utils = dependee->GetUtilities();
|
||||||
|
for(std::set<cmStdString>::const_iterator i = utils.begin();
|
||||||
|
i != utils.end(); ++i)
|
||||||
|
{
|
||||||
|
cmTarget* transitive_dependee =
|
||||||
|
dependee->GetMakefile()->FindTargetToUse(i->c_str());
|
||||||
|
this->AddTargetDepend(depender_index, transitive_dependee, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Lookup the index for this target. All targets should be known by
|
// Lookup the index for this target. All targets should be known by
|
||||||
// this point.
|
// this point.
|
||||||
std::map<cmTarget*, int>::const_iterator tii =
|
std::map<cmTarget*, int>::const_iterator tii =
|
||||||
|
@ -284,6 +294,7 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
|
||||||
this->InitialGraph[depender_index].push_back(
|
this->InitialGraph[depender_index].push_back(
|
||||||
cmGraphEdge(dependee_index, !linking));
|
cmGraphEdge(dependee_index, !linking));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
|
|
|
@ -46,6 +46,7 @@ private:
|
||||||
void CollectTargetDepends(int depender_index);
|
void CollectTargetDepends(int depender_index);
|
||||||
void AddTargetDepend(int depender_index, const char* dependee_name,
|
void AddTargetDepend(int depender_index, const char* dependee_name,
|
||||||
bool linking);
|
bool linking);
|
||||||
|
void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking);
|
||||||
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
|
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
|
||||||
|
|
||||||
cmGlobalGenerator* GlobalGenerator;
|
cmGlobalGenerator* GlobalGenerator;
|
||||||
|
|
|
@ -75,6 +75,22 @@ foreach(c DEBUG RELWITHDEBINFO)
|
||||||
set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
|
set_property(TARGET imp_testExe1b PROPERTY COMPILE_DEFINITIONS_${c} EXE_DBG)
|
||||||
endforeach(c)
|
endforeach(c)
|
||||||
|
|
||||||
|
# Create a custom target to generate a header for the libraries below.
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT testLib2.h
|
||||||
|
VERBATIM COMMAND
|
||||||
|
${CMAKE_COMMAND} -E echo "extern int testLib2(void);" > testLib2.h
|
||||||
|
)
|
||||||
|
add_custom_target(hdr_testLib2 DEPENDS testLib2.h)
|
||||||
|
|
||||||
|
# Drive the header generation through an indirect chain of imported
|
||||||
|
# target dependencies.
|
||||||
|
add_library(dep_testLib2 UNKNOWN IMPORTED)
|
||||||
|
add_dependencies(dep_testLib2 hdr_testLib2)
|
||||||
|
add_dependencies(bld_testLib2 dep_testLib2)
|
||||||
|
add_dependencies(exp_testLib2 dep_testLib2)
|
||||||
|
|
||||||
# Create a library to be linked by another directory in this project
|
# Create a library to be linked by another directory in this project
|
||||||
# to test transitive linking to otherwise invisible imported targets.
|
# to test transitive linking to otherwise invisible imported targets.
|
||||||
add_library(imp_lib1 STATIC imp_lib1.c)
|
add_library(imp_lib1 STATIC imp_lib1.c)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
extern int testLib2(void);
|
#include "testLib2.h"
|
||||||
|
|
||||||
int imp_lib1(void)
|
int imp_lib1(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue