summaryrefslogtreecommitdiff
path: root/lib/spack/docs/configuration.rst
blob: a4b60e43e32f387cfaca81ac0dbc4a5bd392e7d3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
.. Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
   Spack Project Developers. See the top-level COPYRIGHT file for details.

   SPDX-License-Identifier: (Apache-2.0 OR MIT)

.. _configuration:

===================
Configuration Files
===================

Spack has many configuration files.  Here is a quick list of them, in
case you want to skip directly to specific docs:

* :ref:`compilers.yaml <compiler-config>`
* :ref:`concretizer.yaml <concretizer-options>`
* :ref:`config.yaml <config-yaml>`
* :ref:`mirrors.yaml <mirrors>`
* :ref:`modules.yaml <modules>`
* :ref:`packages.yaml <packages-config>`
* :ref:`repos.yaml <repositories>`

You can also add any of these as inline configuration in the YAML
manifest file (``spack.yaml``) describing an :ref:`environment
<environment-configuration>`.

-----------
YAML Format
-----------

Spack configuration files are written in YAML.  We chose YAML because
it's human readable, but also versatile in that it supports dictionaries,
lists, and nested sections. For more details on the format, see `yaml.org
<http://yaml.org>`_ and `libyaml <http://pyyaml.org/wiki/LibYAML>`_.
Here is an example ``config.yaml`` file:

.. code-block:: yaml

   config:
     install_tree: $spack/opt/spack
     build_stage:
       - $tempdir/$user/spack-stage
       - ~/.spack/stage

Each Spack configuration file is nested under a top-level section
corresponding to its name. So, ``config.yaml`` starts with ``config:``,
``mirrors.yaml`` starts with ``mirrors:``, etc.

.. _configuration-scopes:

--------------------
Configuration Scopes
--------------------

Spack pulls configuration data from files in several directories. There
are six configuration scopes. From lowest to highest:

#. **defaults**: Stored in ``$(prefix)/etc/spack/defaults/``. These are
   the "factory" settings. Users should generally not modify the settings
   here, but should override them in other configuration scopes. The
   defaults here will change from version to version of Spack.

#. **system**: Stored in ``/etc/spack/``. These are settings for this
   machine, or for all machines on which this file system is
   mounted. The site scope can be used for settings idiosyncratic to a
   particular machine, such as the locations of compilers or external
   packages. These settings are presumably controlled by someone with
   root access on the machine. They override the defaults scope.

#. **site**: Stored in ``$(prefix)/etc/spack/``. Settings here affect
   only *this instance* of Spack, and they override the defaults and system
   scopes.  The site scope can can be used for per-project settings (one
   Spack instance per project) or for site-wide settings on a multi-user
   machine (e.g., for a common Spack instance).

#. **user**: Stored in the home directory: ``~/.spack/``. These settings
   affect all instances of Spack and take higher precedence than site,
   system, or defaults scopes.

#. **custom**: Stored in a custom directory specified by ``--config-scope``.
   If multiple scopes are listed on the command line, they are ordered
   from lowest to highest precedence.

#. **environment**: When using Spack :ref:`environments`, Spack reads
   additional configuration from the environment file. See
   :ref:`environment-configuration` for further details on these
   scopes. Environment scopes can be referenced from the command line
   as ``env:name`` (to reference environment ``foo``, use
   ``env:foo``).

#. **command line**: Build settings specified on the command line take
   precedence over all other scopes.

Each configuration directory may contain several configuration files,
such as ``config.yaml``, ``compilers.yaml``, or ``mirrors.yaml``.  When
configurations conflict, settings from higher-precedence scopes override
lower-precedence settings.

Commands that modify scopes (e.g., ``spack compilers``, ``spack repo``,
etc.) take a ``--scope=<name>`` parameter that you can use to control
which scope is modified.  By default, they modify the highest-precedence
scope.

.. _custom-scopes:

^^^^^^^^^^^^^
Custom scopes
^^^^^^^^^^^^^

In addition to the ``defaults``, ``system``, ``site``, and ``user``
scopes, you may add configuration scopes directly on the command
line with the ``--config-scope`` argument, or ``-C`` for short.

For example, the following adds two configuration scopes, named
``scopea`` and ``scopeb``, to a ``spack spec`` command:

.. code-block:: console

   $ spack -C ~/myscopes/scopea -C ~/myscopes/scopeb spec ncurses

Custom scopes come *after* the ``spack`` command and *before* the
subcommand, and they specify a single path to a directory full of
configuration files. You can add the same configuration files to that
directory that you can add to any other scope (``config.yaml``,
``packages.yaml``, etc.).

If multiple scopes are provided:

#. Each must be preceded with the ``--config-scope`` or ``-C`` flag.
#. They must be ordered from lowest to highest precedence.

"""""""""""""""""""""""""""""""""""""""""""
Example: scopes for release and development
"""""""""""""""""""""""""""""""""""""""""""

Suppose that you need to support simultaneous building of release and
development versions of ``mypackage``, where ``mypackage`` -> ``A`` -> ``B``.
You could create The following files:

.. code-block:: yaml
   :caption: ~/myscopes/release/packages.yaml

   packages:
       mypackage:
           version: [1.7]
       A:
           version: [2.3]
       B:
           version: [0.8]

.. code-block:: yaml
   :caption: ~/myscopes/develop/packages.yaml

   packages:
       mypackage:
           version: [develop]
       A:
           version: [develop]
       B:
           version: [develop]

You can switch between ``release`` and ``develop`` configurations using
configuration arguments.  You would type ``spack -C ~/myscopes/release``
when you want to build the designated release versions of ``mypackage``,
``A``, and ``B``, and you would type ``spack -C ~/myscopes/develop`` when
you want to build all of these packages at the ``develop`` version.

"""""""""""""""""""""""""""""""
Example: swapping MPI providers
"""""""""""""""""""""""""""""""

Suppose that you need to build two software packages, ``packagea`` and
``packageb``. ``packagea`` is Python 2-based and ``packageb`` is Python
3-based. ``packagea`` only builds with OpenMPI and ``packageb`` only builds
with MPICH. You can create different configuration scopes for use with
``packagea`` and ``packageb``:

.. code-block:: yaml
   :caption: ~/myscopes/packgea/packages.yaml

   packages:
       python:
           version: [2.7.11]
       all:
           providers:
               mpi: [openmpi]

.. code-block:: yaml
   :caption: ~/myscopes/packageb/packages.yaml

   packages:
       python:
           version: [3.5.2]
       all:
           providers:
               mpi: [mpich]


.. _platform-scopes:

------------------------
Platform-specific Scopes
------------------------

For each scope above (excluding environment scopes), there can also be
platform-specific settings.  For example, on most platforms, GCC is
the preferred compiler.  However, on macOS (darwin), Clang often works
for more packages, and is set as the default compiler. This
configuration is set in
``$(prefix)/etc/spack/defaults/darwin/packages.yaml``. It will take
precedence over settings in the ``defaults`` scope, but can still be
overridden by settings in ``system``, ``system/darwin``, ``site``,
``site/darwin``, ``user``, ``user/darwin``, ``custom``, or
``custom/darwin``. So, the full scope precedence is:

#. ``defaults``
#. ``defaults/<platform>``
#. ``system``
#. ``system/<platform>``
#. ``site``
#. ``site/<platform>``
#. ``user``
#. ``user/<platform>``
#. ``custom``
#. ``custom/<platform>``

You can get the name to use for ``<platform>`` by running ``spack arch
--platform``. The system config scope has a ``<platform>`` section for
sites at which ``/etc`` is mounted on multiple heterogeneous machines.


.. _config-scope-precedence:

----------------
Scope Precedence
----------------

When spack queries for configuration parameters, it searches in
higher-precedence scopes first. So, settings in a higher-precedence file
can override those with the same key in a lower-precedence one. For
list-valued settings, Spack *prepends* higher-precedence settings to
lower-precedence settings. Completely ignoring higher-level configuration
options is supported with the ``::`` notation for keys (see
:ref:`config-overrides` below).

There are also special notations for string concatenation and precendense override:

* ``+:`` will force *prepending* strings or lists. For lists, this is the default behavior.
* ``-:`` works similarly, but for *appending* values.

:ref:`config-prepend-append`

^^^^^^^^^^^
Simple keys
^^^^^^^^^^^

Let's look at an example of overriding a single key in a Spack file. If
your configurations look like this:

.. code-block:: yaml
   :caption: $(prefix)/etc/spack/defaults/config.yaml

   config:
     install_tree: $spack/opt/spack
     build_stage:
       - $tempdir/$user/spack-stage
       - ~/.spack/stage


.. code-block:: yaml
   :caption: ~/.spack/config.yaml

   config:
     install_tree: /some/other/directory


Spack will only override ``install_tree`` in the ``config`` section, and
will take the site preferences for other settings. You can see the
final, combined configuration with the ``spack config get <configtype>``
command:

.. code-block:: console
   :emphasize-lines: 3

   $ spack config get config
   config:
     install_tree: /some/other/directory
     build_stage:
       - $tempdir/$user/spack-stage
       - ~/.spack/stage


.. _config-prepend-append:

^^^^^^^^^^^^^^^^^^^^
String Concatenation
^^^^^^^^^^^^^^^^^^^^

Above, the user ``config.yaml`` *completely* overrides specific settings in the
default ``config.yaml``. Sometimes, it is useful to add a suffix/prefix
to a path or name. To do this, you can use the ``-:`` notation for *append*
string concatenation at the end of a key in a configuration file. For example:

.. code-block:: yaml
   :emphasize-lines: 1
   :caption: ~/.spack/config.yaml

   config:
     install_tree-: /my/custom/suffix/

Spack will then append to the lower-precedence configuration under the
``install_tree-:`` section:

.. code-block:: console

   $ spack config get config
   config:
     install_tree: /some/other/directory/my/custom/suffix
     build_stage:
       - $tempdir/$user/spack-stage
       - ~/.spack/stage


Similarly, ``+:`` can be used to *prepend* to a path or name:

.. code-block:: yaml
   :emphasize-lines: 1
   :caption: ~/.spack/config.yaml

   config:
     install_tree+: /my/custom/suffix/


.. _config-overrides:

^^^^^^^^^^^^^^^^^^^^^^^^^^
Overriding entire sections
^^^^^^^^^^^^^^^^^^^^^^^^^^

Above, the user ``config.yaml`` only overrides specific settings in the
default ``config.yaml``. Sometimes, it is useful to *completely*
override lower-precedence settings. To do this, you can use *two* colons
at the end of a key in a configuration file. For example:

.. code-block:: yaml
   :emphasize-lines: 1
   :caption: ~/.spack/config.yaml

   config::
     install_tree: /some/other/directory

Spack will ignore all lower-precedence configuration under the
``config::`` section:

.. code-block:: console

   $ spack config get config
   config:
     install_tree: /some/other/directory


^^^^^^^^^^^^^^^^^^^^
List-valued settings
^^^^^^^^^^^^^^^^^^^^

Let's revisit the ``config.yaml`` example one more time. The
``build_stage`` setting's value is an ordered list of directories:

.. code-block:: yaml
   :caption: $(prefix)/etc/spack/defaults/config.yaml

   build_stage:
     - $tempdir/$user/spack-stage
     - ~/.spack/stage


Suppose the user configuration adds its *own* list of ``build_stage``
paths:

.. code-block:: yaml
   :caption: ~/.spack/config.yaml

   build_stage:
     - /lustre-scratch/$user/spack
     - ~/mystage


Spack will first look at the paths in the defaults ``config.yaml``, then the
paths in the user's ``~/.spack/config.yaml``. The list in the
higher-precedence scope is *prepended* to the defaults. ``spack config
get config`` shows the result:

.. code-block:: console
   :emphasize-lines: 5-8

   $ spack config get config
   config:
     install_tree: /some/other/directory
     build_stage:
       - /lustre-scratch/$user/spack
       - ~/mystage
       - $tempdir/$user/spack-stage
       - ~/.spack/stage


As in :ref:`config-overrides`, the higher-precedence scope can
*completely* override the lower-precedence scope using ``::``. So if the
user config looked like this:

.. code-block:: yaml
   :emphasize-lines: 1
   :caption: ~/.spack/config.yaml

   build_stage::
     - /lustre-scratch/$user/spack
     - ~/mystage


The merged configuration would look like this:

.. code-block:: console
   :emphasize-lines: 5-6

   $ spack config get config
   config:
     install_tree: /some/other/directory
     build_stage:
       - /lustre-scratch/$user/spack
       - ~/mystage


.. _config-file-variables:

---------------------
Config File Variables
---------------------

Spack understands several variables which can be used in config file
paths wherever they appear. There are three sets of these variables:
Spack-specific variables, environment variables, and user path
variables. Spack-specific variables and environment variables are both
indicated by prefixing the variable name with ``$``. User path variables
are indicated at the start of the path with ``~`` or ``~user``.

^^^^^^^^^^^^^^^^^^^^^^^^
Spack-specific variables
^^^^^^^^^^^^^^^^^^^^^^^^

Spack understands over a dozen special variables. These are:

* ``$env``: name of the currently active :ref:`environment <environments>`
* ``$spack``: path to the prefix of this Spack installation
* ``$tempdir``: default system temporary directory (as specified in
  Python's `tempfile.tempdir
  <https://docs.python.org/2/library/tempfile.html#tempfile.tempdir>`_
  variable.
* ``$user``: name of the current user
* ``$user_cache_path``: user cache directory (``~/.spack`` unless
  :ref:`overridden <local-config-overrides>`)
* ``$architecture``: the architecture triple of the current host, as
  detected by Spack.
* ``$arch``: alias for ``$architecture``.
* ``$platform``: the platform of the current host, as detected by Spack.
* ``$operating_system``: the operating system of the current host, as
  detected by the ``distro`` python module.
* ``$os``: alias for ``$operating_system``.
* ``$target``: the ISA target for the current host, as detected by
  ArchSpec. E.g. ``skylake`` or ``neoverse-n1``.
* ``$target_family``. The target family for the current host, as
  detected by ArchSpec. E.g. ``x86_64`` or ``aarch64``.
* ``$date``: the current date in the format YYYY-MM-DD


Note that, as with shell variables, you can write these as ``$varname``
or with braces to distinguish the variable from surrounding characters:
``${varname}``. Their names are also case insensitive, meaning that
``$SPACK`` works just as well as ``$spack``. These special variables are
substituted first, so any environment variables with the same name will
not be used.

^^^^^^^^^^^^^^^^^^^^^
Environment variables
^^^^^^^^^^^^^^^^^^^^^

After Spack-specific variables are evaluated, environment variables are
expanded. These are formatted like Spack-specific variables, e.g.,
``${varname}``. You can use this to insert environment variables in your
Spack configuration.

^^^^^^^^^^^^^^^^^^^^^
User home directories
^^^^^^^^^^^^^^^^^^^^^

Spack performs Unix-style tilde expansion on paths in configuration
files. This means that tilde (``~``) will expand to the current user's
home directory, and ``~user`` will expand to a specified user's home
directory. The ``~`` must appear at the beginning of the path, or Spack
will not expand it.

.. _configuration_environment_variables:

-------------------------
Environment Modifications
-------------------------

Spack allows to prescribe custom environment modifications in a few places
within its configuration files. Every time these modifications are allowed
they are specified as a dictionary, like in the following example:

.. code-block:: yaml

   environment:
     set:
       LICENSE_FILE: '/path/to/license'
     unset:
     - CPATH
     - LIBRARY_PATH
     append_path:
       PATH: '/new/bin/dir'

The possible actions that are permitted are ``set``, ``unset``, ``append_path``,
``prepend_path`` and finally ``remove_path``. They all require a dictionary
of variable names mapped to the values used for the modification.
The only exception is ``unset`` that requires just a list of variable names.
No particular order is ensured on the execution of each of these modifications.

----------------------------
Seeing Spack's Configuration
----------------------------

With so many scopes overriding each other, it can sometimes be difficult
to understand what Spack's final configuration looks like.

Spack provides two useful ways to view the final "merged" version of any
configuration file: ``spack config get`` and ``spack config blame``.

.. _cmd-spack-config-get:

^^^^^^^^^^^^^^^^^^^^
``spack config get``
^^^^^^^^^^^^^^^^^^^^

``spack config get`` shows a fully merged configuration file, taking into
account all scopes. For example, to see the fully merged
``config.yaml``, you can type:

.. code-block:: console

   $ spack config get config
   config:
     debug: false
     checksum: true
     verify_ssl: true
     dirty: false
     build_jobs: 8
     install_tree: $spack/opt/spack
     template_dirs:
     - $spack/templates
     directory_layout: {architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}
     build_stage:
     - $tempdir/$user/spack-stage
     - ~/.spack/stage
     - $spack/var/spack/stage
     source_cache: $spack/var/spack/cache
     misc_cache: ~/.spack/cache
     locks: true

Likewise, this will show the fully merged ``packages.yaml``:

.. code-block:: console

   $ spack config get packages

You can use this in conjunction with the ``-C`` / ``--config-scope`` argument to
see how your scope will affect Spack's configuration:

.. code-block:: console

   $ spack -C /path/to/my/scope config get packages


.. _cmd-spack-config-blame:

^^^^^^^^^^^^^^^^^^^^^^
``spack config blame``
^^^^^^^^^^^^^^^^^^^^^^

``spack config blame`` functions much like ``spack config get``, but it
shows exactly which configuration file each preference came from. If you
do not know why Spack is behaving a certain way, this can help you track
down the problem:

.. code-block:: console

   $ spack --insecure -C ./my-scope -C ./my-scope-2 config blame config
   ==> Warning: You asked for --insecure. Will NOT check SSL certificates.
   ---                                                   config:
   _builtin                                                debug: False
   /home/myuser/spack/etc/spack/defaults/config.yaml:72    checksum: True
   command_line                                            verify_ssl: False
   ./my-scope-2/config.yaml:2                              dirty: False
   _builtin                                                build_jobs: 8
   ./my-scope/config.yaml:2                                install_tree: /path/to/some/tree
   /home/myuser/spack/etc/spack/defaults/config.yaml:23    template_dirs:
   /home/myuser/spack/etc/spack/defaults/config.yaml:24    - $spack/templates
   /home/myuser/spack/etc/spack/defaults/config.yaml:28    directory_layout: {architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}
   /home/myuser/spack/etc/spack/defaults/config.yaml:49    build_stage:
   /home/myuser/spack/etc/spack/defaults/config.yaml:50    - $tempdir/$user/spack-stage
   /home/myuser/spack/etc/spack/defaults/config.yaml:51    - ~/.spack/stage
   /home/myuser/spack/etc/spack/defaults/config.yaml:52    - $spack/var/spack/stage
   /home/myuser/spack/etc/spack/defaults/config.yaml:57    source_cache: $spack/var/spack/cache
   /home/myuser/spack/etc/spack/defaults/config.yaml:62    misc_cache: ~/.spack/cache
   /home/myuser/spack/etc/spack/defaults/config.yaml:86    locks: True

You can see above that the ``build_jobs`` and ``debug`` settings are
built in and are not overridden by a configuration file. The
``verify_ssl`` setting comes from the ``--insecure`` option on the
command line. ``dirty`` and ``install_tree`` come from the custom
scopes ``./my-scope`` and ``./my-scope-2``, and all other configuration
options come from the default configuration files that ship with Spack.

.. _local-config-overrides:

------------------------------
Overriding Local Configuration
------------------------------

Spack's ``system`` and ``user`` scopes provide ways for administrators and users to set
global defaults for all Spack instances, but for use cases where one wants a clean Spack
installation, these scopes can be undesirable. For example, users may want to opt out of
global system configuration, or they may want to ignore their own home directory
settings when running in a continuous integration environment.

Spack also, by default, keeps various caches and user data in ``~/.spack``, but
users may want to override these locations.

Spack provides three environment variables that allow you to override or opt out of
configuration locations:

* ``SPACK_USER_CONFIG_PATH``: Override the path to use for the
  ``user`` scope (``~/.spack`` by default).
* ``SPACK_SYSTEM_CONFIG_PATH``: Override the path to use for the
  ``system`` scope (``/etc/spack`` by default).
* ``SPACK_DISABLE_LOCAL_CONFIG``: set this environment variable to completely disable
  **both** the system and user configuration directories. Spack will only consider its
  own defaults and ``site`` configuration locations.

And one that allows you to move the default cache location:

* ``SPACK_USER_CACHE_PATH``: Override the default path to use for user data
  (misc_cache, tests, reports, etc.)

With these settings, if you want to isolate Spack in a CI environment, you can do this::

  export SPACK_DISABLE_LOCAL_CONFIG=true
  export SPACK_USER_CACHE_PATH=/tmp/spack