[cmake-developers] Possible feature request concerning conditional linking support by generator expressions

Alan W. Irwin Alan.W.Irwin1234 at gmail.com
Tue Sep 24 17:02:18 EDT 2019


Sorry for the long post, but my use case is complex, and there are
several possible solutions to the problem presented by that use case
which add to the length of this.  So to help keep your reading
organized, this post is separated into three sections which are (I.) a
possible feature request explaining what I think I need in an ideal
world, (II.)  my use case, and (III.) possible solutions to the
-pthread and D problem presented by that use case (including you guys
implementing this feature request).

I. Possible feature request

After reading through the generator-expression documentation at
<https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html>
it appears for my use case (see below) I need generator expressions of
the form

$<$<NOT:$<LINK_LANGUAGE:D>>:-pthread>
$<$<LINK_LANG_AND_ID:D,gdc>:-pthread>
$<$<LINK_LANG_AND_ID:D,ldc2>:-Xcc-pthread>
$<$<LINK_LANG_AND_ID:D,dmd>:libbasename> (where libbasename is likely pthread)

where I guess (since I am pretty much a newbie with regard to detailed
generator expressions) they would all be combined together in a list
for a library target INTERFACE_LINK_LIBRARIES property.

It appears such generator expressions are not implemented now and
there is no other way to use generator expressions to deal with my use
case, but if you think this feature would generally be worthwhile once
you have considered my use case and others who might have already
expressed a need for this functionality, I would be willing to make a
formal feature request on the bug tracker for this
generator-expression capability.

II. Use case:

The PLplot build system is currently in an inconsistent mess with our
various device drivers that depend on various external libraries
specifying the thread library in a variety of ways.  So my plan is to
figure out how to make the thread library results delivered by a
number of different find modules consistent with the Thread::Thread
target result returned by find_package(Threads), and the rest of this
discussion considers one particular configuration where that work
has already been done.

I have already done that work for our xwin device driver and all the
PLplot libraries are now built with the PRIVATE option for
target_link_libraries.  So here is a simplified result for the static
case (where that device code becomes part of the plplot library) when
only that device has been enabled:

-- DEBUG: For target=Threads::Threads and property=INTERFACE_LINK_LIBRARIES, the value of the property is -pthread
-- DEBUG: For target=PLPLOT::plplot and property=INTERFACE_LINK_LIBRARIES, the value of the property is /usr/lib/x86_64-linux-gnu/libSM.so;/usr/lib/x86_64-linux-gnu/libICE.so;/usr/lib/x86_64-linux-gnu/libX11.so;/usr/lib/x86_64-linux-gnu/libXext.so;$<LINK_ONLY:Threads::Threads>;/usr/lib/x86_64-linux-gnu/libm.so;/usr/lib/x86_64-linux-gnu/libshp.so;/usr/lib/x86_64-linux-gnu/libfreetype.so;$<LINK_ONLY:PLPLOT::csirocsa>;$<LINK_ONLY:PLPLOT::csironn>;$<LINK_ONLY:PLPLOT::qsastime>
-- DEBUG: For target=PLPLOT::plplotdmd and property=INTERFACE_LINK_LIBRARIES, the value of the property is $<LINK_ONLY:PLPLOT::plplot>

Note, PLplot has its own recently developed fork of the cmake-d
project that works well for D language support on Linux for all three
of the dmd, ldc2, and gdc D compilers, and preliminary results on
Darwin for dmd are good as well. However, there is one remaining D
issue considering the -pthread link option delivered by the above
combined INTERFACE_LINK_LIBRARIES to the D example builds via

target_link_libraries(x${STRING_INDEX}d PLPLOT::plplotdmd PLPLOT::plplot ${MATH_LIB})

For the static case that example build combines C and D objects from
the plplot and plplotdmd libraries and the D code making up the D
example into the x${STRING_INDEX}d executable.  And the problem is
that although the gdc compiler understands the -pthread *compiler
option* that is used for linking the executable, the dmd and ldc2
compilers do not understand that option.  Fortunately they both link
by using an underlying C compiler (rather than calling ld directly),
and in the ldc2 case you can specify the -pthread option to the
underlying C compiler used for linker with the -Xcc-pthread option.
But you cannot currently do that with dmd (although there are requests
on their bug tracker of simply following ldc2 in this regard).  So for
the dmd case we need (at least for now) to specify the library with
its "pthread" basename (which will be translated by the D language
support into the -L-lpthread option that the dmd compiler understands)
or as the full pathname of the library (which will be translated by D
language support into the -Lfullpathname form that the dmd compiler
also understands).

III. Possible solutions to the -pthread and D issue presented by this use case.

* Do not set THREADS_PREFER_PTHREAD_FLAG so the Threads find module
   delivers a library rather than the -pthread compiler option used for
   linking.  Although that appears to work well of my Debian Buster
   platform (once <https://gitlab.kitware.com/cmake/cmake/issues/19747>
   is worked around for older versions of CMake) it is not a generally
   recommended solution since apparently on some platforms the -pthread
   compiler option for linking is essential according to the gcc
   documentation and lots of web pages that parrot that information.

   But since using a library rather than -pthread is working for me on
   my platform, I don't know whether that general consensus is really
   true anymore or just a remnant of bad threading solutions to be
   avoided in the past.  Therefore, if others here have good or bad
   experience with NOT setting the THREADS_PREFER_PTHREAD_FLAG I would
   like to hear about it since this is an easy solution to implement if
   it is actually known to be reliable on all platforms/compilers that
   understand the -pthread linking option for compilers.

* Always use some other linking language than D for linking the D examples

   As an experiment I was able to set the LINKER_LANGUAGE
   x${STRING_INDEX}d target property to C, and that did force using gcc
   (which understands the -pthread compiler option for linking) for
   linking the D examples.  But that lead to another issue which is I
   had to specify which libphobos was to be used with each different D
   compiler, and they are all different!  So this option is possible,
   but quite messy with regard to finding the correct libphobos for
   each different D compiler on every platform!

* Use generator expressions like above.  This should work perfectly I
   think, but does require agreement on your part this change should be
   made to CMake, and that very likely depends on how complicated that
   implementation would be.

* What I tentatively plan to do now as a workaround for the issue

   For the combination of static libraries, D enabled, D compiler one
   of ldc2 or dmd, and Threads::Threads INTERFACE_LINK_LIBRARIES set to
   -pthread, make an additional version of the PLplot library called
   PLPLOT::plplot_nothread.  This library would be absolutely identical
   to PLPLOT::plplot except that Threads::Threads would be removed from
   its INTERFACE_LINK_LIBRARIES property.  (I am assuming here that the
   INTERFACE_LINK_LIBRARIES only affects what happens at generation
   time so it is impossible to "temporarily" remove Threads::Threads
   from the INTERFACE_LINK_LIBRARIES for PLPLOT:plplot just for linking
   the D examples which is why a second library needs to be built for
   this situation).

   Then if that target exists use PLPLOT::plplot_nothread and an extra
   link option consisting of either -Xcc-pthread for the ldc2 case or
   basename for the dmd case where needed to build the D binding
   library PLPLOT::plplotdmd and the D examples.

In sum, I think I have found a way to work around the -pthread D issue
for my use case although I haven't yet implemented or tested that
workaround.  However, it is obvious that making a build of a second
version of the core plplot C library is not an ideal solution so I
would far prefer to use conditional linking that depended on generator
expressions.  However, that requires work by you guys which you might
not prefer to do if this turns out to be the only use case ever that
requires such conditional linking. :-)

Again, sorry for the length of this, but I look forward to replies
from those who have had the patience to read through this about the
feasibility and general usefulness of implementing the possible
feature request or additional discussion or suggestions concerning the
other proposed solutions above to the -pthread D issue for my use
case.

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-developers mailing list