[MacPorts] CompilerSelection added

MacPorts Wiki noreply at macports.org
Mon Jan 14 00:25:37 UTC 2019


Page "CompilerSelection" was added by MarcusCalhoun-Lopez
Comment: Attempted description of https://github.com/macports/macports-base/pull/88
Content:
-------8<------8<------8<------8<------8<------8<------8<------8<--------
== Overview ==

The flexibility of a [https://guide.macports.org/#development Portfile] allows MacPorts to support a wide variety of languages.
The lowest level of support is for a Portfile to call the appropriate build command.
The port [https://github.com/macports/macports-ports/blob/master/math/lapack/Portfile lapack-manpages] builds documentation by calling [https://en.wikipedia.org/wiki/Doxygen doxygen].
Commonality among several ports can be gathered into a [https://guide.macports.org/#reference.portgroup portgroup].
For example, [https://github.com/macports/macports-ports/blob/master/_resources/port1.0/group/cargo_fetch-1.0.tcl there is a portgroup] that facilitates building projects written in [https://en.wikipedia.org/wiki/Rust_(programming_language) Rust]. However, some language have direct support in the [https://guide.macports.org/#introduction MacPorts base].

== Minimal Base Support ==
[https://en.wikipedia.org/wiki/Perl Perl],
[https://en.wikipedia.org/wiki/Python_(programming_language) Python],
[https://en.wikipedia.org/wiki/Ruby_(programming_language) Ruby],
[https://en.wikipedia.org/wiki/AWK Awk],
[https://en.wikipedia.org/wiki/GNU_Bison Bison],
and
[https://en.wikipedia.org/wiki/Java_(programming_language) Java]
have minimal support in the base through
{{{
configure.perl
configure.python
configure.ruby
configure.awk
configure.bison
configure.javac
}}}
These commands do nothing more than set environmental variables during the [https://guide.macports.org/#reference.phases configure phase] if [https://guide.macports.org/#reference.phases.configure use_configure] is {{{yes}}}.
They do **not** add [https://guide.macports.org/#reference.dependencies dependencies].

== Full Base Support ==
[https://en.wikipedia.org/wiki/C_(programming_language) C] and [https://en.wikipedia.org/wiki/C%2B%2B C++] are fully supported in the base. This means that, unless instructed otherwise, each Portfile will have access to a compiler for both of these languages.
* {{{configure.cc}}}, {{{configure.cxx}}}, and {{{configure.cpp}}} are set.
* The environmental variables {{{CC}}} and {{{CXX}}} are set during the configure phase if {{{use_configure}}} is {{{yes}}}.
* If MacPorts provides the compiler, the appropriate dependencies are added.

Ideally, [https://guide.macports.org/#installing.xcode Xcode] would provide the C and C++ compilers.
This ideal, however, cannot always be achieved.
MacPorts have two alternates to provide C and C++ compilers: [https://en.wikipedia.org/wiki/Clang Clang] and [https://en.wikipedia.org/wiki/GNU_Compiler_Collection GCC].

=== Language Standards ===
Both C and C++ evolve.
A project can require a more recent [https://en.wikipedia.org/wiki/C_(programming_language)#History C standard] or [https://en.wikipedia.org/wiki/C%2B%2B#Standardization C++ standard] than is provided by the Xcode compiler.

C Standards supported by Clang, GCC, and Xcode:
||= C Standard   =||=  Clang  =||=  [https://trac.macports.org/wiki/XcodeVersionInfo Xcode Clang]  =||=   Xcode   =||=  GCC  =||
||= 1989 (C89)   =||     -      ||        -          ||    -        ||     -     ||
||= 1999 (C99)   =||     -      ||    211.10.1   ||    4.2    ||    [https://gcc.gnu.org/c99status.html 4.5]    ||
||= 2011 (C11)    =||    [https://releases.llvm.org/3.1/docs/ClangReleaseNotes.html#cchanges 3.1]  ||    318.0.61  ||    4.3    ||    [https://gcc.gnu.org/wiki/C11Status 4.9]    ||

[https://en.cppreference.com/w/cpp/compiler_support C++ Standards supported by Clang, GCC, and Xcode]:
||=  C++ Standard =||=   Clang   =||=  Xcode Clang  =||=   Xcode   =||=    GCC  =||
||= 1998 (C++98) =||    [https://clang.llvm.org/cxx_status.html#cxx98 -]     =||=       -      =||=     -    =||=    [https://gcc.gnu.org/projects/cxx-status.html#cxx98 -]      =||
||= 2011 (C++11) =||    [https://clang.llvm.org/cxx_status.html#cxx11 3.3]    ||   500.2.75    ||    5.0    ||   [https://gcc.gnu.org/projects/cxx-status.html#cxx11 4.8.1]   ||
||= 2014 (C++14) =||    [https://clang.llvm.org/cxx_status.html#cxx14 3.4]    ||   600.0.54    ||    6.1    ||    [https://gcc.gnu.org/projects/cxx-status.html#cxx14 5]     ||
||= 2017 (C++17) =||    [https://clang.llvm.org/cxx_status.html#cxx17 5.0]    ||   902.0.39.1  ||    9.3    ||    [https://gcc.gnu.org/projects/cxx-status.html#cxx17 7]     ||

=== Parallelism ===
The compilers provided by Xcode do not support all of the methods of parallelism that ports may require.

None of the compilers provided by Xcode support any version [https://en.wikipedia.org/wiki/OpenMP OpenMP].    
OpenMP Standards supported by Clang, GCC, and Xcode:
||= OpenMP Version =||=  Clang  =||=  Xcode Clang  =||=  Xcode  =||=   GCC   =||
||=      2.5       =||   [https://openmp.llvm.org 3.8]   ||    Future?    || Future? ||   [https://gcc.gnu.org/wiki/openmp  4.2]   ||
||=      3.0       =||   [https://openmp.llvm.org 3.8]   ||    Future?    || Future? ||   [https://gcc.gnu.org/wiki/openmp  4.4]   ||
||=      3.1       =||   [https://openmp.llvm.org 3.8]   ||    Future?    || Future? ||   [https://gcc.gnu.org/wiki/openmp  4.7]   ||
||=      4.0       =|| [https://openmp.llvm.org Partial] ||    Future?    || Future? ||   [https://gcc.gnu.org/wiki/openmp  4.9]   ||
||=      4.5       =|| [https://openmp.llvm.org Partial] ||    Future?    || Future? ||   ???   ||

None of the compilers provided by Xcode implement [https://en.wikipedia.org/wiki/Message_Passing_Interface MPI].
To implement it, [https://en.wikipedia.org/wiki/MPICH MPICH] and [https://en.wikipedia.org/wiki/Open_MPI Open MPI] provide wrappers for Clang, GCC, and Xcode.

The compilers provided by Xcode only support [https://en.wikipedia.org/wiki/Thread-local_storage thread-local storage] if the OS supports it, which did not happen until [https://en.wikipedia.org/wiki/Mac_OS_X_Lion Mac OS X Lion].
GCC and Clang can emulate thread-local storage even on versions of macOS that do not support it.

=== C++ Standard Library ===
There are three possible [https://en.wikipedia.org/wiki/C%2B%2B_Standard_Library C++ standard libraries] on macOS.

C++ standard libraries supported by Clang, GCC, and Xcode:
||= C++ Standard Library =||=  Supported by Clang  =||=  Supported  by Xcode  =||=   Supported  by GCC   =||= Supports C++11 =||
||=[https://libcxx.llvm.org libc++] =|| Yes ({{{-stdlib=libc++}}}) ||Yes ({{{-stdlib=libc++}}}) || No || Yes ||
||=[https://gcc.gnu.org/onlinedocs/libstdc++ libstdc++ in /usr/lib/] =||Yes ({{{-stdlib=libstdc++}}}) || Yes ({{{-stdlib=libstdc++}}}) || No || No ||
||=[https://gcc.gnu.org/onlinedocs/libstdc++ libstdc++ provided by MacPorts] =||Yes ({{{-stdlib=macports-libstdc++}}}) || No || Yes || Yes ||

=== Getting the Right Compiler in the Portfile ===
Names of valid Compilers:
||= [https://en.wikipedia.org/wiki/Regular_expression Regular Expression] =||= Description =||
|| {{{^apple-gcc-(4\.[02])$}}} || MacPorts Apple GCC %s ||
|| {{{^cc$}}} || System cc ||
|| {{{^clang$}}} || Xcode Clang ||
|| {{{^gcc$}}} || System GCC ||
|| {{{^gcc-(3\.3|4\.[02])$}}} || Xcode GCC %s ||
|| {{{^llvm-gcc-4\.2$}}} || Xcode LLVM-GCC 4.2 ||
|| {{{^macports-clang$}}} || MacPorts Clang (port select) ||
|| {{{^macports-clang-(\d+\.\d+)$}}} || MacPorts Clang %s ||
|| {{{^macports-dragonegg-(\d+\.\d+)$}}} || MacPorts DragonEgg %s ||
|| {{{^macports-dragonegg-(\d+\.\d+)-gcc-(\d+\.\d+)$}}} || MacPorts DragonEgg %s with GCC %s ||
|| {{{^macports-gcc$}}} || MacPorts GCC (port select) ||
|| {{{^macports-gcc-(\d+(?:\.\d+)?)$}}} || MacPorts GCC %s ||
|| {{{^macports-llvm-gcc-4\.2$}}} || MacPorts LLVM-GCC 4.2 ||
|| {{{^macports-g95$}}} || MacPorts G95 ||
|| {{{^macports-mpich-default$}}} || MacPorts MPICH Wrapper for MacPorts' Default C/C++ Compiler ||
|| {{{^macports-openmpi-default$}}} || MacPorts Open MPI Wrapper for MacPorts' Default C/C++ Compiler ||
|| {{{^macports-mpich-clang$}}} || MacPorts MPICH Wrapper for Xcode Clang ||
|| {{{^macports-openmpi-clang$}}} || MacPorts Open MPI Wrapper for Xcode Clang ||
|| {{{^macports-mpich-clang-(\d+\.\d+)$}}} || MacPorts MPICH Wrapper for Clang %s ||
|| {{{^macports-openmpi-clang-(\d+\.\d+)$}}} || MacPorts Open MPI Wrapper for Clang %s ||
|| {{{^macports-mpich-gcc-(\d+(?:\.\d+)?)$}}} || MacPorts MPICH Wrapper for GCC %s ||
|| {{{^macports-openmpi-gcc-(\d+(?:\.\d+)?)$}}} || MacPorts Open MPI Wrapper for GCC %s ||

The compiler is chosen with the following precedence:
1. If {{{configure.compiler}}} is set in the Portfile, then that is the compiler that is used.
1. If the user sets {{{default_compilers}}}, the compiler is chosen from that list unless the compiler is blacklisted.
1. If the Portfile sets {{{compiler.whitelist}}}, the compiler is chosen from that list unless the compiler is blacklisted. 
1. If the Portfile sets {{{compiler.fallback}}}, the compiler is chosen from that list unless the compiler is blacklisted. 
1. A compiler is chosen (Xcode compilers if possible) that
 * is not blacklisted,
 * is known to work on the particular version of the OS, and
 * satisfies the requirements set in the Portfile.

The following are requirements that can be set in the Portfile:
||= =||= Description =||= Possible Values =||= Default =||
|| {{{compiler.c_standard}}} || Standard for the C programming language || 1989, 1999, 2011, etc. || 1989 ||
|| {{{compiler.cxx_standard}}} || Standard for the C++ programming language || 1998, 2011, 2014, 2017, etc. || 1998 ||
|| {{{compiler.openmp_version}}} || Version of OpenMP required || blank, 2.5, 3.0, 3.1, 4.0, 4.5, etc. || blank ||
|| {{{compiler.mpi}}}  ||  MacPorts port that provides MPI || blank, mpich, or openmpi || blank ||
|| {{{compiler.thread_local_storage}}}  || Is thread local storage required, e.g. {{{__thread}}}, {{{_Thread_local}}}, or {{{std::thread_local}}} || yes or no || no || 
|| {{{configure.cxx_stdlib}}} || C++ Standard Library || blank, libc++, libstdc++, or macports-libstdc++ || dependent on user preference and OS version ||

== Medium Base Support ==
[https://en.wikipedia.org/wiki/Objective-C Objective-C] and
[https://en.wikipedia.org/wiki/Objective-C#Objective-C++ Objective-C++]
are supported as well.
* {{{configure.objc}}} and {{{configure.objcxx}}} are set.
* The environmental variables {{{OBJC}}} and {{{OBJCXX}}} are set during the configure phase if {{{use_configure}}} is {{{yes}}}.
This is achieved, however, by assuming that the Objective-C and Objective-C++ compilers as the same as the C and C++ compilers respectively.

[https://en.wikipedia.org/wiki/Fortran Fortran] is partially supported in the base.
* {{{configure.fc}}}, {{{configure.f90}}}, and {{{configure.f77}}} are set.
* The environmental variables {{{FC}}}, {{{F90}}}, and {{{F77}}} are set during the configure phase if {{{use_configure}}} is {{{yes}}}.
* If MacPorts provides the compiler, the appropriate dependencies are added.
Xcode does not provide any Fortran compilers.
Clang does not provide a Fortran compiler (although [https://github.com/flang-compiler/flang Flang] might one day be viable).
A Fortran compiler is available only if one is requested or is provided by a previously requested compiler.
1. A Fortran compiler is requested if {{{compiler.require_fortran}}} is set to {{{yes}}}.
1. A Fortran compiler is provided if GCC is being used as a compiler (since GCC provides [https://en.wikipedia.org/wiki/GNU_Fortran GFortran] anyway).

The Fortran compiler is chosen with the following precedence:
1. If a Fortran compiler is already available (e.g. from GCC), then use it.
1. If the Portfile sets {{{compiler.fortran_fallback}}}, the Fortran compiler is chosen from that list unless the compiler is blacklisted. 
1. A Fortran compiler is chosen that
 * is not blacklisted,
 * is known to work on the particular version of the OS, and
 * satisfies the requirements set in the Portfile.

== Compiler Consideration: Runtime Libraries ==
When a GCC compiler is used, the resulting binary links against [https://wiki.osdev.org/Libgcc libgcc], a low-level runtime library.
While there can be multiple versions of these runtimes in a single process, it is not possible to pass objects between different versions.
So while MacPorts allows multiple versions of GCC to be installed at once, they must all use the same libgcc.
This means that an upgrade of libgcc sometimes requires ports compiled with GCC to be rebuilt.

Passing objects between C++ standard libraries can cause crashes that are difficult to debug.
The current trend is to [https://trac.macports.org/wiki/LibcxxOnOlderSystems use libc++ on all systems] except on older [https://en.wikipedia.org/wiki/Apple%27s_transition_to_Intel_processors PowerPC] systems.
Some notes on the C++ Standard Libraries:
1. libc++
 * Installed by the system on Mac OS X Lion and later.
 * Is the **default** C++ standard library on [https://en.wikipedia.org/wiki/OS_X_Mavericks OS X Mavericks] and later.
1. libstdc++ in /usr/lib/
 * Does not support C++11.
 * Is now deprecated.
 * Was the default C++ standard library prior to OS X Mavericks.
1. libstdc++ provided by MacPorts
 * Is ABI incompatible with libstdc++ in /usr/lib/ unless the macro [https://gcc.gnu.org/onlinedocs/gcc-5.2.0/libstdc++/manual/manual/using_dual_abi.html _GLIBCXX_USE_CXX11_ABI] is defined.

-------8<------8<------8<------8<------8<------8<------8<------8<--------

--
Page URL: <https://trac.macports.org/wiki/CompilerSelection>
MacPorts <https://www.macports.org/>
Ports system for macOS

This is an automated message. Someone added your email address to be
notified of changes on 'CompilerSelection' page.
If it was not you, please report to admin at macports.org.


More information about the macports-changes mailing list