C++ standard version fallbacks.

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

C++ standard version fallbacks.

Roger Leigh
Hi folks,

I'm currently using this logic to use C++14 with a fallback to C++11
when C++14 is unavailable:

   if(NOT CMAKE_CXX_STANDARD)
     set(CMAKE_CXX_STANDARD 14)
   endif()
   if(NOT CMAKE_CXX_STANDARD_REQUIRED)
     set(CMAKE_CXX_STANDARD_REQUIRED 11)
   endif()

which seems to work OK.

However, for some new stuff, I'd like to use C++17 when available, but
fall back to C++14, C++11 or C++98.  Is it possible to do this?

- I'd like it to work on older CMake versions where "17" isn't a valid
version for the above; is there any way to introspect the supported
standards?
- And I'd like it to fall back intelligently, i.e. if 17 isn't available
I want it to select the newest standard possible, rather than falling
back all the way to 98

Any suggestions?


Thanks,
Roger
--

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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: C++ standard version fallbacks.

Stephen Kelly-2
Roger Leigh wrote:

> Hi folks,
>
> I'm currently using this logic to use C++14 with a fallback to C++11
> when C++14 is unavailable:
>
>    if(NOT CMAKE_CXX_STANDARD)
>      set(CMAKE_CXX_STANDARD 14)
>    endif()
>    if(NOT CMAKE_CXX_STANDARD_REQUIRED)
>      set(CMAKE_CXX_STANDARD_REQUIRED 11)
>    endif()
>
> which seems to work OK.
>
> However, for some new stuff, I'd like to use C++17 when available, but
> fall back to C++14, C++11 or C++98.  Is it possible to do this?

Probably set CMAKE_CXX_STANDARD

without CMAKE_CXX_STANDARD_REQUIRED (That variable doesn't really make sense
to me and I think it is overused when not needed).

> - I'd like it to work on older CMake versions where "17" isn't a valid
> version for the above; is there any way to introspect the supported
> standards?

Not currently. It could be added now (as a global property), but that won't
help you for existing CMake versions.

> - And I'd like it to fall back intelligently, i.e. if 17 isn't available
> I want it to select the newest standard possible, rather than falling
> back all the way to 98

I think it already does that.

Thanks,

Steve.


--

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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: C++ standard version fallbacks.

Craig Scott-3


On Tue, Jun 6, 2017 at 7:50 AM, Stephen Kelly <[hidden email]> wrote:
Roger Leigh wrote:

> Hi folks,
>
> I'm currently using this logic to use C++14 with a fallback to C++11
> when C++14 is unavailable:
>
>    if(NOT CMAKE_CXX_STANDARD)
>      set(CMAKE_CXX_STANDARD 14)
>    endif()
>    if(NOT CMAKE_CXX_STANDARD_REQUIRED)
>      set(CMAKE_CXX_STANDARD_REQUIRED 11)
>    endif()
>
> which seems to work OK.
>
> However, for some new stuff, I'd like to use C++17 when available, but
> fall back to C++14, C++11 or C++98.  Is it possible to do this?

Probably set CMAKE_CXX_STANDARD

without CMAKE_CXX_STANDARD_REQUIRED (That variable doesn't really make sense
to me and I think it is overused when not needed).

If you don't set CMAKE_CXX_STANDARD_REQUIRED, then there's no guarantee you get any particular minimum standard. Roger's example (sorry Roger!) highlights part of the confusion about this latter variable (and the target property it ultimately controls). He appears to be setting it expecting it to specify a minimum version, but that's not how it works. It is expected to be a boolean which says whether CMAKE_CXX_STANDARD must be honoured or not, which most developers (myself included) tend to find unintuitive. Roger's use would actually make it a bit better, if that was how it worked, but unfortunately there's currently no way to set a minimum standard version, only either "I'd like to use up to this version" or "I must use exactly this version". That's back to front, in my view, and pretty much all uses of these that I see want either "I'd like at least this version" or "I must use exactly this version".


--
Craig Scott
Melbourne, Australia

--

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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: C++ standard version fallbacks.

Stephen Kelly-2
Craig Scott wrote:

> On Tue, Jun 6, 2017 at 7:50 AM, Stephen Kelly
> <[hidden email]> wrote:
>
>> Roger Leigh wrote:
>>
>> > Hi folks,
>> >
>> > I'm currently using this logic to use C++14 with a fallback to C++11
>> > when C++14 is unavailable:
>> >
>> >    if(NOT CMAKE_CXX_STANDARD)
>> >      set(CMAKE_CXX_STANDARD 14)
>> >    endif()
>> >    if(NOT CMAKE_CXX_STANDARD_REQUIRED)
>> >      set(CMAKE_CXX_STANDARD_REQUIRED 11)
>> >    endif()
>> >
>> > which seems to work OK.
>> >
>> > However, for some new stuff, I'd like to use C++17 when available, but
>> > fall back to C++14, C++11 or C++98.  Is it possible to do this?
>>
>> Probably set CMAKE_CXX_STANDARD
>>
>> without CMAKE_CXX_STANDARD_REQUIRED (That variable doesn't really make
>> sense
>> to me and I think it is overused when not needed).
>>
>
> If you don't set CMAKE_CXX_STANDARD_REQUIRED, then there's no guarantee
> you get any particular minimum standard.

He wants to fall back all the way to C++98. Am I missing something?

> Roger's example (sorry Roger!)
> highlights part of the confusion about this latter variable (and the
> target property it ultimately controls). He appears to be setting it
> expecting it to specify a minimum version, but that's not how it works. It
> is expected to be a boolean which says whether CMAKE_CXX_STANDARD must be
> honoured or not, which most developers (myself included) tend to find
> unintuitive.

Ok.

I remember I was opposed to introducing CMAKE_CXX_STANDARD_REQUIRED in the
first place as I think it is redundant. I recommend populating compile
features for whatever you absolutely need and let cmake populate the std
flag. If your code can benefit from a more-recent std flag than the
requirement, then set CMAKE_CXX_STANDARD to that.

> Roger's use would actually make it a bit better, if that was
> how it worked, but unfortunately there's currently no way to set a
> *minimum* standard version,

If you have a minimum, then you must be relying on some language features
existing and you can list those.

Thanks,

Steve.


--

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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: C++ standard version fallbacks.

Craig Scott-3


On Tue, Jun 6, 2017 at 8:50 AM, Stephen Kelly <[hidden email]> wrote:
Craig Scott wrote:

> On Tue, Jun 6, 2017 at 7:50 AM, Stephen Kelly
> <[hidden email]> wrote:
>
>> Roger Leigh wrote:
>>
>> > Hi folks,
>> >
>> > I'm currently using this logic to use C++14 with a fallback to C++11
>> > when C++14 is unavailable:
>> >
>> >    if(NOT CMAKE_CXX_STANDARD)
>> >      set(CMAKE_CXX_STANDARD 14)
>> >    endif()
>> >    if(NOT CMAKE_CXX_STANDARD_REQUIRED)
>> >      set(CMAKE_CXX_STANDARD_REQUIRED 11)
>> >    endif()
>> >
>> > which seems to work OK.
>> >
>> > However, for some new stuff, I'd like to use C++17 when available, but
>> > fall back to C++14, C++11 or C++98.  Is it possible to do this?
>>
>> Probably set CMAKE_CXX_STANDARD
>>
>> without CMAKE_CXX_STANDARD_REQUIRED (That variable doesn't really make
>> sense
>> to me and I think it is overused when not needed).
>>
>
> If you don't set CMAKE_CXX_STANDARD_REQUIRED, then there's no guarantee
> you get any particular minimum standard.

He wants to fall back all the way to C++98. Am I missing something?

Sorry, my comments were based on the example code which looks as though it was expecting C++11 to be a minimum requirement. The paragraph that follows it describes a  different scenario, as you say. Apologies for the confusion!

 

> Roger's example (sorry Roger!)
> highlights part of the confusion about this latter variable (and the
> target property it ultimately controls). He appears to be setting it
> expecting it to specify a minimum version, but that's not how it works. It
> is expected to be a boolean which says whether CMAKE_CXX_STANDARD must be
> honoured or not, which most developers (myself included) tend to find
> unintuitive.

Ok.

I remember I was opposed to introducing CMAKE_CXX_STANDARD_REQUIRED in the
first place as I think it is redundant. I recommend populating compile
features for whatever you absolutely need and let cmake populate the std
flag. If your code can benefit from a more-recent std flag than the
requirement, then set CMAKE_CXX_STANDARD to that.

> Roger's use would actually make it a bit better, if that was
> how it worked, but unfortunately there's currently no way to set a
> *minimum* standard version,

If you have a minimum, then you must be relying on some language features
existing and you can list those.

Until very recently, that only worked for language features, it didn't help if you relied on parts of the STL, for example. I think the recently added cxx_std_?? compiler meta feature comes close to giving the behaviour I was describing now, but it is less convenient in that you always have to set it for every target, there isn't an associated variable that sets a default for all targets (that I'm aware of - I'd be happy to be wrong on this one!).

Roger, to get back to your original question, Stephen's suggestion of not setting CMAKE_CXX_STANDARD_REQUIRED is probably going to give you what you are seeking. My view is that setting just CMAKE_CXX_STANDARD leads to unintuitive behaviour for many developers, but since you've explicitly stated that it is indeed the behaviour that you want, then I guess it works for you. Just be prepared to explain it to other developers from time to time!



--

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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: C++ standard version fallbacks.

Roger Leigh
In reply to this post by Stephen Kelly-2
On 05/06/17 23:50, Stephen Kelly wrote:

> Craig Scott wrote:
>
>> On Tue, Jun 6, 2017 at 7:50 AM, Stephen Kelly
>> <[hidden email]> wrote:
>>
>>> Roger Leigh wrote:
>>>
>>>> Hi folks,
>>>>
>>>> I'm currently using this logic to use C++14 with a fallback to C++11
>>>> when C++14 is unavailable:
>>>>
>>>>     if(NOT CMAKE_CXX_STANDARD)
>>>>       set(CMAKE_CXX_STANDARD 14)
>>>>     endif()
>>>>     if(NOT CMAKE_CXX_STANDARD_REQUIRED)
>>>>       set(CMAKE_CXX_STANDARD_REQUIRED 11)
>>>>     endif()
>>>>
>>>> which seems to work OK.
>>>>
>>>> However, for some new stuff, I'd like to use C++17 when available, but
>>>> fall back to C++14, C++11 or C++98.  Is it possible to do this?
>>>
>>> Probably set CMAKE_CXX_STANDARD
>>>
>>> without CMAKE_CXX_STANDARD_REQUIRED (That variable doesn't really make
>>> sense
>>> to me and I think it is overused when not needed).
>>>
>>
>> If you don't set CMAKE_CXX_STANDARD_REQUIRED, then there's no guarantee
>> you get any particular minimum standard.
>
> He wants to fall back all the way to C++98. Am I missing something?

No, that's exactly what I want.  I'd like to have the compiler put into
the highest mode possible and then do feature tests for various things.
For example, try std::thread and fall back to boost or POSIX/Win32
threads if not available.  Not setting CMAKE_CXX_STANDARD_REQUIRED seems
to be all that's required, so that solves my problem nicely.

>> Roger's example (sorry Roger!)
>> highlights part of the confusion about this latter variable (and the
>> target property it ultimately controls). He appears to be setting it
>> expecting it to specify a minimum version, but that's not how it works. It
>> is expected to be a boolean which says whether CMAKE_CXX_STANDARD must be
>> honoured or not, which most developers (myself included) tend to find
>> unintuitive.
>
> Ok.

Yes, I misread the documentation here, and I think I also picked it up
by reading someone else's (broken) example.  I've now fixed up my code
to work according to the documented behaviour.  Thanks everyone for the
corrections and suggestions in this thread.

> I remember I was opposed to introducing CMAKE_CXX_STANDARD_REQUIRED in the
> first place as I think it is redundant. I recommend populating compile
> features for whatever you absolutely need and let cmake populate the std
> flag. If your code can benefit from a more-recent std flag than the
> requirement, then set CMAKE_CXX_STANDARD to that.
>
>> Roger's use would actually make it a bit better, if that was
>> how it worked, but unfortunately there's currently no way to set a
>> *minimum* standard version,
>
> If you have a minimum, then you must be relying on some language features
> existing and you can list those.

This would make sense, and I'll look at doing that.

I'm still not 100% sure that the behaviour is as good as it could be
though.  Some scenarios:

1) I set CMAKE_CXX_STANDARD to 17.  This is unsupported and it falls
back to 14.  Is the fallback introspectable?  Can I query that the
fallback happened/is going to happen?

2) I do a check for <cstdint> which succeeds, and I use it in a
configuration header, but this later fails to build because it's only
usable in C++11 mode, and if I set CMAKE_CXX_STANDARD to 98 it fails.

I know the *requested* standard version.  But I don't know the
*effective* standard version, and I need to know that at cmake time.

Much of the standard version selection is based upon setting the minimum
set of required compile features and having cmake put the compiler in a
mode appropriate to support that featureset.  What I'd like to do here
is the opposite: I want to dynamically adjust the features I use by
gracefully falling back to alternative implementations based upon my own
feature testing.  But I can't see how I can ask that question of CMake
even by getting the appropriate target properties; these look like they
are the requested version as well, do they ever get turned into the
effective version?

I'm sure I can work around the lack with some more sophisticated feature
tests if required, e.g. compile checks rather than header checks.


Thanks,
Roger
--

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
Loading...