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_&lt;suffix&gt;</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>