[CMake] OS X architecture changes interfere with CheckTypeSize()?

Erik Lindahl lindahl at cbr.su.se
Wed Aug 11 14:17:29 EDT 2010


Hi Mike,

Oh, we already have a _huge_ amount of configuration #ifdefs since we run on virtually every hardware and OS there is that supports ANSI C. Think Fujitsu FR-V embedded chips, MIPS, ia64, Cray Unicos, Playstation3, Sparc & Sparc64, PowerPC, Power5,6,7, PowerCell 8xi, BlueGene (with and without Posix environments on nodes) and Cuda - just to mention a few. 
Gromacs is probably one of the most widespread computational chemistry softwares in the world, as well as the engine in Folding at Home (and we actually _have_ ported it to the iphone too, but performance there is horrible :-).   

That's the very reason we want general tests for headers and data type sizes at configuration time rather than manual vendor-specific #ifdef sections that have to be re-checked for new OS/compiler versions.


CheckTypeSize() seems to have lots of logic to do the right thing for multiple architectures and report type sizes as key/value pairs, which we should use in the future.  However, I guess that too will run into the same problem if all the values in the cache are based on the default value before the user has a chance to actually _set_ CMAKE_OSX_ARCHITECTURE to the proper list of multiple architectures.


The CMAKE_OSX_ARCHITECTURE is already OSX-specific, and CMake already contains all the code to properly detect variable sizes and other architecture-dependent stuff - provided one calls CMake on the command line and specify the architecture there.


To be concrete, wouldn't it make a lot more sense if the OS X architecture setting is treated the same way as the compiler setting, and forces a cache clean if the user changes it? 


Cheers,

Erik


> 
>  OS X is "special" because of all the platforms that CMake supports it is the only one where you can compile for multiple architectures at the same time. All the other platforms assume 1) you are compiling for the platform you are running on or 2) you are cross compiling and you have the appropriate platform definition files for CMake. OS X is a mixture of both of those. The other thing you can do is to have your own CheckTypeSize() that has logic to look for changes in the OS X Architectures string in CMake and then rerun the tests when cmake is run the next time. This will still ONLY get a single arch correct if you are compiling for 2 archs (say i386 and x86_64) at the same time.
>  You could also detect more than a single arch in the CMAKE_OSX_ARCHS and error out with a message stating that only a single arch is supported at a time.
>  One thing is for sure though. If you ignore the fact that you NEED these special #ifdefs your code may contain very subtle bugs that will not be found until edge cases are hit by your users during runtime. OR the inability to compile Universal Binaries of your code.
> 
> Really the things to look for you in your code are uses of "long" or "size_t" in things like calculations where on 32 bit systems the value would overflow. Or pointer math in some situations. Not sure what to tell you. Most projects have something like this in them.
> 
> Cheers
> --
> Mike Jackson <www.bluequartz.net>
> 
> On Aug 11, 2010, at 1:31 PM, Erik Lindahl wrote:
> 
>> Hi,
>> 
>> Thanks for the suggested workaround Mike!
>> 
>> However, that will get pretty cluttered when we add everything we need for 50MB of source code... Our entire reason for moving from autoconf CMake is to avoid having Windows as a "special case", so we'd rather not exchange it for having OS X as a special case :-)
>> 
>> If the OS X architecture/s has/have to be set before starting CMake (just as the compilers), wouldn't the natural solution be to ask the user for it at the same time as the compilers, and then not make it editable in the GUI/ccmake parameter list (In particular if there's large risk of inconsistent results if you actually do edit it, which I'd say the blank initial value is an invitation to :-)?
>> 
>> 
>> Cheers,
>> 
>> Erik
>> 
>> 
>> On Aug 11, 2010, at 7:03 PM, Michael Jackson wrote:
>> 
>>> So basically you will "over ride" some of the values that get returned from those tests for OS X. Typically you end up with a "Configuration" file that has something like this in it:
>>> 
>>> #if !defined(__APPLE__)
>>> /* The size of `size_t', as computed by sizeof. */
>>> #define MXA_SIZEOF_SIZE_T
>>> 
>>> /* The size of `ssize_t', as computed by sizeof. */
>>> #define MXA_SIZEOF_SSIZE_T
>>> 
>>> /* The size of `long', as computed by sizeof. */
>>> #define MXA_SIZEOF_LONG
>>> 
>>> #else
>>> # if defined(__LP64__) && __LP64__
>>> #define MXA_SIZEOF_LONG 8
>>> #define MXA_SIZEOF_SIZE_T 8
>>> #define MXA_SIZEOF_SSIZE_T 8
>>> # else
>>> #define MXA_SIZEOF_LONG 4
>>> #define MXA_SIZEOF_SIZE_T 4
>>> #define MXA_SIZEOF_SSIZE_T 4
>>> # endif
>>> 
>>> #endif
>>> 
>>> and then you end up with a "Types.h" file with something like this in it:
>>> 
>>> /* Select a 64-bit integer type.  */
>>> #if defined(MXA_TYPE_USE_LONG_LONG) && MXA_SIZEOF_LONG_LONG == 8
>>> #if !defined(_UINT64_T) && !defined(MXA_SIZEOF_UINT64_T)
>>> #define _UINT64_T
>>> typedef unsigned long long   uint64_t;
>>> #endif /* _UINT64_T */
>>> 
>>> #if !defined(_INT64_T) && !defined(MXA_SIZEOF_INT64_T)
>>> #define _INT64_T
>>> typedef long long            int64_t;
>>> #endif /* _INT64_T */
>>> 
>>> # define MXA_TYPE_UINT64 MXA_UNSIGNED_LONG_LONG
>>> # define MXA_TYPE_INT64 MXA_LONG_LONG
>>> 
>>> #elif MXA_SIZEOF_LONG == 8
>>> #if !defined(_UINT64_T) && !defined(MXA_SIZEOF_UINT64_T)
>>> #define _UINT64_T
>>> typedef unsigned long   uint64_t;
>>> #endif /* _UINT64_T */
>>> 
>>> #if !defined(_INT64_T) && !defined(MXA_SIZEOF_INT64_T)
>>> #define _INT64_T
>>> typedef long            int64_t;
>>> #endif /* _INT64_T */
>>> # define MXA_TYPE_UINT64 MXA_UNSIGNED_LONG
>>> # define MXA_TYPE_INT64 MXA_LONG
>>> 
>>> #elif defined(MXA_TYPE_USE___INT64) && MXA_SIZEOF___INT64 == 8
>>> 
>>> #if !defined(_UINT64_T) && !defined(MXA_SIZEOF_UINT64_T)
>>> #define _UINT64_T
>>> typedef unsigned __int64 uint64;
>>> #endif /* _UINT64_T */
>>> 
>>> #if !defined(_INT64_T) && !defined(MXA_SIZEOF_INT64_T)
>>> #define _INT64_T
>>> typedef signed __int64   int64;
>>> #endif /* _INT64_T */
>>> 
>>> # define MXA_TYPE_UINT64 MXA_UNSIGNED___INT64
>>> # define MXA_TYPE_INT64 MXA___INT64
>>> 
>>> #else
>>> # error "No native data type can represent a 64-bit integer."
>>> #endif
>>> 
>>> NOTE: this does NOT take into account compiling for the iPhone environment.
>>> 
>>> All of this is stored in a pair of files that get configured using "configure_file()" cmake command. Then in your code you explicitly use the types that you have defined above and all should work out when compiling on OS X with multiple Archs because the above files will control how the various ambiguous types get compiled. Which means that your source codes MUST at some point include these header files.
>>> ___________________________________________________________
>>> Mike Jackson                      www.bluequartz.net
>>> Principal Software Engineer       mike.jackson at bluequartz.net
>>> BlueQuartz Software               Dayton, Ohio
>>> 
>>> 
>>> 
>>> On Aug 11, 2010, at 12:08 PM, Erik Lindahl wrote:
>>> 
>>>> Hi cmake-list,
>>>> 
>>>> We've run into a minor problem when adapting our source code Gromacs to use CMake for the default build environment.
>>>> 
>>>> CMake 2.8 doesn't use any string for the default OS X architecture, which on Snow Leopard is interpreted as the default x86_64.
>>>> All the CheckTypeSize() tests then seem to run directly when e.g. ccmake is invoked, and they thus set all SIZEOF_XXX defines to the 64-bit values (e.g. 8 for "long int").
>>>> 
>>>> Even if I set the architecture to "i386" the very first thing I do in ccmake, the 64-bit values appear to be cached(?), and we then happily continue to create a 32-bit build with 64-bit SIZEOF_XXX values, which tends to break things in a hard way :-)
>>>> 
>>>> If we use -DCMAKE_OSX_ARCHITECTURES=i386 on the command line when starting a new build tree everything works fine.
>>>> 
>>>> 
>>>> Is there any way we can work around this? My main worry is that people will simply start ccmake, set the architecture, and then produce a bad build without getting any warnings about it...
>>>> (we tend to use i386 pretty frequently since we need to create compatible versions for distributed computing).
>>>> 
>>>> 
>>>> Cheers,
>>>> 
>>>> Erik
>>>> 
>>>> ----------------------------------------------------------
>>>> Erik Lindahl <lindahl at cbr.su.se>
>>>> Professor, Computational Structural Biology
>>>> Center for Biomembrane Research & Swedish e-Science Research Center
>>>> Department of Biochemistry & Biophysics, Stockholm University
>>>> Tel: +468164675 Cell: +46703844534
>>>> 
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>> 
>>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>> 
>>>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>>> 
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.cmake.org/mailman/listinfo/cmake
>>> 
>>> _______________________________________________
>>> Powered by www.kitware.com
>>> 
>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>> 
>>> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>>> 
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.cmake.org/mailman/listinfo/cmake
>>> 
>> 
>> ----------------------------------------------------------
>> Erik Lindahl <lindahl at cbr.su.se>
>> Professor, Computational Structural Biology
>> Center for Biomembrane Research & Swedish e-Science Research Center
>> Department of Biochemistry & Biophysics, Stockholm University
>> Tel: +468164675 Cell: +46703844534
>> 
> 
> _______________________________________________
> Powered by www.kitware.com
> 
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
> 
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
> 
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
> 

----------------------------------------------------------
Erik Lindahl <lindahl at cbr.su.se>
Professor, Computational Structural Biology
Center for Biomembrane Research & Swedish e-Science Research Center
Department of Biochemistry & Biophysics, Stockholm University
Tel: +468164675 Cell: +46703844534



More information about the CMake mailing list