|
| 1 | +# Patch files |
| 2 | + |
| 3 | +## What are patch files (patches)? |
| 4 | + |
| 5 | +A patch file, or just *patch* for short, is a text file that can be used to modify an existing software sources. |
| 6 | +They are often used to fix bugs, but can also be used to improve the usability or performance. |
| 7 | + |
| 8 | +## Including patches in an easyconfig file |
| 9 | + |
| 10 | +Patches can be provided via the `patches` easyconfig parameter (list). A |
| 11 | +patch can be defined as: |
| 12 | + |
| 13 | +- a `string`, |
| 14 | +- a `tuple` of 2 elements, or |
| 15 | +- a `dict` |
| 16 | + |
| 17 | +The most straight-forward use-case is `string`, which contains the name |
| 18 | +of the patch file (and must have `.patch` extension). |
| 19 | + |
| 20 | +A `tuple` adds the possibility to specify the subdirectory in which the patch should be applied. |
| 21 | +This is mostly needed if a patch file adds new files or it is generally |
| 22 | +not possible to determine the appropriate directory to apply the patch in. |
| 23 | +The first element of this tuple is |
| 24 | +the name of patch file. The second element is either the *patch level* (as an integer value) |
| 25 | +which is used in the patch command (`patch -p<level>`), or a directory relative to the unpacked source directory. |
| 26 | + |
| 27 | +!!! note |
| 28 | + `tuple` also has a special use case if the patch file has any other extension than `.patch`. |
| 29 | + In this case, the first tuple element is the name of a file which should be |
| 30 | + copied to the unpacked source directory, and the second element is |
| 31 | + the target path, where the files should be copied to (relative to |
| 32 | + the unpacked source directory). See below for an example of this use case. |
| 33 | + |
| 34 | +A `dict` value can be used pass additional arguments to the `patch` command. |
| 35 | +For example, the `--binary` flag may be needed for patch files |
| 36 | +with CRLF endings. For a `dict` value the `filename` key is required. |
| 37 | +`level` and `opts` are supported (optional) keys. |
| 38 | + |
| 39 | +!!! note |
| 40 | + Specifying only `filename` in `dict` is the same as using a plain `string` definition. |
| 41 | + Specifying `filename` and `level` is same as using a `tuple` |
| 42 | + definition. |
| 43 | + |
| 44 | +Example: |
| 45 | + |
| 46 | +```python |
| 47 | +patches = [ |
| 48 | + # a simple patch file |
| 49 | + 'example.patch', |
| 50 | + |
| 51 | + # when creating only new files by patch file, you need to specify the level: |
| 52 | + ('example-add-files.patch', 1), |
| 53 | + |
| 54 | + # apply the patch in a (sub-)subdirectory inside the source tree |
| 55 | + ('example-subfolder.patch', 'src/subfolder'), |
| 56 | + |
| 57 | + # copy file to target_path folder |
| 58 | + ('Makefile', 'path/to/target/'), |
| 59 | + |
| 60 | + # specify patch file and optionally level and opts for patch command |
| 61 | + {'filename': 'example.patch', 'level': 1, 'opts': '--binary'} |
| 62 | +] |
| 63 | +``` |
| 64 | + |
| 65 | +## Creating a patch file |
| 66 | + |
| 67 | +To create a patch file to use with EasyBuild, follow the steps below. |
| 68 | + |
| 69 | +### 1) Copy unpacked sources |
| 70 | + |
| 71 | +Start by copying the unpacked sources, before making any changes, so we can determine which changes were made: |
| 72 | + |
| 73 | +```bash |
| 74 | +cp -a unpacked_sources unpacked_sources.orig |
| 75 | + |
| 76 | +``` |
| 77 | + |
| 78 | +### 2) Make necessary changes |
| 79 | + |
| 80 | +Make the necessary changes in the `unpacked_sources` directory. |
| 81 | + |
| 82 | +### 3) Create patch file |
| 83 | + |
| 84 | +Create the patch file by comparing the original sources with the modified sources using the `diff` command: |
| 85 | + |
| 86 | +```bash |
| 87 | +diff -ruN unpacked_sources.orig unpacked_sources > example.patch |
| 88 | +``` |
| 89 | + |
| 90 | +The `-ruN` options here are important: |
| 91 | + |
| 92 | +- `r` instructs the `diff` command to look for changes between the specified directories *recursively*; |
| 93 | +- `u` indicates that `diff` should produce a *unified* diff as output; |
| 94 | +- `N` indicates that files only found in one directory should be treated as new files; |
| 95 | + |
| 96 | +### 4) Add description, author, reference |
| 97 | + |
| 98 | +Please also add a description on top of the patch file, along with the author and/or reference to the source of the patch. |
| 99 | + |
| 100 | +For example: |
| 101 | + |
| 102 | +```diff |
| 103 | +example of a patch description |
| 104 | +author: John Doe (Earth University) |
| 105 | +diff -ru unpacked_sources.orig/example.c unpacked_sources/example.c |
| 106 | +--- unpacked_sources.orig/example.c 2011-08-05 05:08:07.000000000 +0200 |
| 107 | ++++ unpacked_sources/example.c 2024-03-14 12:31:16.218067000 +0100 |
| 108 | +... |
| 109 | +``` |
0 commit comments