Hi, The target_compile_features topic in my clone is almost ready to merge to next.
Here are some remaining issues to discuss: 1) Extensions With GNU and Clang, standard C++ features are enabled with a compile flag something like -std=c++98 or -std=c++11. Compiler specific extensions are enabled with a flag like -std=c++98 or -std=gnu++11. It is a two-dimensional system. One axis extends the C++ standard whose features are required, and the other extends the compiler features. With XL, compiler specific extensions are enabled with -qlanglvl=extended. For GNU, Clang and XL, the compiler-specific extensions are enabled by default. http://pic.dhe.ibm.com/infocenter/lnxpcomp/v121v141/index.jsp?topic=%2Fcom.ibm.xlcpp121.linux.doc%2Flanguage_ref%2Fexts_general.html The XL driver doesn't seem to be two dimensional in the same way as GNU. That is, we can use -qlanglvl=extended0x to get the extensions *and* the C++0x [sic] features. There doesn't seem to be a -qlanglvl=no-extended to disable the compiler-specific extensions. Because the XL driver offers more granularity in features that may be enabled/disabled, it is possible to enable only the C++0x features by specifying more flags. COMPILER | CXX_STANDARD | CXX_EXTENSIONS | FLAG GNU 98 0 -std=c++98 GNU 98 1 -std=gnu++98 Clang 98 0 -std=c++98 Clang 98 1 -std=gnu++98 XL 98 0 [NA] [1] XL 98 1 -qlanglvl=extended GNU 11 0 -std=c++11 GNU 11 1 -std=gnu++11 Clang 11 0 -std=c++11 Clang 11 1 -std=gnu++11 XL 11 0 -qlanglvl=extended0x [2] XL 11 1 -qlanglvl=extended0x GNU 14 [3] 0 -std=c++14 GNU 14 1 -std=gnu++14 Clang 14 0 -std=c++14 Clang 14 1 -std=gnu++14 XL 14 0 -qlanglvl=extended14 [4] XL 14 1 -qlanglvl=extended14 [1] No known -qlanglvl=no-extended flag. [2] Future versions of XL might enable the C++11 features by default. In that case we would add no flags for this combination. [3] CXX_STANDARD=14 allowed in a future CMake version, when it is ratified and GNU/Clang support -std=c++14. [4] Or whatever flag they choose to enable C++14 features. I propose ignoring the granularity of XL and letting the user be more granular if they wish (I think there's also granularity available with GNU flags). Does that have an impact on the order that built-in vs user flags are specified in the compile commands? 2) Unavailable features There will be some set of features supported by CMake. Each tuple of {compiler id, compiler version, lang standard, extensions} will have some subset of those features available. If CMake is executed on a target which requires a particular feature, and CMake knows that the particular feature is not supported by the compiler id and version (with any extra flags), CMake reports an error. Recording that a {compiler id, compiler version} supports a particular feature is fairly easy, as is done in my topic already. The distinction between "this compiler version supports an empty subset of the features known to CMake" and "we have not tested the features of this version of the compiler" is not quite so easy. Currently my topic reports no error if there are no recorded features for a compiler version. An error is only reported if the {compiler id, version} is known to have features (which means someone must have investigated and added them). That means that if I try to use MSVC71 for example with a target which requires cxx_constexpr, there will be no error reported by CMake, because MSVC71 supports an empty subset of the current features known to CMake. One way to enable that error would be to introduce a dummy cxx_no_features feature for use with compilers known to have an empty subset of the features known to CMake. 3) Maintenance If CMake learns a cxx_partial_template_specialization feature in the future, the cxx_no_features feature would be removed for MSVC71 and cxx_partial_template_specialization added. That means that someone (preferably with direct access to MSVC71) needs to maintain the list of features for that {compiler id, compiler version} as the list of features known to CMake grows. This is more difficult maintenance to do for compilers which are no longer widely available or common. The same requirement of maintaining the list of features is present for contemporary compilers, but it is easier to maintain for compilers which are easily available to run. My topic doesn't record the features of the XL compiler (any version). That means that no feature requirement will report an error with that compiler currently. Someone could record the features, but that would require some commitment of ongoing maintenance of the list for future versions of the compiler and for future features learned by CMake. So, I could merge my topic initially with recorded features for GNU 4.8, but no earlier version of GNU, and commit to maintaining that {GNU, 4.8} tuple for future CMake features. That would mean that if someone tries to use CMake with a target which requires cxx_constexpr and {GNU, 4.6}, which supports that feature with the -std=c++11 flag, CMake would not add the flag. If the same compiler is used with a target which requires cxx_override (which GNU 4.6 does not support), CMake would report no error. At any time though, someone can come along and record the features of that compiler and contribute it to CMake and maintain it there. So, generically, adding new known features to CMake which are present in old {compiler id, version} tuples will be more work (probably for more people) than adding features which are known only to recent {compiler id, version} tuples. I expect that if the topic is merged, there will be an initial period of time where C++11 and C++14 features are added, but I don't know if anyone will want to record features of old or ancient compilers like partial specicialization. There may be a long tail of things like that though. Am I over-thinking this? Do we need to require some kind of maintenance commitment from people who want to add the first feature for a {compiler id, version} tuple, like is currently required for adding new modules? 4) All available features use-case Something that most projects (Qt, llvm, etc) want to have in their buildsystem is 'Use the most features available from the compiler the user is using'. Qt does this with 'CONFIG += c++11' (I guess they'll add 'CONFIG += c++14' eventually too), and LLVM uses similar CMake options. Then variadic templates, the override keyword etc are used conditionally. I added a prototype untested commit to my topic to use the flags for the highest standard version available if the compiler doesn't support the standard version specified. Users could use this together with a header generated by write_compiler_detection_header. Is it a use-case we want to support with this interface with CMake? 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/cgi-bin/mailman/listinfo/cmake-developers
