blob: deac3b408bb1cccd44337e32ea73ea7c965a757d [file] [log] [blame]
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{namespace buck.build_rule}
/***/
{template .soyweb}
{call buck.page}
{param title: 'Build Rule' /}
{param navid: 'concept_build_rule' /}
{param description}
A procedure for producing output files from a set of input files
in the context of a specified build configuration.
{/param}
{param content}
<p>
A <em>build rule</em> is a procedure for producing output files from
a set of input files in the context of a specified build
configuration. Build rules are specified
in {call buck.build_file /}s&mdash;typically named BUCK.
</p>
<p>
<strong>Note:</strong> A build rule must explicitly specify, in its
arguments, all of its required inputs in order for Buck to be able to
build the rule's output in a way that is deterministic and reproducible.
</p>
<h2>Buck's collection of build rules</h2>
<p>
Buck comes with a collection of built-in build rules for many
common build procedures. For example, compiling Java
code against the Android SDK is a common procedure, so Buck provides the
build rule {sp}{call buck.android_library /} to do that. Similarly,
the final product of most Android development is an APK, so you can use the build
rule {sp}{call buck.android_binary /} to create an APK.
</p>
<p>
This documentation organizes Buck's build rules by development language
and by target platform. Examples
are: <strong>C++</strong>, <strong>Java</strong>, <strong>Python</strong> (development languages)
and <strong>Android</strong>, <strong>iOS</strong>, <strong>.NET</strong> (target platforms).
Consult the table of contents to locate the build rules that are
appropriate for your development project.
</p>
<p>
You can view a list of Buck's build rules from the command line with the
command:
</p>
<p>
<pre>
{literal}
buck audit ruletypes
{/literal}
</pre>
</p>
<p>
You can view the arguments supported by a particular rule with the
command:
</p>
<p>
<pre>
{literal}
buck audit ruletype &#x3C;rule>
{/literal}
</pre>
</p>
<p>
Note that the first of these commands uses the <em>plural</em> <code>ruletypes</code>, and
the second uses the <em>singular</em> <code>ruletype</code>. For more information,
see the {call buck.cmd_audit /} documentation.
</p>
<h2>Source files as inputs to build rules</h2>
<p>
Most build rules specify source files as inputs. For example,
a {call buck.cxx_library /} rule would specify <code>.cpp</code> files
as inputs. To support specifying these files, a <code>cxx_library</code> rule
provides the <code>srcs</code> argument. Some languages, such as C++, use
header files as well. To specify these, <code>cxx_library</code> provides
a <code>headers</code> argument.
</p>
<p>
In addition to <code>srcs</code> and <code>headers</code>,
some rules provide variants of these arguments, such
as <code>platform_srcs</code> and <code>platform_headers</code>. These
arguments support groups of source files that should be used as inputs only when
building for specific platforms.
For more information, see the descriptions for <code>platform_srcs</code> and
{sp}<code>platform_headers</code> in, for example, the {call buck.cxx_library /} topic.
</p>
<h3>Package boundaries and access to source files</h3>
<p>
In Buck, a BUCK file defines a <em>package</em>, which corresponds <em>roughly</em> to
the directory that contains the BUCK file and those subdirectories that do not themselves contain
BUCK files. (To learn more, see the {call buck.key_concepts_link}{param rendered_text: 'Key Concepts' /}{/call} topic.)
</p>
<p>
A rule in a BUCK file cannot specify a source file as an input unless
that source file is in that BUCK file's package. An exception to this
restriction exists for header files, but only if a rule in the package
that contains the header file <em>exports</em> that header file using
the <code>exported_headers</code> argument.
For more details, see the description for <code>exported_headers</code> in,
for example, the {call buck.cxx_library /} topic.
</p>
<p>
More commonly though, the package for a BUCK file contains all the
source files required for the rules defined in that BUCK file.
Functionality in source files from other packages is made available through
the artifacts produced by the rules in the BUCK files for those packages.
For example, a {call buck.cxx_binary /} might use the functionality
in a <code>cxx_library</code> that is defined in another
package. To access that functionality, the <code>cxx_binary</code> would
take that <code>cxx_library</code> as a <em>dependency</em>.
</p>
<h5>Symlinks: Use with caution if at all</h5>
<p>
We recommend that you do <em>not</em> use symlinks&mdash;either absolute or
relative&mdash;to specify input files to build rules. Although using
symlinks in this context does sometimes work, it can lead to unexpected
behavior and errors.
</p>
<h2>Dependencies: Output from one rule as input to another rule</h2>
<p>
A build rule can use the output from another build rule as one of its inputs by
specifying that rule as a <em>dependency</em>. Typically, a build rule
specifies its dependencies as a list of {call buck.build_target /}s
in its <code>deps</code> argument. However, the rule can also
specify dependencies&mdash;as build targets&mdash;in other arguments, such as <code>srcs</code>.
</p>
<p>
<strong>Example:</strong> The output of a {call buck.java_library /}{sp} rule
is a JAR file. If a <code>java_library</code>{sp} rule
specifies another <code>java_library</code> rule as a dependency, the
JAR file produced by the specified rule is added to the classpath for
the <code>java_library</code> that depends on it.
</p>
<p>
<strong>Example:</strong> If a {call buck.java_binary /}{sp} rule
specifies a <code>java_library</code> rule as a dependency, the JAR file
for the specified <code>java_library</code> is available on the classpath for
the <code>java_binary</code>. In addition, in the case of <code>java_binary</code>,
the JAR files for any dependencies of the <code>java_library</code> rule <em>are also</em> made
available to the <code>java_binary</code> rule&mdash;and if those
dependencies have dependencies of their own, they are added as well.
This exhaustive cascade of dependencies is referred to as the
rule's <em>transitive closure</em>.
</p>
<h3>Required dependencies are always built first</h3>
<p>
Buck guarantees that any dependencies that a rule lists that are required
in order to build that rule are built successfully <em>before</em> Buck
builds the rule itself. Note though that there can be special
cases&mdash;such as {call buck.apple_bundle /}&mdash;where
a rule's listed dependencies do not actually need to be built before
the rule.
</p>
<h3>Visibility</h3>
<p>
In order for a build rule to take a dependency on another build rule, the
build rule on which the dependency is taken must be <em>visible</em> to
the build rule taking the dependency. A build rule's <code>visibility</code> argument
is a list of {call buck.build_target_pattern /}s that specify the rules
that can take that rule as a dependency. For more information about the
concept of visibility in Buck, see
the {call buck.concept_link}{param page: 'Visibility' /}{param name: 'Visibility' /}{/call} topic.
</p>
<h3>Dependencies define a graph</h3>
<p>
Build rules and their dependencies define a directed acyclic graph
(DAG). Buck requires this graph to be acyclic to make it possible to
build independent subgraphs in parallel.
</p>
<h2>How to handle special cases: genrules and macros</h2>
<p>
Although Buck provides a rich set of built-in build rules for
developers, it is not able to address all possible needs. As an "escape hatch,"
Buck provides a category of generic build rules called <em>genrules</em>.
With genrules, you can perform arbitrary operations using shell scripts.
The genrules supported by Buck are:
</p>
<ul>
<li>{call buck.genrule /}</li>
<li>{call buck.apk_genrule /}</li>
<li>{call buck.cxx_genrule /}</li>
</ul>
<h3>Multiple output files with genrules</h3>
<p>
In most cases, a build rule produces exactly one output file. However,
with genrules, you can specify an output <em>directory</em> and write
arbitrary files to that directory.
</p>
<h3>Macros</h3>
<p>
Finally, note that you can define functions that generate build rules.
In general, this should not be something that you need to do, but taking
advantage of this option might help you add needed functionality to
Buck's without editing its source code. For more details, see the
{sp}<a href="{ROOT}extending/macros.html">Custom Macros</a> topic.
</p>
{/param}
{/call}
{/template}