diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2017-09-27 20:03:30 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2017-09-30 02:06:59 -0700 |
commit | 96d2488e0cf04d65448a9a9fb3c7e3198e5dc6ff (patch) | |
tree | c88c361a515d9ee160331f5c27aa523bf824661c /lib/spack/docs/packaging_guide.rst | |
parent | 4f8c7d57eb3839ea866a9fbfb55f9a44af99d6c0 (diff) | |
download | spack-96d2488e0cf04d65448a9a9fb3c7e3198e5dc6ff.tar.gz spack-96d2488e0cf04d65448a9a9fb3c7e3198e5dc6ff.tar.bz2 spack-96d2488e0cf04d65448a9a9fb3c7e3198e5dc6ff.tar.xz spack-96d2488e0cf04d65448a9a9fb3c7e3198e5dc6ff.zip |
Documentation for dependency patching.
Diffstat (limited to 'lib/spack/docs/packaging_guide.rst')
-rw-r--r-- | lib/spack/docs/packaging_guide.rst | 152 |
1 files changed, 136 insertions, 16 deletions
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst index 402de6d8ed..57eafde2dc 100644 --- a/lib/spack/docs/packaging_guide.rst +++ b/lib/spack/docs/packaging_guide.rst @@ -1212,27 +1212,47 @@ structure like this: package.py ad_lustre_rwcontig_open_source.patch -If you supply a URL instead of a filename, you need to supply a checksum, -like this: +If you supply a URL instead of a filename, you need to supply a +``sha256`` checksum, like this: .. code-block:: python - patch('http://www.nwchem-sw.org/images/Tddft_mxvec20.patch.gz', - md5='f91c6a04df56e228fe946291d2f38c9a') + patch('http://www.nwchem-sw.org/images/Tddft_mxvec20.patch', + sha256='252c0af58be3d90e5dc5e0d16658434c9efa5d20a5df6c10bf72c2d77f780866') + +Spack includes the hashes of patches in its versioning information, so +that the same package with different patches applied will have different +hash identifiers. To ensure that the hashing scheme is consistent, you +must use a ``sha256`` checksum for the patch. Patches will be fetched +from their URLs, checked, and applied to your source code. You can use +the ``spack sha256`` command to generate a checksum for a patch file or +URL. -This directive provides an ``md5`` checksum. You can use other hashing -algorihtms like ``sha256`` as well. The patch will be fetched from the -URL, checked, and applied to your source code. You can use the ``spack -md5`` command to generate a checksum for a patch file. +Spack can also handle compressed patches. If you use these, Spack needs +a little more help. Specifically, it needs *two* checksums: the +``sha256`` of the patch and ``archive_sha256`` for the compressed +archive. ``archive_sha256`` helps Spack ensure that the downloaded +file is not corrupted or malicious, before running it through a tool like +``tar`` or ``zip``. The ``sha256`` of the patch is still required so +that it can be included in specs. Providing it in the package file +ensures that Spack won't have to download and decompress patches it won't +end up using at install time. Both the archive and patch checksum are +checked when patch archives are downloaded. -``patch`` can take two options keyword arguments. They are: +.. code-block:: python + + patch('http://www.nwchem-sw.org/images/Tddft_mxvec20.patch.gz', + sha256='252c0af58be3d90e5dc5e0d16658434c9efa5d20a5df6c10bf72c2d77f780866', + archive_sha256='4e8092a161ec6c3a1b5253176fcf33ce7ba23ee2ff27c75dbced589dabacd06e') -"""""""""""""""""""""""""""""""""""""" -``md5``, ``sha256``, ``sha512``, etc. -"""""""""""""""""""""""""""""""""""""" +``patch`` keyword arguments are described below. -Use one of these when you supply a patch to be downloaded from a remote -site. The downloaded file will be validated using the given checksum. +"""""""""""""""""""""""""""""" +``sha256``, ``archive_sha256`` +"""""""""""""""""""""""""""""" + +Hashes of downloaded patch and compressed archive, respectively. Only +needed for patches fetched from URLs. """""""" ``when`` @@ -1309,6 +1329,21 @@ if you run install, hit ctrl-C, and run install again, the code in the patch function is only run once. Also, you can tell Spack to run only the patching part of the build using the :ref:`cmd-spack-patch` command. +.. _patch_dependency_patching: + +^^^^^^^^^^^^^^^^^^^ +Dependency patching +^^^^^^^^^^^^^^^^^^^ + +So far we've covered how the ``patch`` directive can be used by a package +to patch *its own* source code. Packages can *also* specify patches to be +applied to their dependencies, if they require special modifications. As +with all packages in Spack, a patched dependency library can coexist with +other versions of that library. See the `section on depends_on +<dependency_dependency_patching_>`_ for more details. + +.. _handling_rpaths: + --------------- Handling RPATHs --------------- @@ -1482,7 +1517,7 @@ particular constraints, and package authors can use specs to describe relationships between packages. ^^^^^^^^^^^^^^ -Version Ranges +Version ranges ^^^^^^^^^^^^^^ Although some packages require a specific version for their dependencies, @@ -1530,7 +1565,7 @@ correct way to specify this would be: ^^^^^^^^^^^^^^^^ -Dependency Types +Dependency types ^^^^^^^^^^^^^^^^ Not all dependencies are created equal, and Spack allows you to specify @@ -1566,6 +1601,91 @@ inject the dependency's ``prefix/lib`` directory, but the package needs to be in ``PATH`` and ``PYTHONPATH`` during the build process and later when a user wants to run the package. +.. _dependency_dependency_patching: + +^^^^^^^^^^^^^^^^^^^ +Dependency patching +^^^^^^^^^^^^^^^^^^^ + +Some packages maintain special patches on their dependencies, either to +add new features or to fix bugs. This typically makes a package harder +to maintain, and we encourage developers to upstream (contribute back) +their changes rather than maintaining patches. However, in some cases +it's not possible to upstream. Maybe the dependency's developers don't +accept changes, or maybe they just haven't had time to integrate them. + +For times like these, Spack's ``depends_on`` directive can optionally +take a patch or list of patches: + +.. code-block:: python + + class SpecialTool(Package): + ... + depends_on('binutils', patches='special-binutils-feature.patch') + ... + +Here, the ``special-tool`` package requires a special feature in +``binutils``, so it provides an extra ``patches=<filename>`` keyword +argument. This is similar to the `patch directive <patching_>`_, with +one small difference. Here, ``special-tool`` is responsible for the +patch, so it should live in ``special-tool``'s directory in the package +repository, not the ``binutils`` directory. + +If you need something more sophisticated than this, you can simply nest a +``patch()`` directive inside of ``depends_on``: + +.. code-block:: python + + class SpecialTool(Package): + ... + depends_on( + 'binutils', + patches=patch('special-binutils-feature.patch', + level=3, + when='@:1.3'), # condition on binutils + when='@2.0:') # condition on special-tool + ... + +Note that there are two optional ``when`` conditions here -- one on the +``patch`` directive and the other on ``depends_on``. The condition in +the ``patch`` directive applies to ``binutils`` (the package being +patched), while the condition in ``depends_on`` applies to +``special-tool``. See `patch directive <patching_>`_ for details on all +the arguments the ``patch`` directive can take. + +Finally, if you need *multiple* patches on a dependency, you can provide +a list for ``patches``, e.g.: + +.. code-block:: python + + class SpecialTool(Package): + ... + depends_on( + 'binutils', + patches=[ + 'binutils-bugfix1.patch', + 'binutils-bugfix2.patch', + patch('https://example.com/special-binutils-feature.patch', + sha256='252c0af58be3d90e5dc5e0d16658434c9efa5d20a5df6c10bf72c2d77f780866', + when='@:1.3')], + when='@2.0:') + ... + +As with ``patch`` directives, patches are applied in the order they +appear in the package file (or in this case, in the list). + +.. note:: + + You may wonder whether dependency patching will interfere with other + packages that depend on ``binutils``. It won't. + + As described in patching_, Patching a package adds the ``sha256`` of + the patch to the package's spec, which means it will have a + *different* unique hash than other versions without the patch. The + patched version coexists with unpatched versions, and Spack's support + for handling_rpaths_ guarantees that each installation finds the + right version. If two packages depend on ``binutils`` patched *the + same* way, they can both use a single installation of ``binutils``. .. _setup-dependent-environment: |