[CMake] Difference between PRIVATE and PUBLIC with target_link_libraries

Alan W. Irwin Alan.W.Irwin1234 at gmail.com
Tue Sep 17 19:21:36 EDT 2019


Hi Craig:

It appears you pretty much made the definitive statement about
target_link_libraries (TLL) <INTERFACE|PUBLIC|PRIVATE> options at
<https://cmake.org/pipermail/cmake/2016-May/063400.html>.  However,
I have some further questions about this key section of your
statement:

"[...] when A links in B as PRIVATE, the include directories of B
never propagate to something linking to A, but if A is a static
library, then the *linking* of B behaves as though the relationship
was PUBLIC. This PRIVATE-becomes-PUBLIC behaviour for static libraries
only applies to the *linking*, not to the other dependencies (compiler
options/flags and include search paths). The upshot of all this is
that if you select PRIVATE, PUBLIC or INTERFACE based on the
explanations in the dot points above, then CMake will ensure
dependencies propagate through to where they are required, regardless
of whether libraries are static or shared. This does, of course, rely
on you the developer not missing any dependencies or specifying the
wrong PRIVATE/PUBLIC/INTERFACE relationship."

The issues I am concerned with are the following:

* The target_include_directories, target_compile_definitions, and
   target_compile_options (TID, TCD, and TCO) commands all have
   <INTERFACE|PUBLIC|PRIVATE> options.  I am pretty sure those options
   must take precedence over the TLL <INTERFACE|PUBLIC|PRIVATE> options,
   but can you confirm that?

* It appears to me that if a CMake-based build system is configured
   properly there is very little need for the PUBLIC option for TLL
   because PRIVATE works well for shared libraries and the
   PRIVATE-becomes-PUBLIC behaviour for static libraries you mentioned
   above.  Can you confirm this statement is generally true both for
   Unix and Windows?

I am concerned with the above issues because the PLplot build system
currently does the following:

* For shared libraries uses the PRIVATE TLL option for the Unix case
   and PUBLIC TLL option for the Windows case.

* For static libraries always uses the PUBLIC TLL option.

These decisions were based on my own understanding of transitive
linking needs for static Unix libraries and shared and static Windows
libraries many years ago, but now it appears that understanding is out
of date or else was wrong in the first place.

For example, in the static Linux case there is a nasty leakage of
compile and link flags between static libraries that I have just
tripped over when dealing with the D ldc2 compiler which cannot
understand those flags which are generated for the gcc compiler for a
C library which our D library depends on.  So to stop that leakage,
and in light of what you said three years ago, it appears to be a
no-brainer to use PRIVATE TLL for the PLplot static libraries at least
in the Unix case.  So assuming that for the PLplot build system I
follow up and prove that PRIVATE TLL works for both the shared and
static library cases on Unix, would you also recommend PLplot move to
PRIVATE TLL for both the shared and static library cases on Windows?

Thanks in advance for your further comments on these matters.

Alan
__________________________
Alan W. Irwin

Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.org); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________

Linux-powered Science
__________________________


More information about the CMake mailing list