github.com/sercand/please@v13.4.0+incompatible/docs/build_rules.html (about) 1 <h1>Writing build rules</h1> 2 3 <p>Please is designed to support interleaving custom build commands as first-class 4 citizens in the system. This describes some of the concepts to bear in mind when 5 writing rules of your own.</p> 6 7 <p>The documentation for <a href="lexicon.html#genrule">genrule</a> may be of use as well, 8 as that explains the available arguments and what they do.</p> 9 10 <h2>Build location</h2> 11 12 <p>A core concept of Please is to try to isolate compilation so we have a good concept of 13 correctness for each action. To this end each rule builds in its own temporary directory 14 (under <code>plz-out/tmp</code>) with a limited set of files in it.<br/> 15 If you want to have a look at what it looks like in there, <code>plz build --shell</code> 16 will prepare a target for building and open up a shell into the directory, where you can 17 look around and try running commands by hand.</p> 18 19 <p>Some aspects of this environment are different to normal - for example rules are given a 20 small, deterministic set of environment variables. They shouldn't need to read anything 21 outside this directory or not described by those variables.</p> 22 23 24 <h2>Sources</h2> 25 26 <p>Sources are the inputs to your rule - typically source code. This is defined in the 27 <code>srcs</code> argument.</p> 28 29 <p>All sources are linked into the build directory - for performance reasons they aren't copied 30 so you shouldn't modify them in-place.</p> 31 32 <p>Sources can be referred to through the <code>$SRCS</code> environment variable. If there's only 33 one, a <code>$SRC</code> variable will be defined too.<br/> 34 Sources can also be named, e.g. 35 <pre><code> 36 srcs = { 37 'srcs': ['my_source.py'], 38 'resources': ['something.txt'], 39 }, 40 </code></pre> 41 In that case they can be accessed separately through <code>$SRCS_SRCS</code> and 42 <code>$SRCS_RESOURCES</code>. 43 </p> 44 45 46 <h2>Dependencies</h2> 47 48 <p>Dependencies are other things you need to build - e.g. other code that your rule depends on.<br/> 49 These are also linked into the build directory, so the difference between sources and dependencies 50 can seem arbitrary, but for some internal functions it's an important distinction to know how 51 rules see the things they'll consume.</p> 52 53 <p>Dependencies don't have any corresponding environment variables associated with them.</p> 54 55 56 <h2>Tools</h2> 57 58 <p>Tools are the things that a rule uses to build with. They can refer either to other rules 59 within the repo, or system-level binaries, for example: 60 <pre><code> 61 tools = [ 62 'curl', 63 '//path/to:tool', 64 ], 65 </code></pre> 66 In this example, <code>curl</code> is resolved on the system using the <code>PATH</code> 67 variable defined in your <a href="config.html">.plzconfig file</a>. <code>//path/to:tool</code> 68 will be built first and used from its output location.</p> 69 70 <p>Tools are not copied into the build directory, you can access them using the <code>$TOOL</code> 71 or <code>$TOOLS</code> environment variables. They can also be named in a similar manner to sources.</p> 72 73 <p>Note that since tools aren't copied, they can be a source of nondeterminism if you make use of 74 other outputs that happen to be located near them. In order to ensure correctness you should 75 make sure that you only run the tool itself and don't access neighbouring outputs.</p> 76 77 78 <h2>Commands</h2> 79 80 <p>The command that you run is of course the core part of the rule. It can be passed to 81 <code>genrule</code> in three formats: 82 <ul> 83 <li>As a string; the simplest format, since there's only one command that's run.</li> 84 <li>As a list, it's a sequence of commands run one after another if the preceding ones are 85 successful (i.e. it's effectively shorthand for <code>' && '.join(cmd)</code></li> 86 <li>As a dict, the keys correspond to the build config to run and the values 87 are the command to run in that config. The typical use case here is <code>opt</code> vs. 88 <code>dbg</code> but arbitrary names can be given and specified with <code>plz build -c name</code>.</li> 89 </ul> 90 </p> 91 92 <p>There are various special sequence replacements that the rule is subject to: 93 <ul> 94 <li><code>$(location //path/to:target)</code> expands to the location of the given build rule, 95 which must have a single output only.</li> 96 <li><code>$(locations //path/to:target)</code> expands to the locations of the outputs of the 97 given build rule, which can have any number of outputs.</li> 98 <li><code>$(exe //path/to:target)</code> expands to a command to run the output of the given 99 target. The rule must be marked as binary.</li> 100 <li><code>$(out_location //path_to:target)</code> expands to the output of the given build rule, 101 with the preceding plz-out/gen etc.<br/> 102 Consider carefully when to use this though; it is not normally useful.</li> 103 <li><code>$(hash //path/to:target)</code> expands to a hash of the outputs of that target.<br/> 104 This can be useful to uniquely fingerprint the given rule.</li> 105 </ul> 106 </p> 107 108 <p>The following environment variables are also set: 109 <ul> 110 <li><code>ARCH</code>: architecture of the system, eg. amd64</li> 111 <li><code>OS</code>: current operating system (linux, darwin, etc).</li> 112 <li><code>PATH</code>: usual PATH environment variable as defined in your .plzconfig</li> 113 <li><code>TMP_DIR</code>: the temporary directory you're compiling within.</li> 114 <li><code>HOME</code>: also set to the temporary directory you're compiling within.</li> 115 <li><code>NAME</code>: the name of the rule. 116 <li><code>SRCS</code>: the sources of your rule</li> 117 <li><code>OUTS</code>: the outputs of your rule</li> 118 <li><code>PKG</code>: the path to the package containing this rule</li> 119 <li><code>PKG_DIR</code>: Similar to <code>PKG</code> but always contains a path (specifically <code>.</code> 120 if the rule is in the root of the repo).</li> 121 <li><code>NAME</code>: the name of this build rule</li> 122 <li><code>OUT</code>: the output of this rule. Only present when there is only one output.</li> 123 <li><code>SRC</code>: the source of this rule. Only present when there is only one source.</li> 124 <li><code>SRCS_<suffix></code>: Present when you've defined named sources on a rule. Each group 125 creates one of these these variables with paths to those sources.</li> 126 <li><code>TOOLS</code>: Any tools defined on the rule.</li> 127 <li><code>TOOL</code>: Available on any rule that defines a single tool only.</li> 128 <li><code>SECRETS</code>: If any secrets are defined on the rule, these are the paths to them.</li> 129 </ul> 130 </p> 131 132 133 <h2>Secrets</h2> 134 135 <p>Rules can define a list of secrets that they want access to. These are all absolute paths 136 (beginning with <code>/</code> or <code>~</code> and aren't copied to the build directory; 137 instead they can be located using the environment variable <code>$SECRETS</code>.<br/> 138 They're useful for things like signing or access keys that you don't want to check into 139 version control but still might be necessary for building some rules.</p> 140 141 <p>These don't contribute to the key used to retrieve outputs from the cache; this 142 means it's possible for one machine to build a target with the secret and then 143 share the output with others.</p>