[CMake] Enabling C99 in CMake
Todd Gamblin
tgamblin at llnl.gov
Mon Jun 27 12:34:23 EDT 2011
On Jun 24, 2011, at 11:30 PM, Michael Hertling wrote:
> On 06/23/2011 06:20 PM, Jed Brown wrote:
>> On Thu, Jun 23, 2011 at 17:50, Michael Hertling <mhertling at online.de> wrote:
>>
>>> You need to use a C99 compiler for your project
>>
>>
>> This is already a problem. C99 introduces new keywords (e.g. restrict) and
>> removes implicit int. It is entirely possible for part of a project to
>> include C89-conforming legacy code that is not valid C99. The use of C99 or
>> C89 should be a file- and directory-level property.
>
> That's a really good point and could indeed be very well addressed by
> a possibility for a project to enable language dialects per directory/
> target/file as Todd has asked for in his initial posting.
Yep -- After reading all the responses, think my suggestion was insufficient. Just having a variable for the compiler flags isn't enough. Also, I really like the dialects approach here. This has the potential to take care of not only C99, but also C++ *and* Fortran. The Fortran support in CMake could really use this kind of thing, as it would be very helpful to know if particular Fortran compilers support F90, F77, F08, etc.
> In order to
> achieve this in a platform/compiler-independent manner, take a look at
> the attached dialects.patch file, a diff against the Modules directory
> of CMake 2.8.4. It is not meant as a production-ready solution, but as
> as proof of concept, and it's restricted to the GNU C compiler, though
> it should be easily applicable to the other compilers known by CMake.
Thanks for making this!
> First of all, the new Compiler/LanguageDialects.cmake file provides a
> function __language_dialects() which accepts a language and a paired
> list of arguments denoting each supported language dialect followed by
> the flags to enable it. The function sets up the variable CMAKE_<LANG>_
> DIALECTS_INIT containing the list of dialects, and for each dialect a
> variable CMAKE_<LANG>_DIALECT_<DIALECT>_INIT containing the respective
> flags. The Compiler/GNU-C.cmake file is enhanced to - exemplary - call
>
>> __language_dialects(C C90 "-std=c90" C89 "-std=c89" C99 "-std=c99" C9X "-std=c9x" C1X "-std=c1x" ANSI "-ansi")
This looks great. One question is what to do with things like gnu99. This is C99 plus GNU extensions. I ask because the GNU compiler separates this from regular C99, while other compilers like XL don't. If you run xlc -qlanglvl=c99, it supports inline assembly, but if you run gcc -std=c99, it does not. You have to run with std=gnu99.
I *suspect* that most people will prefer gnu99 by default, as the lenient mode is the default for both gcc and xlc, but I could be conjecturing too far here.
My suggestion would be to have an option like "CMAKE_STRICT_C_DIALECT=TRUE" that says to also turn off support for compiler-specific extensions if possible, e.g.:
gcc: -std=c99
xlc: -qnoasm -qlanglvl=c99
and stick to the standard, but prefer the more lenient mode by default e.g.:
gcc: -std=gnu99
xlc: -qlanglvl=c99
> This turns out to be a simple and promising approach that
>
> - provides the developers with platform/compiler-independent variables
> to check if the compiler accepts a certain dialect and to enable it,
Yes. This is great.
> - places the compiler-specific dialect flags in the compiler-specific
> files in the Modules/Compiler directory where they obviously belong,
Excellent.
> - doesn't require complicated modifications in the Modules directory.
Also great.
> If you like this idea, feel free to add it to the feature request Todd
> has filed in the meantime. However, while this approach is independent
> of the dialects a compiler actually supports, be aware that mixed C89/
> C90 projects to be built with CMake need *one* compiler which masters
> C89 *and* C99, and that's not guaranteed for all of them.
I'm not sure what a good way around this would be, given the current internals of CMake. I would personally like to see CMake support multiple compilers like this for other reasons (mixing cross-compiled and non-cross-compiled builds) but I don't think that will happen in the near future and I'm not sure what a clean way to support it would be.
>> It's also horrible to encumber the poor user just trying to build your
>> project with needing to know whether it is written in C99 or whatever else,
>> nor with how to make their compiler deliver that dialect.
>
> Once the CMake-detected or user-specified compiler isn't suitable for
> the project, the user is in charge of choosing another one, and this
> might happen quite quickly; it's sufficient that the compiler is not
> in the PATH or unusually named. Then, the user must know whether the
> project needs a C and/or C++ and/or Fortran compiler, and where it's
> located. In such a situation, the need to know that a C99 compiler
> is required does not make any further difference to the user, IMO.
This seems in line with the current level of knowledge effort required to build a CMake project. There is an effort to get things right automatically, but if you want a specific compiler and things can't be guessed, you're on your own. I agree on this one.
> In order not to be misunderstood: Of course, I appreciate measures
> making the user's life easier, but I don't believe that choosing a
> suitable compiler via the CC environment variable is something that
> means an excessive demand for anyone.
I agree with this, too. I just think that it's possible to do better in this case. It's these kinds of convenience features that make CMake a pleasant build system. Thanks for putting the patch together -- I think we should replace my initial feature request with this because your patch is far more comprehensive.
-Todd
______________________________________________________________________
Todd Gamblin, tgamblin at llnl.gov, http://people.llnl.gov/gamblin2
CASC @ Lawrence Livermore National Laboratory, Livermore, CA, USA
More information about the CMake
mailing list