Frequently Asked Questions¶
This page contains answers to frequently asked questions about Spack. If you have questions that are not answered here, feel free to ask on Slack or GitHub Discussions. If you’ve learned the answer to a question that you think should be here, please consider contributing to this page.
Why does Spack pick particular versions and variants?¶
This question comes up in a variety of forms:
Why does Spack seem to ignore my package preferences from
packages.yamlconfiguration?Why does Spack toggle a variant instead of using the default from the
package.pyfile?
The short answer is that Spack always picks an optimal configuration based on a complex set of criteria[1]. These criteria are more nuanced than always choosing the latest versions or default variants.
Note
As a rule of thumb: requirements + constraints > strong preferences > reuse > preferences > defaults.
The following set of criteria (from lowest to highest precedence) explains common cases where concretization output may seem surprising at first.
Package preferences configured in
packages.yamloverride variant defaults frompackage.pyfiles, and influence the optimal ordering of versions. Preferences are specified as follows:packages: foo: version: [1.0, 1.1] variants: ~mpi
Reuse concretization configured in
concretizer.yamloverrides preferences, since it’s typically faster to reuse an existing spec than to build a preferred one from sources. When build caches are enabled, specs may be reused from a remote location too. Reuse concretization is configured as follows:concretizer: reuse: dependencies # other options are 'true' and 'false'
Strong preferences configured in
packages.yamlare higher priority than reuse, and can be used to strongly prefer a specific version or variant, without erroring out if it’s not possible. Strong preferences are specified as follows:packages: foo: prefer: - "@1.1: ~mpi"
Package requirements configured in
packages.yaml, and constraints from the command line as well aspackage.pyfiles override all of the above. Requirements are specified as follows:packages: foo: require: - "@1.2: +mpi" conflict: - "@1.4"
Requirements and constraints restrict the set of possible solutions, while reuse behavior and preferences influence what an optimal solution looks like.
How do I use a specific compiler?¶
When you have multiple compilers available in spack compiler list, and want to build your packages with a specific one, you have the following options:
Specify your compiler preferences globally for all packages in configuration files.
Specify them on the level of individual specs, like
pkg %gcc@15orpkg %c,cxx=gcc@15.
We’ll explore both options in more detail.
Specific compiler for all packages¶
If you want to use a specific compiler for all packages, it’s best to use strong preferences in packages.yaml config.
The following example prefers GCC 15 for all languages c, cxx, and fortran:
packages:
c:
prefer:
- gcc@15
cxx:
prefer:
- gcc@15
fortran:
prefer:
- gcc@15
You can also replace prefer: with require: if you want Spack to produce an error if the preferred compiler cannot be used.
See also the previous FAQ entry.
In Spack, the languages c, cxx and fortran are virtual packages, on which packages depend if they need a compiler for that language.
Compiler packages provide these language virtuals.
When you specify these strong preferences, Spack determines whether the package depends on any of the language virtuals, and if so, it applies the associated compiler spec when possible.
What is not recommended is to define %gcc as a required dependency of all packages:
packages:
all:
require:
- "%gcc@15"
This is incorrect, because some packages do not need a compiler at all (e.g. pure Python packages).
Specific compiler for individual specs¶
If different parts of your software stack need to be built with different compilers, it’s best to specify compilers as dependencies of the relevant specs (whether on the command line or in Spack environments).
$ spack install foo %gcc@15 ^bar %intel-oneapi-compilers
What this means is that foo will depend on GCC 15, while bar will depend on intel-oneapi-compilers.
You can also be more specific about what compiler to use for a particular language:
$ spack install foo %c,cxx=gcc@15 %fortran=intel-oneapi-compilers
These input specs can be simplified using Toolchains (toolchains.yaml). See also Pitfalls without toolchains for common mistakes to avoid.
How do I debug unexpected or failing concretization?¶
spack install and spack concretize may fail with a concretization error when the solver cannot find a package configuration that satisfies all constraints.
Most of the time, the error message is structured and contains information about which requirements could not be met.
It typically identifies the conflicting constraints and the files where they are defined (e.g., a packages.yaml entry or a conflicts() directive in a package.py).
If the cause is clear from the error, you can fix the offending entry directly.
If it is not obvious why the solver made a particular decision – for example, why it chose a specific version or variant – run spack solve to see the full optimization breakdown:
$ spack solve <spec>
The output shows the optimization criteria and the weights assigned to each choice. This makes it possible to trace which preference or requirement is driving an unexpected result. See also Why does Spack pick particular versions and variants? for an overview of how criteria are prioritized.
For a deeper investigation of solver internals, see Debugging concretization in the developer guide.
Footnotes