GCC Gfortran and Intel oneAPI are the most advanced, widely available modern Fortran compilers.
Useful Fortran 2018 enhancements include:
select rankassumed array rank,
error stop
within pure procedures,
random_init
to initialize random number seed, and
implicit none (type, external)
to require external procedures to be explicitly declared.
GCC 10 is the
oldest version
currently maintained.
Intel oneAPI has full Fortran 2018
support.
To get recent GCC is usually straightforward.
Red Hat should use
GCC Toolset.
macOS Homebrew quickly adds the latest
GCC version.
If Ubuntu gfortran repo
defaults
aren’t adequate, get recent Gfortran via
PPA.
Here are some of the major changes in Gfortran by version:
Gfortran 12 enhances OpenMP 5 and OpenACC 2.6 support. Numerous bugfixes. bind(C) with character length greater than one.
Gfortran 11 completed OpenMP 4.5 support
Gfortran 10 added select rank
Gfortran 9 added random_init() to initialize the random generator seed.
Gfortran 8 added automatic nested loop exchange with do concurrent, actual argument array with too few elements for dummy argument now errors, initial support for parameterized derived types (simply define kind at initialization) and coarray support for teams. Standard flag -std=f2018 added and deprecated -std=f2008ts.
Gfortran 7 added derived type IO select type. Complete Fortran 2003 support, Fortran 2018 non-constant stop and error stop codes, and -fdec- options to help compile very old non-standard code.
Gfortran 6 added Fortran 2008 submodule support, useful for large projects to save compilation time and allow powerful use scenarios.
Fortran 2003 deferred-length character are
useful
for avoiding bothersome trim() everywhere.
GCC 5 added full support for OpenMP 4.0, Fortran 2003 ieee_ intrinsics, Fortran 2008 error stop in pure procedures with constant error code.
GCC 4.9 added Fortran 2003 deferred-length character variables in derived types.
GCC 4.8 supported Fortran 2008 polymorphism, including select type, class(*), type(*), and Fortran 2018 assumed rank dimension(..).
GCC 4.6 was the first version of Gfortran reaching beyond Fortran 95, with Fortran 2003 deferred-length character variable and Fortran 2008 impure elemental support.
GCC 4.5 added Fortran 2008 iso_fortran_env.
GCC 4.4 added initial support for polymorphism and OpenMP 3.
CMake allows switching parameters based on compiler version.
This is very useful for modern Fortran programs.
Example CMakeLists.txt for Fortran compiler version dependent options.
Major projects with CPU arch-specific code may distribute binaries for multiple CPU architectures for operating systems.
Apple Silicon is a key example.
For example, Anaconda Python has Intel and Apple Silicon installers.
Check
if a C++, GNU Octave, Matlab, or Python executable on Apple Silicon is using native or Rosetta.
CMake can
detect the host CPU arch
to use with Intel compilers.
We discourage package maintainers from settings flags like “-march=native” (GCC, Clang) and “-xHost” (Intel oneAPI) because they may break on user systems such as ARM or HPC.
However, the user can set flags for a project by setting environment variables like CFLAGS before the first project configure in CMake.
This allows optimizing for a target compiler while compiling from a different host.
Or, the user on an appropriate system may simply set their ~/.profile to have CFLAGS=-march=native or similar.
Projects use a variety of methods to detect which compiler is being used to thereby set compilation options.
Although this discussion focuses on Fortran, it is easily and equally applicable to other languages such as C and C++.
Robustly detect compiler in CMake
CMAKE_Fortran_COMPILER_ID.
This tells the compiler vendor (GNU, Intel, Clang, etc.)
Don’t use
CMAKE_Fortran_COMPILER
because there are several compiler executables per vendor and this will not be robust over time.
To get the compiler version,
CMAKE_Fortran_COMPILER_VERSION
allows version comparisons.
Cygwin startup configuration is controlled by Windows environment variable
CYGWIN.
Not populating Cygwin PATH from Windows PATH avoids confusion from Windows programs being used instead of Cygwin programs.
Set Windows environment variable:
CYGWIN_NOWINPATH=1
will result in a basic Cygwin PATH like:
/usr/local/bin:/usr/bin
Look inside Cygwin “/etc/profile” for more environment variables that may be of interest.
NOTE: all Windows environment variables are
imported
by Cygwin.
Override these variables in ~/.profile or scripts if desired.
Libutil gives abstractions for OS-specific TTY operations.
When using these abstractions across macOS and Linux, use this preprocessing statement for the appropriate header:
OpenWatcom
is an open-source C/C++ compiler that can compile for a variety of systems, particularly legacy 16/32-bit Windows and DOS systems.
This can be of interest for retro gamers and those using old devices that have DOS-based software, including industrial controllers and two-way radio programming.
CMake supports OpenWatcom, and is conveniently used with a toolchain file.
GitHub Actions has easy scripting for OpenWatcom to test building of DOS programs from Linux.
The easiest way to show this is by example: see the Ascii Patrol game for how to build with OpenWatcom for DOS from Windows/Linux and GitHub Actions build CI.
CMake
target_compile_features
sets a transitive MINIMUM language standard necessary.
If the compiler defaults to a newer language standard, target_compile_features()
allows that default higher language standard.
This can make issues for legacy code that requires an older language standard.
For example, an old C++98 code may need to have the compiler in C++98 mode.
This is accomplished with the target property
CXX_STANDARD.
Other languages may have a similar property e.g. C_STANDARD.