[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