Building Cloudy C13 - Compile the code with an ANSI C++ compiler
The skinny on compiling the code. If you have a Linux computer, a Mac, or Windows with Cygwin, and have g++ and make installed then building the code is easy. Open a command prompt window, cd into the source directory, and type "make". If you have a multi-core system, you can type make -j <n> to do a parallel build, where <n> is the number of cores you want to use.
The code will be compiled and produce an executable named source/cloudy.exe. You can go to the next step, RunSmokeTest.
For more information on the use of the makefiles go to the MakefileDescription page.
Instructions for various compilers are given below.
Compilers we know don't work The code uses some fairly advanced parts of C++ and must be compiled with a standards-compliant C++ compiler. Testing shows that gcc 3.4.x, clang++ 3.4 and later (shipped with Xcode 5.1 and later -- this applies only to Cloudy versions C13.03 and older), the IA32 version of icc 10.1, and Pathscale EKOPath 2.3.1 cannot successfully compile this version of the code. The IA32 and Intel64 versions of icc 11.x and icc 12.x require special attention; see the remarks in the icc section below. Also the open64 compiler cannot successfully compile the code at high levels of optimization. It is not recommended. Cygwin 1.5.x features several broken g++ compilers. Mac users may have the current, broken, version of Xcode and should check the OS X notes below. Cygwin users should use version 1.7.x or newer of Cygwin and install the most recent compiler.
Makefiles. The gnu make utility is now the preferred method of building Cloudy. A collection of makefiles for several compilers is included in the sys_xxx subdirectories of the source directory in the code distribution. The MakefileDescription page describes how to use the make utility to compile Cloudy.
Configure script. Starting with the C10 release a configure script has been included in the source directory. This script needs to be executed prior to compiling the code. If you compile with make as advertised above, the script will be executed automatically and nothing extra needs to be done. However if you switch to a different compiler (this includes upgrading to a newer version) then make sure to type make distclean before starting the compilation. The configure script helps us deal with platform dependencies and idiosyncrasies of certain compilers.
inlining functions At high levels of optimization all compilers will inline functions. Most do not inline at low levels of optimization. The code will run about ten times more slowly without inlining. Inlining is enabled by default in all the makefiles.
Floating point exceptions. Compile options should be set so that the machine throws an exception ("crashes") on division by zero, overflow, and invalid operations. Underflow is inevitable and should not be trapped. Cloudy has code in the routine enable_traps (in the file cpu.cpp) that will set the proper floating point environment for nearly all systems. However, not all platforms are covered. Most notably floating point traps will not be enabled on G4/G5 (PowerPC) based systems.
A note on aggressive optimization. Safe levels of optimization, which we have seen work successfully, are shown in the following examples. If you try to use your compiler's very highest optimization levels you will just find compiler bugs, at least when compiling a code as large as Cloudy. Do a debug compile first, check that all went well by running the TestSuite, and recompile with optimization and run the test suite again. If that fails you will need to do a binary search to find the routine the compiler could not handle, by compiling half the code in debug, and half in optimized mode, eventually tracing down which files could not be compiled with aggressive optimization. The compiler vendor may fix the bug if you can isolate it down to a few lines of code. They won't help if you just tell them that a 200k-line code does not work with their compiler. My experience is that aggressive optimization only gains another 5 to 15 percent speedup and is generally not worth the bother. People time is far more expensive than machine time.
Warnings with routine ParseCrashDo. This routine contains logic that is intentionally designed to cause the code to crash. Good compilers will detect dangerous code and create a warning about the use of an uninitialized variable called ‘A_variable_which_SHOULD_be_used_uninitialized’. This is not a problem, it only means that you have a good compiler.
A note on LAPACK. A translated C++ version of some LAPACK routines is included in the source distribution (the file lapack.cpp). Your machine may have a precompiled and optimized version of this library that is faster than mine (for links to these versions, see SupportLibraries). Cloudy actually calls a wrapper for LAPACK that is resolved to either the internal routines (which have slightly changed names to avoid collisions with the real LAPACK) or your system's LAPACK library. If you set the macro LAPACK on the compiler command line (usually with the option -DLAPACK) then the wrappers will resolve to your system's LAPACK library. If the vendor worked hard to generate optimized code then this may be faster than the version obtained by simply compiling the source that comes with the distribution. You may have to include an additional library on the link step to actually load your version of LAPACK.
The assert macro. Asserts are a feature of safe computer languages. They provide for a simple way to insure that variables have sane values. They do slow down the calculation a bit. They can be turned off if you are confident that your compiler produces an executable that behaves properly. Asserts are turned off with the command-line option -DNDEBUG. You would write the compiler command line as something like "g++ <other compiler options> -DNDEBUG *.cpp" on the compile step. If you wish to turn off asserts it you should first run the test suite with optimized code and the asserts enabled. Once the test suite completes successfully the -DNDEBUG parameter can be added and the code recompiled. NB - It is important to run the test suite at least once with the asserts included - this could reveal compiler problems that would go unnoticed otherwise.
Array bounds checking Versions C08 and later have the option to do array bounds checking. This is set with the command-line option -DBOUNDS_CHECK. This will enable bounds checking on all arrays derived from the multi_arr and flex_arr container classes, but none of the other arrays. It makes the code much slower, so should only be used for debugging and testing purposes.
The remainder of this page gives advice on compiling the code on various platforms. Note that in the command lines shown below the "o" or "O" is the letter "oh" not the number zero.
To use this compiler, build in the source directory or in the sys_gcc subdirectory.
This is the preferred compiler. We recommend version 3.1 or later of g++, but not version 3.4 (see below). The code is tested with g++ on a regular basis.
Peter van Hoof found a way to disable gradual underflows when using g++ on ultrasparcs - this results in a major speedup. See the comments around the macro "HAVE_SUNMATH" in cpu.cpp.
Starting with the C08 release, Cloudy no longer compiles correctly with g++ compilers from the 3.4.x series due to a serious compiler bug. All g++ versions except 3.4.x will work OK. The compiler will issue an error when you try to compile with a g++ compiler from the 3.4.x series. Linux users with an old installation that contains a g++ 3.4.x compiler will have to upgrade to a newer g++ version, or use another compiler, like e.g. the Solaris Studio compiler for Linux (available free of charge). For other UNIX systems you can either use the native compiler, or upgrade to a newer g++ version.
Cygwin users should use Cygwin version 1.7.x or newer and install the most recent compiler. Cygwin 1.5.x features several compilers that will not work. There may be more than one version of perl installed on a cygwin/windows machine. The make command must find the cygwin version of perl or errors will result. The path must be set up to find the cygwin perl. The compilation should be done in a Cygwin terminal. MobaXterm is not supported.
To find out what version of g++ you have, issue the command "g++ -v".
Compiling the code on Itanium platforms may generate many warnings by the assembler that an "additional NOP may be necessary to work around the Itanium processor A/B step errata". These warnings appear to be benign.
Version 2.14.90 or 2.15 of glibc that ships with Fedora 16, and other recent Linux versions (such as Ubuntu precise), has a bug in the math library that causes Cloudy to crash with an FP exception shortly after startup. We have provided a fix for the problem, which should by now have propagated into all linux distributions. If you have an older linux version that still has the problem, a workaround is to download the AMD LibM replacement (this library also works on Intel processors). You need the download link at the bottom of the page for the most recent glibc versions. Unpack the tarball somewhere on your computer and compile Cloudy with:
make -j <n> LDLIBS='-lamdlibm -L/path/to/amdlibm-x-y-z-lin64/lib/static/'
where "/path/to" should point to the location where you unpacked the tarball and "x-y-z" should be replaced with the version number of the library that you downloaded (e.g. "amdlibm-3-0-2-lin64"). This will only work on 64-bit systems. You can also install the Oracle Solaris Studio compiler (see below). That should also work on 32-bit systems.
The code is tested with g++ on a regular basis. However it is not feasible to test every version of the code against every version of g++ on every platform. It is therefore important that you run the test suite to test the particular combination that you are using.
Version 3.4 and later of this compiler cannot build Cloudy versions up to and including C13.03. Use an older version. Cloudy versions C13.04 and later work around the problem and can be compiled with recent versions of this compiler.
To use this compiler, build in the sys_llvm subdirectory.
The LLVM compiler can be downloaded free of charge from the LLVM Download Page. LLVM is the name of the project. Their C++ compiler is clang++. Choose the clang binaries that are appropriate for your platform. This compiler has the advantage that it is really easy to install (even without root privileges) and is a very fast compiler. We tested version 3.2 and later of the compiler. Note that clang++ versions 3.4 and later have a serious problem that creates a broken binary with default levels of optimization for Cloudy versions up to and including C13.03.
See the notes below about compiling on a Mac. The version of LLVM which shipped with Xcode 4.1 is broken and cannot compile the code. The LLVM version which shipped with Xcode 5.1 and later doesn't work either. Other versions do work.
Portland Group pgCC
To use this compiler, build in the sys_pgcc subdirectory.
This compiler is one of the very few that includes native array bounds checking in a C/C++ code. The compiler web site is here.
The -A option detects code that does not conform to the ANSI/ISO C++ standard. It produces many errors concerning header files in the PGI distribution we use. Many thanks to Mitchell Martin for testing this compiler.
To use this compiler, build in the sys_icc subdirectory.
Update 2014/03/06 - Tests show that the test suite passes with both icc 13.1.3 and 14.0.1.
We tested versions 10.x, 11.x, and 13.0 of icc. The default level of optimization enables rather aggressive forms of floating-point optimization that interfere with the correct execution of Cloudy. It is essential to use the "-fp-model source -fp-model except -fp-speculation off" flags in order to disable those optimizations.
Note that the default level of optimization is -O2, and not -O0 as with most other compilers.
Versions prior to icc 10.0 are not supported. They may not work correctly unless you use lower levels of optimization ("-O1 -mp" or even "-O0"). Make sure you run the test suite if you use such a compiler. Versions 12.0 and 12.1 also need a lower level of optimization (see warning 3 below). Version 13.0 works fine again.
You may get a warning "feupdateenv is not implemented and will always fail" during the link phase. This warning appears to be benign and can be ignored.
WARNING 1: We have noticed that on platforms with glibc versions from 2.9 or 2.10 upwards, the code produced by icc 11.1 hangs indefinitely very early on (while reading the input lines). This appears to be due to an incorrect handling of inlined routines like memchr(). The problem appears both in the IA32 and the Intel64 version of the compiler. You can work around this by recompiling the code with the flag -U__OPTIMIZE__ added. It is unknown whether the Itanium version of the compiler is also affected by this problem. In Cloudy C08.01 and later this flag is automatically added by the make file.
WARNING 2: Testing has shown that the IA32 version of icc 10.1 is incapable of compiling the code correctly with any level of optimization. We recommend that you use another version of icc, or g++, or the Solaris C++ compiler instead. This problem is only present on IA32 platforms, and not on any of the 64-bit platforms, and occurs only with icc 10.1.
WARNING 3: Testing on an amd64 platform has shown that icc 12.x produces a broken binary. This does not show up when running the smoke test, but does show up when running the entire test suite. The 32-bit version of icc 12.x has not been tested, so the status for that platform is unknown. Changing "-O3" to "-O1" in the compiler flags produces a valid binary on our 64-bit platforms. If you want to use this compiler version, make sure that you lower the optimization level and include -DMM in the compiler flags to bypass the compiler check built into Cloudy.
icc on Mac Apple updated Xcode to 3.2.2 in Spring 2010. This upgrade breaks the intel C++ 11.1
compiler. Cloudy will no longer pass its smoke test. Intel has posted a hack that seems to work -
include the option
on both the compile and link steps.
Many thanks to Peter van Hoof and Ryan Porter for testing this compiler.
Oracle Developer Studio compiler for Linux (formerly Solaris / Sun Studio compiler)
Oracle provides a C++ compiler for Linux that can be obtained free of charge from the Oracle download page. When downloaded as a tarball it has the advantage that it can be installed without any root privileges. It can produce code for both IA32 and AMD64/EM64T platforms. We tested the Solaris Studio 12.4 and 12.5 compilers.
To use version 12.5 of this compiler, build in the sys_oraclestudio subdirectory (only available in c13.05).
The -Yl,/usr/bin flag is needed to work around an incompatibility between the (modified) linker supplied by Oracle and the object file format in recent Linux distributions. If the compiler does not recognize the linux version you have, it will still fall back to the modified linker included in the distribution. This modified linker will break your code and should never be used on modern Linux distributions. If you get this warning when compiling:
CC: Warning: failed to detect system linker version, falling back to custom linker usage
then you will get the broken linker. The workaround is to remove the broken linker and replace it with a symlink to the system linker.
cd /path/to/developerstudio12.5/lib/compilers/amd64 mv ld ld.broken ln -s /usr/bin/ld .
To use version 12.4 or lower of this compiler, build in the sys_solstudio subdirectory.
The -library=stlport4 selects a more modern STL implementation that is fully compatible with the ANSI/ISO standard instead of the default Rogue Wave implementation. Cloudy will not compile correctly with the Rogue Wave version of the STL.
Important. Release 12.1 of the Sun Studio compiler will not work correctly on modern Linux distributions that have g++ 4.4.0 or higher. The symptom is that you get lots of errors like:
"/usr/include/stdio.h", line 480: Error: "(" expected instead of "__attribute__". "/usr/include/stdio.h", line 480: Error: "(" expected instead of "__attribute__". "/usr/include/stdio.h", line 480: Error: ")" expected instead of "__attribute__". ... etc ...
The work-around is to modify the file /path/to/sunstudio12.1/prod/include/cc/sys/cdefs.h and apply the following patch:
*** cdefs.h.org 2009-06-04 05:07:18.000000000 +0200 --- cdefs.h 2010-04-20 15:03:13.768273355 +0200 *************** *** 14,20 **** --- 14,25 ---- * for compilers which don't define __GNUC__. We don't define __GNUC__ * but want attributes support, hence the interposed header. */ + /* + disabled until both compilers can accept attributes syntax + */ + #ifndef __cplusplus #undef __attribute__ + #endif /* * use REDIRECT only for C++/C99 as it uses C99 _Pragma operator
MAC OS X
The current version of Xcode ships with a broken version of LLVM and Xcode no longer includes gcc. To get a working compiler see the CompilingCloudyOSX page.
Cloudy versions C13.04 and later will compile correctly with recent versions of Xcode.
You need the command line build tools which are a free download from here. This includes make, gcc 4.2.1, and a recent version of LLVM.
Both gcc and LLVM compilers work well and are the recommended ways to build the code on a Mac. Note that Apple has announced that it will stop providing gcc 4.2.1 in Xcode versions after 4.6 and recommends that LLVM be used in its place. The two compilers are highly compatible. From Xcode 5.0 onwards, g++ has been removed but a symbolic link g++ -> clang++ is provided which makes the change transparent to Cloudy users.
The versions of LLVM which ship with Xcode 4.1 and Xcode 5.1 and later are broken. Other versions do work. See the CompilingCloudyOSX page.
MS Visual Studio 2012
The Visual C++ Express Edition is a free download at http://msdn.microsoft.com/vstudio/express/visualc/. You need Visual C++ 2010 or later. Previous versions do not work.
Creating a new project
Use file/new to create a new project. In "Project Types" select "Visual C++ Projects" / Win32. Enter a name for the project and browse to a location. Click OK. The project will be in a folder under that specified in the location. Under "application settings" select "console application" and "empty project", then "finish" Add all the source and header files to the project with the "project/add existing files" option. Then remove the files with names "Test*.cpp" as they are not used.
under "project / properties / configuration properties" set the following for all configurations:
"c/c++ / preprocessor / preprocessor definitions" add the following:
The string in the CLOUDY_DATA_PATH macro should be modified to give the actual location of the code's data directory. If there are problems setting the path, it can alternatively be set by editing the path.h file. Path.h contains instructions for setting the path depending on operating system. Define the macro OLD_ASSERT if you wish to use old-style asserts.
Under "c/c++ / optimization " make sure that "inline function expansion" is set to "only __inline". The code will run about ten times more slowly if this is not set.
Under "c/c++/general" set "Debug Information Format" to "Program Database (Z/i)"
Disable warnings 4244; 4305; 4355; in configuration properties / c/c++ / advanced - these warn against implicit demotions.
To compile in multiple threads, in "c/c++/general" set "Multi-Processor Compilation" to "Yes (/MP)", but you will also have to under "c/c++/code generation" change "Enable Minimal Rebuild" to "No (/Gm-)" as the two options are incompatible. The /MP option is also incompatible with the #import, /E, /EP, /showIncludes, and /Yc, but in the versions tested these were not used by default.
Pathscale EKOPath and open64 compilers - WARNING!!!
These compilers can produce code for both IA32 and AMD64/EM64T platforms.
We do not recommend using the Pathscale EKOPath or the open64 compiler. We were able to get the test suite to pass only with low levels of optimization. We recommend g++ on these platforms.
RunCode describes how to run the code
Return to StepByStep instructions.
Return to nublado.org