[PATCH 1/1] build/cmake: Fix CMP0023 warning with libffi

Dan Liew dan at su-root.co.uk
Thu Sep 4 05:41:57 PDT 2014

On 4 September 2014 00:51, Brad King <brad.king at kitware.com> wrote:
> On 9/3/2014 5:22 PM, Dan Liew wrote:
>> I'm a little confused as to why the PUBLIC, PRIVATE and INTERFACE
>> exist at all. Even if the library has an implementation-only
>> dependency any user of that library still needs to link against that
>> dependency, so there isn't anything "PRIVATE" about it.
> They are for usage requirements beyond just linking.  If dependent
> code does not include the headers of the private implementation
> dependency then it does not need any usage requirement such as
> include directories or preprocessor definitions.
> Conceptually it is a private implementation dependency.  It is only
> an implementation detail that dependents need to link the private
> dependencies of a static library transitively.  Private dependencies
> of SHARED libraries are not propagated even for linking.

Wouldn't that break linking against the library? If libLLVMInterpreter
was built as a shared library and libffi was a PRIVATE dependency
(let's assume that libffi is shared as well) then when building an
executable that links against the LLVMInterpreter library, linking
will fail because the PRIVATE dependency on libffi is not propagated
to the executable target.

> The cmake-buildsystem(7) manual in CMake 3.0 explains in more detail.

Thanks for the explanation. The new cmake-buildsystem man page is
incredibly helpful :)

>> but [1] seems to suggest they are the INTERFACE_*
>> (e.g.  INTERFACE_COMPILE_DEFINITIONS) target properties set by
>> ``target_include_directories(), target_compile_definitions() and
>> target_compile_options()``. INTERFACE_LINK_LIBRARIES doesn't seem to a
>> usage requirement. Is that right?
> INTERFACE_LINK_LIBRARIES is the main usage requirement: it specifies
> transitive link dependencies.  The other usage requirements must be
> propagated from the targets in the transitive closure of the link
> interface graph.

Thanks. I guess my confusion was over whether or not
"INTERFACE_LINK_LIBRARIES" is a "usage requirement" because the
documentation suggests that it might not be.

cmake-buildsystem(7) doesn't list it as one (it lists
"INTERFACE_LINK_LIBRARIES" **is not** a "usage requirement"

* Section "Transitive Usage Requirements" in cmake-buildsystem(7)
seems to suggest any target property prefixed with "INTERFACE_" will
be propagated, suggesting that "INTERFACE_LINK_LIBRARIES" **is** a
usage requirement (" Usage requirements are propagated by reading the
INTERFACE_ variants of target properties from dependencies and
appending the values to the non-INTERFACE_ variants of the operand").

Further more the documentation for "target_link_libraries()" in
cmake-commands(7) confuses things further by stating...

This transitive "link interface" is stored in the
Libraries and targets following PUBLIC are  linked  to,  and  are made
 part  of the "link interface". Libraries and targets following
PRIVATE are linked to, but are not made part of the "link interface".
Libraries following INTERFACE are appended to the "link interface" and
are not used for linking <target>

This makes it sound like the PUBLIC, INTERFACE and PRIVATE only affect
the propagation of INTERFACE_LINK_LIBRARIES property which is not the
case (as shown by cmake-buildsystem(7)).

I don't want to labour the point too much or be overly critical but I
think the documentation could be made clearer.


More information about the llvm-commits mailing list