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

Jan Vesely jan.vesely at rutgers.edu
Thu Sep 4 07:47:44 PDT 2014


On Thu, 2014-09-04 at 13:41 +0100, Dan Liew wrote:
> 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.

(only considering shared libraries, and ignoring problems with different
versions)
it's perfectly OK for an app to not link against all secondary
dependencies. i.e if app A needs library B, and B's internal
implementation needs library C, then A only needs to link against B.

the case is different when C's symbols are used in B's headers and can
be directly used by A, in that case both and A and B need to link with
C.

that basically covers the three options;
PRIVATE (only implementation, B needs to link with C),
INTERFACE (only in headers, A needs to link with C),
PUBLIC (both implementation and headers, both A and B need to link with
C).

jan

> 
> > 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.
> 
> * Section "BUILD SPECIFICATION AND USAGE REQUIREMENTS" in
> cmake-buildsystem(7) doesn't list it as one (it lists
> INTERFACE_INCLUDE_DIRECTORIES,  INTERFACE_COMPILE_DEFINITIONS  and
> INTERFACE_COMPILE_OPTIONS). Which suggests that
> "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
> INTERFACE_LINK_LIBRARIES target property
> ...
> 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.
> 
> Thanks,
> Dan.

-- 
Jan Vesely <jan.vesely at rutgers.edu>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140904/30fcf625/attachment.sig>


More information about the llvm-commits mailing list