[CMake] [cmake-developers] libc++ usage in CMake with Clang?

Stephen McDowell sjm324 at cornell.edu
Thu Sep 13 09:57:12 EDT 2018


Hello,

I wanted to revisit this topic.  Craig gave a great answer for using
add_{compile,link}_options which mostly answers the question -- this is the
most modern way at this time.

However, I believe that CMake would really benefit from standardizing
this.  For example, CMAKE_CXX_STL_TYPE.  I would argue that this should
also be a public "compile feature" in some form, so that it propagates to
consuming targets.

Some projects I work with do what Craig suggested and when Clang is
detected, default to using libc++ and also usually libc++-abi.  While kind
of nice, it's mostly annoying to me.  You're forcing an incompatible ABI on
me for Linux, when there's no reason to.  If I want to install to /usr/local
and use this with other dependencies say from my package manager installs,
I cannot because libc++ and libstdc++ are not compatible.  Instead of
asking projects to do some kind of option(MYLIB_USE_LIBCXX ...) and do
their own detection logic, setting the default to ON when Clang is the
compiler or whatever, if CMake supports this natively it would be a great
feature.

For example, I can compile with clang and use libstdc++ on Linux no
problem.  Similarly, when compiling with gcc, I *can* also use libc++
(assuming it's installed of course).  A rough prototype of the values
accepted (modelled after the android module):

- gnustl_shared (GNU libstdc++ shared)
- gnustl_static (GNU libstdc++ static)
- c++_shared (LLVM libc++ shared)
- c++_shared (LLVM libc++ static)
- c++_abi_shared (LLVM libc++-abi sharedi)
- c++_abi_static (LLVM libc++-abi static)

Where I do not have answers is how to make libc++ and libc++-abi more
ubiquitous.  As far as I know (which is not very far), libc++-abi cannot be
used unless you are also using libc++.  So I guess c++_abi_shared implies
c++_abi?

What about default values?

Linux: gnustl_shared seems like a reasonable choice, regardless of compiler
(e.g., don't always default to libc++ with clang [???]).
MacOS: ???
Windows: ???

I don't feel there is an immediate need for this, but long term I think
having CMAKE_CXX_STL_TYPE as well as a compile feature cxx_stl_type would
be really useful.  I started looking at possible implementation (hence the
long pause here), but ultimately gave up because I always try and implement
things for CMake that are beyond my capabilities of doing correctly.

Just soliciting feedback as to what people think about having this kind of
cmake-level STL type support, especially with respect to choosing defaults,
and in extra-specific case of Windows, ummm, what to do in general.

-Stephen

P.S. I think if CMAKE_CROSSCOMPILING is set then if the user sets either
CMAKE_CXX_STL_TYPE or cxx_stl_type this should be an error (informing them
to possibly instead set CMAKE_ANDROID_STL_TYPE if applicable)?  I don't
know what to do about cross compiling in general, but an agreement should
be reached on what to do when these proposed new variable / features are
used in conjunction with cross compiling.


On Wed, Aug 22, 2018 at 2:05 AM, Craig Scott <craig.scott at crascit.com>
wrote:

>
>
> On Wed, Aug 22, 2018 at 1:39 PM, Ian Henriksen <insertinterestingnamehere@
> gmail.com> wrote:
>
>>
>>
>> On Tue, Aug 21, 2018 at 6:40 PM Craig Scott <craig.scott at crascit.com>
>> wrote:
>>
>>>
>>> On Wed, Aug 22, 2018 at 7:18 AM, Robert Dailey <rcdailey.lists at gmail.com
>>> > wrote:
>>>
>>>> On Tue, Aug 21, 2018 at 3:47 PM Craig Scott <craig.scott at crascit.com>
>>>> wrote:
>>>> > Excuse the brevity, but it sounds like you might be looking for the
>>>> CXX_EXTENSIONS target property (sorry if I've misunderstood your problem,
>>>> let me know why it isn't appropriate if so). See the following article for
>>>> a more complete overview of this and related properties:
>>>> >
>>>> > https://crascit.com/2015/03/28/enabling-cxx11-in-cmake/
>>>>
>>>> Unfortunately that's not the same. Extensions manage C++ language
>>>> features and STL capabilities, but -stdlib is for selecting an STL
>>>> implementation, AFAIK. Such as GNU STL and LLVM STL (which is libc++
>>>> to clang).
>>>>
>>>
>>> Sorry, yes I misunderstood your problem. After a little digging, it
>>> seems like you probably shouldn't be using the -stdlib option on Linux
>>> <https://stackoverflow.com/a/50407611/1938798> anyway. FWIW, for
>>> Android, the roadmap
>>> <https://android.googlesource.com/platform/ndk/+/master/docs/Roadmap.md>
>>> is converging on a single STL implementation too.
>>>
>>
>> All that first link says is that -stdlib is a flag that is specific to
>> clang and that it shouldn't be used with gcc. You can use clang on Linux
>> with either libstdc++ or libc++. I often use libc++ on Linux by setting
>> CMAKE_CXX_FLAGS on the command line, though I'll admit that for me it's
>> usually just to check if problems that come up are OS dependent, compiler
>> dependent, or standard library dependent. You have to be careful since
>> libstdc++ and libc++ have incompatible ABIs, but it's a useful feature.
>> That said, I have no idea if specifying the standard library implementation
>> merits handling at the CMake level since only clang supports switching
>> anyway.
>>
>
>
> Good clarification, thanks. I was only thinking GCC on Linux and wasn't
> considering clang (which was a bit dumb on my part - blame the lack of
> coffee early in the morning ;) ).
>
> Getting back to Robert's original query, the only part of the CMake code
> base that I can see attempting to account for a -stdlib option is for
> detection of gcc include paths, and this is only for Eclipse and CodeBlocks
> generators (according to the comments in Modules/
> CMakeExtraGeneratorDetermineCompilerMacrosAndIncludeDirs.cmake). It
> doesn't seem to be related to providing any support for manipulating it in
> a project. The only other place -stdlib seems to be mentioned is in the
> setup of the macOS release build of CMake itself, which isn't relevant to
> the discussion here.
>
> If CMake were to offer direct support for -stdlib, it sounds like it would
> be a clang-specific feature, so a clang-specific target property and/or
> variable may be a way forward, analogous to the way it is done for Android.
> Alternatively, maybe it could be done with generator expressions, but it
> would be a bit verbose and harder to ensure the same -stdlib was used
> consistently throughout if many targets were involved. But maybe just a
> fairly simple check is good enough here, something like this (using
> directory properties instead of variables):
>
> if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT ANDROID)
>     add_compile_options(-stdlib=libc++)
>     # Presumably need the above for linking too, maybe other options
> missing as well
>     add_link_options(-stdlib=libc++)   # New command on CMake master, not
> in 3.12 release
> endif()
>
> The linking comments above are in response to discussions in a recent
> issue <https://gitlab.kitware.com/cmake/cmake/issues/18275> also related
> to the -stdlib option. One down side of the above is no transitive
> dependency details, something that a target property could achieve. I'll
> pause here and see what others think.
>
>
>
>
>>
>> Just my two cents though.
>>
>> Best,
>>
>> Ian
>>
>>
>>> Regarding your earlier comment:
>>>
>>> I'll explain a bit why I'm asking. I noticed that for code bases that
>>>> work on Android plus other UNIX platforms, they unconditionally
>>>> specify `-stdlib=libc++`, however this doesn't work on Ubuntu by
>>>> default, which uses gnu stl + gcc/clang. So  you get compiler errors.
>>>> There's no way for me to "search" a platform to see if it is eligible
>>>> for the libc++ flag, I simply have to either disable it completely or
>>>> conditionally include it based on target platform and/or toolchain.
>>>> None of these really address the root cause.
>>>
>>> If you are trying to control which STL to use for Android builds, CMake variables like CMAKE_ANDROID_STL_TYPE are probably the more appropriate way to do that rather than hard-coding compiler flags. This would also mean that non-Android builds won't be affected since they would simply ignore that variable (and target properties it may affect) and should then pick up the right STL implementation automatically.The Android-specific variable would ideally be set in a toolchain file rather than in the project itself.
>>>
>>>
>>> --
>>>
>>> Craig Scott
>>> Melbourne, Australia
>>> https://crascit.com
>>>
>>> New book released: Professional CMake: A Practical Guide
>>> <https://crascit.com/professional-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:
>>> https://cmake.org/mailman/listinfo/cmake
>>>
>>
>
>
> --
> Craig Scott
> Melbourne, Australia
> https://crascit.com
>
> New book released: Professional CMake: A Practical Guide
> <https://crascit.com/professional-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:
> https://cmake.org/mailman/listinfo/cmake
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180913/06f7d04e/attachment-0001.html>


More information about the CMake mailing list