Hi Mario,

Eureka! I had glanced through that explanation in the past, however, I
missed this key piece of information:

"For this reason, when A
links in B as PRIVATE and another target C links in A, CMake will still add
B to the list of libraries to be linked for C because parts of B are needed
by A, but A itself doesn't have that dependency encoded into it. So even
though B is an internal implementation detail of A, C still needs B added
to the linker command, which CMake conveniently handles for you."

So, indeed, CMake takes care of this by adding the 'static' library
dependency to the link dependency,
even if it's private. Great feature!

My confusion comes from reading the documentation. For
target_link_libraries, it simply states:

"Libraries and targets following PRIVATE are linked to, but are not made
part of the link interface."

Perhaps it should add another sentence "except when the library is a static
library".  And perhaps
would also clarify how this "exception" indeed only applies to the link
interface but nothing else
(include path or compile flags), as stated in Craig Scott's explanation.

Thanks a lot for the clarification!

--
Luis

On Thu, Jun 1, 2017 at 12:53 PM, Mario Werner <mario.wer...@iaik.tugraz.at>
wrote:

> Hi Luis,
>
> as you correctly concluded, if 'Foo' is not part of the public interface
> of 'Bar', then the PRIVATE is the correct specifier.
>
> However, you don't have to add 'Foo' to the consumers of 'Bar' (e.g.,
> 'MyApp'). If everything works as expected, CMake automatically tracks
> the link dependency from 'Bar' to 'Foo' and adds it to the link command
> of the consuming artifact when 'Bar' is a static library.
>
> I did a quick experiment based on the code layout you outlined and for
> me everything worked out of the box. If it does not for you, it would be
> great if you can provide an actual minimal working example which shows
> the issue.
>
> Maybe the very detailed explanation [1] provided by Craig Scott is also
> interesting in this context.
>
> HTH,
> Mario
>
> [1] https://cmake.org/pipermail/cmake/2016-May/063400.html
>
> On 2017-06-01 13:11, Luis Caro Campos wrote:
> > I have the following scenario where I have 2 static libraries, where one
> > uses symbols from the other, and the executable needs to link against
> both
> > in order to build properly.
> >
> > Library 'Bar' uses symbols from library 'Foo' internally, but 'Foo' is
> not
> > part of the "interface" of Bar, i.e., the calling library/application
> only
> > needs to include headers from 'Bar', and use symbols from Bar.
> >
> > ---
> > #static libraries, assuming BUILD_SHARED_LIBS is off
> > add_library(Foo)
> > add_library(Bar)
> > target_include_directories(Foo PRIVATE ... )
> > target_include_directories(Foo INTERFACE ...)
> > target_include_directories(Bar PRIVATE ...)
> > target_include_directories(Bar INTERFACE ..)
> >
> > # this will expose Bar to Foo's interface include directories
> > target_link_libraries(Bar PUBLIC|PRIVATE Foo)
> >
> >
> > add_executable(MyApp)
> > target_link_libraries(MyApp PRIVATE Bar)
> >
> > ---
> >
> > In order to for the executable "MyApp" to build successfully, which uses
> > static library Bar, "Foo" also needs be in the link statement otherwise
> > I'll get missing symbols. If 'Bar' doesn't include this information in
> the
> > target link interface, I'll have to explicitly link against "Foo" for
> MyApp.
> >
> > My question is, in this case, which is the correct keyword for use when
> > calling "target_link_libraries" between Bar and Foo?
> >
> > Technically, 'Foo' is not part of Bar's public interface, so it would be
> > PRIVATE. However, this would force me to have to expressly link against
> Foo
> > in MyApp.
> > The other alternative is PUBLIC, as that would take care of the
> dependency.
> > I think strictly speaking, it is an "interface link dependency", but not
> an
> > "interface" dependency. I know that there are LINK_PUBLIC and
> LINK_PRIVATE
> > keywords for target_link_libraries, however the documentation says they
> are
> > for compatibility only and the other ones should be favoured.
> >
> > So in this scenario, I guess "PUBLIC" would be the best case, as that
> takes
> > care of the linking of MyApp.
> >
> > Question (1): does this not have the downside of adding Foo's interface
> > include directories to MyApp's include path?
> >
> > The second scenario would be if Foo was static and Bar was shared. In
> that
> > case, it would be crystal clear, the target_link_libraries call between
> Foo
> > and Bar should use the PRIVATE keyword.
> > However, what about if BUILD_SHARED_LIBS was set to on?
> > Both would be shared libraries, but MyApp doesn't need to link against
> > "Foo" anymore, however it is needed at runtime.
> >
> > Question (2): toggling the BUILD_SHARED_LIBS flag then seems to require
> > altering the semantics of calls to target_link_libraries? What about the
> > "needed at runtime" but "no part of the interface case?
> >
> > My conclusion is that I should perhaps explicitly declare those libraries
> > as static (foo and bar), and use the "PUBLIC" keyword when linking them.
> > Although I see two downsides:
> > 1) Foo's interface include path is added to MyApp's include path (and it
> is
> > not needed)
> > 2) Bar is now dependant on "Foo", so Foo needs to be built before.
> However,
> > from a compiler point of view, the binaries of Foo are not needed to
> > produce bar.
> >
> > Any help would be appreciated, in case there are better ways to express
> > these dependencies that I'm ignoring.
> >
> >
> >
> > Thanks,
> > Luis
> >
> >
> >
>
>
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensou
> rce/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake
>
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to