Configuring Compilers

Spack has the ability to build packages with multiple compilers and compiler versions. Compilers can be made available to Spack by:

  1. Specifying them as externals in packages.yaml, or

  2. Having them installed in the current Spack store, or

  3. Having them available as binaries in a build cache

For convenience, Spack will automatically detect compilers as externals the first time it needs them, if no compiler is available.

spack compiler list

You can see which compilers are available to Spack by running spack compiler list:

$ spack compiler list
==> Available compilers
-- gcc ubuntu20.04-x86_64 ---------------------------------------
[e]  gcc@10.5.0  [+]  gcc@15.1.0  [+]  gcc@14.3.0

Compilers marked with an [e] are system compilers (externals), and those marked with a [+] have been installed by Spack. Compilers from remote build caches are marked as -, but are not shown by default. To see them you need a specific option:

$ spack compiler list --remote
==> Available compilers
-- gcc ubuntu20.04-x86_64 ---------------------------------------
[e]  gcc@10.5.0  [+]  gcc@15.1.0  [+]  gcc@14.3.0

-- gcc ubuntu20.04-x86_64 ---------------------------------------
 -   gcc@12.4.0

Any of these compilers can be used to build Spack packages. More details on how this is done can be found in Spec Syntax.

spack compiler find

If you do not see a compiler in the list shown by:

$ spack compiler list

but you want to use it with Spack, you can simply run spack compiler find with the path to where the compiler is installed. For example:

$ spack compiler find /opt/intel/oneapi/compiler/2025.1/bin/
==> Added 1 new compiler to /home/user/.spack/packages.yaml
    intel-oneapi-compilers@2025.1.0
==> Compilers are defined in the following files:
    /home/user/.spack/packages.yaml

Or you can run spack compiler find with no arguments to force auto-detection. This is useful if you do not know where compilers are installed, but you know that new compilers have been added to your PATH. For example, you might load a module, like this:

$ module load gcc/4.9.0
$ spack compiler find
==> Added 1 new compiler to /home/user/.spack/packages.yaml
    gcc@4.9.0

This loads the environment module for gcc-4.9.0 to add it to PATH, and then it adds the compiler to Spack.

Note

By default, Spack does not fill in the modules: field in the packages.yaml file. If you are using a compiler from a module, then you should add this field manually. See the section on Compilers Requiring Modules.

spack compiler info

If you want to see additional information about specific compilers, you can run spack compiler info:

$ spack compiler info gcc
gcc@=8.4.0 languages='c,c++,fortran' arch=linux-ubuntu20.04-x86_64:
  prefix: /usr
  compilers:
    c: /usr/bin/gcc-8
    cxx: /usr/bin/g++-8
    fortran: /usr/bin/gfortran-8

gcc@=9.4.0 languages='c,c++,fortran' arch=linux-ubuntu20.04-x86_64:
  prefix: /usr
  compilers:
    c: /usr/bin/gcc
    cxx: /usr/bin/g++
    fortran: /usr/bin/gfortran

gcc@=10.5.0 languages='c,c++,fortran' arch=linux-ubuntu20.04-x86_64:
  prefix: /usr
  compilers:
    c: /usr/bin/gcc-10
    cxx: /usr/bin/g++-10
    fortran: /usr/bin/gfortran-10

This shows the details of the compilers that were detected by Spack. Notice also that we didn’t have to be too specific about the version. We just said gcc, and we got information about all the matching compilers.

Manual configuration of external compilers

If auto-detection fails, you can manually configure a compiler by editing your packages configuration. You can do this by running:

$ spack config edit packages

which will open the file in your favorite editor.

Each compiler has an “external” entry in the file with extra_attributes:

packages:
  gcc:
    externals:
    - spec: gcc@10.5.0 languages='c,c++,fortran'
      prefix: /usr
      extra_attributes:
        compilers:
          c: /usr/bin/gcc-10
          cxx: /usr/bin/g++-10
          fortran: /usr/bin/gfortran-10

The compiler executables are listed under extra_attributes:compilers, and are keyed by language. Once you save the file, the configured compilers will show up in the list displayed by spack compilers.

You can also add compiler flags to manually configured compilers. These flags should be specified in the flags section of the compiler specification. The valid flags are cflags, cxxflags, fflags, cppflags, ldflags, and ldlibs. For example:

packages:
  gcc:
    externals:
    - spec: gcc@10.5.0 languages='c,c++,fortran'
      prefix: /usr
      extra_attributes:
        compilers:
          c: /usr/bin/gcc-10
          cxx: /usr/bin/g++-10
          fortran: /usr/bin/gfortran-10
        flags:
          cflags: -O3 -fPIC
          cxxflags: -O3 -fPIC
          cppflags: -O3 -fPIC

These flags will be treated by Spack as if they were entered from the command line each time this compiler is used. The compiler wrappers then inject those flags into the compiler command. Compiler flags entered from the command line will be discussed in more detail in the following section.

Some compilers also require additional environment configuration. Examples include Intel’s oneAPI and AMD’s AOCC compiler suites, which have custom scripts for loading environment variables and setting paths. These variables should be specified in the environment section of the compiler specification. The operations available to modify the environment are set, unset, prepend_path, append_path, and remove_path. For example:

packages:
  intel-oneapi-compilers:
    externals:
    - spec: intel-oneapi-compilers@2025.1.0
      prefix: /opt/intel/oneapi
      extra_attributes:
        compilers:
          c: /opt/intel/oneapi/compiler/2025.1/bin/icx
          cxx: /opt/intel/oneapi/compiler/2025.1/bin/icpx
          fortran: /opt/intel/oneapi/compiler/2025.1/bin/ifx
        environment:
          set:
            MKL_ROOT: "/path/to/mkl/root"
          unset: # A list of environment variables to unset
          - CC
          prepend_path: # Similar for append|remove_path
            LD_LIBRARY_PATH: /ld/paths/added/by/setvars/sh

It is also possible to specify additional RPATHs that the compiler will add to all executables generated by that compiler. This is useful for forcing certain compilers to RPATH their own runtime libraries so that executables will run without the need to set LD_LIBRARY_PATH:

packages:
  gcc:
    externals:
    - spec: gcc@4.9.3
      prefix: /opt/gcc
      extra_attributes:
        compilers:
          c: /opt/gcc/bin/gcc
          cxx: /opt/gcc/bin/g++
          fortran: /opt/gcc/bin/gfortran
        extra_rpaths:
        - /path/to/some/compiler/runtime/directory
        - /path/to/some/other/compiler/runtime/directory

Compilers Requiring Modules

Many installed compilers will work regardless of the environment from which they are called. However, some installed compilers require environment variables to be set in order to run.

On typical HPC clusters, these environment modifications are usually delegated to some “module” system. In such a case, you should tell Spack which module(s) to load in order to run the chosen compiler:

packages:
  gcc:
    externals:
    - spec: gcc@10.5.0 languages='c,c++,fortran'
      prefix: /opt/compilers
      extra_attributes:
        compilers:
          c: /opt/compilers/bin/gcc-10
          cxx: /opt/compilers/bin/g++-10
          fortran: /opt/compilers/bin/gfortran-10
      modules: [gcc/10.5.0]

Some compilers require special environment settings to be loaded not just to run, but also to execute the code they build, breaking packages that need to execute code they just compiled. If it’s not possible or practical to use a better compiler, you’ll need to ensure that environment settings are preserved for compilers like this (i.e., you’ll need to load the module or source the compiler’s shell script).

By default, Spack tries to ensure that builds are reproducible by cleaning the environment before building. If this interferes with your compiler settings, you CAN use spack install --dirty as a workaround. Note that this MAY interfere with package builds.

Build Your Own Compiler

If you require a specific compiler and version, you can have Spack build it for you. For example:

$ spack install gcc@14

Once the compiler is installed, you can start using it without additional configuration:

$ spack install hdf5~mpi %gcc@14

Mixing Compilers

For more options on configuring Spack to mix different compilers for different languages, see the toolchains configuration docs.

To disable mixing (e.g. if you have multiple compilers defined, but want each concretized DAG to use one of them consistently), you can set:

concretizer:
  compiler_mixing: false

This affects root specs and any (transitive) link or run dependencies. Build-only dependencies are allowed to use different compilers (even when this is set).

Some packages are difficult to build with high performance compilers, and it may be necessary to enable compiler mixing just for those packages. To enable mixing for specific packages, specify an allow-list in the compiler_mixing config:

concretizer:
  compiler_mixing: ["openssl"]

Adding openssl to the compiler mixing allow-list does not allow mixing for dependencies of openssl.