Link interface for an INTERFACE target now requires all linked libraries to exist
The CMake 3.30 introduced a regression where this MRE fails:
cmake_minimum_required(VERSION 3.15)
project(foo)
add_library(foo INTERFACE)
target_link_libraries(foo INTERFACE nonexistent::bar)
install(TARGETS foo DESTINATION lib EXPORT foo-targets)
install(EXPORT foo-targets FILE foo-targets.cmake DESTINATION lib)
The error I observe is
CMake Error at CMakeLists.txt:4 (target_link_libraries):
The link interface of target "foo" contains:
nonexistent::bar
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
CMake is correct that the target does not exist, but the target's existence should not be required here since it is only part of the link interface of an interface target, i.e. nonexistent::bar
is only a dependency of consumers of foo
at build time, not of foo
itself. It is desirable to support this use case so that an interface library can be created on a system without needing to install all of its (possibly heavy) dependencies if they are only needed when the interface library is consumed.
I bisected the issue down to this commit. The issue seems to be that install
(or export
, which also triggers the error) is now considered to be sufficient to trigger the checks related to CMP0028, and as a result since nonexistent::bar
is not an INTERFACE or ALIAS target the configuration fails. Therefore, any of the following changes to the MRE are sufficient to make the error vanish:
- Stop installing the target
- Add
cmake_policy(SET CMP0028 OLD)
- Change the target name to just
nonexistent
, i.e. remove the double colon so that the linked target is no longer considered to be an INTERFACE or ALIAS target.