Merge topic 'link-shared-depend-cycle-issue-12647'

8e756d2 Tolerate cycles in shared library link interfaces (#12647)
This commit is contained in:
David Cole 2012-01-17 16:25:19 -05:00 committed by CMake Topic Stage
commit 05fbfd494e
6 changed files with 55 additions and 3 deletions

View File

@ -358,7 +358,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
this->AddLinkEntries(depender_index, iface->Libraries); this->AddLinkEntries(depender_index, iface->Libraries);
// Handle dependent shared libraries. // Handle dependent shared libraries.
this->QueueSharedDependencies(depender_index, iface->SharedDeps); this->FollowSharedDeps(depender_index, iface);
// Support for CMP0003. // Support for CMP0003.
for(std::vector<std::string>::const_iterator for(std::vector<std::string>::const_iterator
@ -376,6 +376,23 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
} }
} }
//----------------------------------------------------------------------------
void
cmComputeLinkDepends
::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface,
bool follow_interface)
{
// Follow dependencies if we have not followed them already.
if(this->SharedDepFollowed.insert(depender_index).second)
{
if(follow_interface)
{
this->QueueSharedDependencies(depender_index, iface->Libraries);
}
this->QueueSharedDependencies(depender_index, iface->SharedDeps);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void void
cmComputeLinkDepends cmComputeLinkDepends
@ -430,8 +447,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
entry.Target->GetLinkInterface(this->Config)) entry.Target->GetLinkInterface(this->Config))
{ {
// Follow public and private dependencies transitively. // Follow public and private dependencies transitively.
this->QueueSharedDependencies(index, iface->Libraries); this->FollowSharedDeps(index, iface, true);
this->QueueSharedDependencies(index, iface->SharedDeps);
} }
} }
} }

View File

@ -105,6 +105,10 @@ private:
int DependerIndex; int DependerIndex;
}; };
std::queue<SharedDepEntry> SharedDepQueue; std::queue<SharedDepEntry> SharedDepQueue;
std::set<int> SharedDepFollowed;
void FollowSharedDeps(int depender_index,
cmTarget::LinkInterface const* iface,
bool follow_interface = false);
void QueueSharedDependencies(int depender_index, void QueueSharedDependencies(int depender_index,
std::vector<std::string> const& deps); std::vector<std::string> const& deps);
void HandleSharedDependency(SharedDepEntry const& dep); void HandleSharedDependency(SharedDepEntry const& dep);

View File

@ -7,3 +7,6 @@ macro(add_CMakeOnly_test test)
-P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
) )
endmacro() endmacro()
add_CMakeOnly_test(LinkInterfaceLoop)
set_property(TEST CMakeOnly.LinkInterfaceLoop PROPERTY TIMEOUT 90)

View File

@ -0,0 +1,27 @@
cmake_minimum_required (VERSION 2.8)
project(LinkInterfaceLoop C)
# Add a shared library that incorrectly names itself as a
# dependency, thus forming a cycle.
add_library(A SHARED IMPORTED)
set_target_properties(A PROPERTIES
IMPORTED_LINK_DEPENDENT_LIBRARIES A
IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/dirA/A"
)
# Add a shared library that incorrectly names itself in
# its link interface, thus forming a cycle.
add_library(B SHARED IMPORTED)
set_target_properties(B PROPERTIES
IMPORTED_LINK_INTERFACE_LIBRARIES B
IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/dirB/B"
)
# Add a shared library with an empty link interface
# that depends on two shared libraries.
add_library(C SHARED lib.c)
set_property(TARGET C PROPERTY LINK_INTERFACE_LIBRARIES "")
target_link_libraries(C B A)
add_executable(main main.c)
target_link_libraries(main C)

View File

@ -0,0 +1 @@
int lib(void) { return 0; }

View File

@ -0,0 +1 @@
int main(void) { return 0; }