mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-12-01 01:36:09 +03:00
126 lines
4.8 KiB
Markdown
126 lines
4.8 KiB
Markdown
# How GN handles cross-compiling
|
|
|
|
## As a GN user
|
|
|
|
GN has robust support for doing cross compiles and building things for
|
|
multiple architectures in a single build (e.g., to build some things to
|
|
run locally and some things to run on an embedded device). In fact,
|
|
there is no limit on the number of different architectures you can build
|
|
at once; the Chromium build uses at least four in some configurations.
|
|
|
|
To start, GN has the concepts of a _host_ and a _target_. The host is
|
|
the platform that the build is run on, and the target is the platform
|
|
where the code will actually run (This is different from
|
|
[autotools](http://www.gnu.org/software/automake/manual/html_node/Cross_002dCompilation.html)'
|
|
terminology, but uses the more common terminology for cross
|
|
compiling**).**
|
|
|
|
(Confusingly, GN also refers to each build artifact -- an executable,
|
|
library, etc. -- as a target. On this page, we will use "target" only to
|
|
refer to the system you want to run your code on, and use "rule" or some
|
|
other synonym to refer to a specific build artifact).
|
|
|
|
When GN starts up, the `host_os` and `host_cpu` variables are set
|
|
automatically to match the operating system (they can be overridden in
|
|
args files, which can be useful in weird corner cases). The user can
|
|
specify that they want to do a cross-compile by setting either or both
|
|
of `target_os` and `target_cpu`; if they are not set, the build config
|
|
files will usually set them to the host's values, though the Chromium
|
|
build will set target\_cpu to "arm" if target\_os is set to "android").
|
|
|
|
So, for example, running on an x64 Linux machine:
|
|
|
|
```
|
|
gn gen out/Default
|
|
```
|
|
|
|
is equivalent to:
|
|
|
|
```
|
|
gn gen out/Default --args='target_os="linux" target_cpu="x64"'
|
|
```
|
|
|
|
To do an 32-bit ARM Android cross-compile, do:
|
|
|
|
```
|
|
gn gen out/Default --args='target_os="android"'
|
|
```
|
|
|
|
(We don't have to specify target\_cpu because of the conditionals
|
|
mentioned above).
|
|
|
|
And, to do a 64-bit MIPS Chrome OS cross-compile:
|
|
|
|
```
|
|
gn gen out/Default --args='target_os="chromeos" target_cpu="mips64el"'
|
|
```
|
|
|
|
## As a BUILD.gn author
|
|
|
|
If you are editing build files outside of the //build directory (i.e.,
|
|
not directly working on toolchains, compiler configs, etc.), generally
|
|
you only need to worry about a few things:
|
|
|
|
The `current_toolchain`, `current_cpu`, and `current_os` variables
|
|
reflect the settings that are **currently** in effect in a given rule.
|
|
The `is_linux`, `is_win` etc. variables are updated to reflect the
|
|
current settings, and changes to `cflags`, `ldflags` and so forth also
|
|
only apply to the current toolchain and the current thing being built.
|
|
|
|
You can also refer to the `target_cpu` and `target_os` variables. This
|
|
is useful if you need to do something different on the host depending on
|
|
which target\_arch is requested; the values are constant across all
|
|
toolchains. You can do similar things for the `host_cpu` and `host_os`
|
|
variables, but should generally never need to.
|
|
|
|
For the default toolchain, `target_cpu` and `current_cpu` are the same. For a
|
|
secondary toolchain, `current_cpu` is set based on the toolchain definition
|
|
and `target_cpu` remains the same. When writing rules, **`current_cpu` should
|
|
be used rather than `target_cpu` most of the time**.
|
|
|
|
By default, dependencies listed in the `deps` variable of a rule use the
|
|
same (currently active) toolchain. You may specify a different toolchain
|
|
using the `foo(bar)` label notation as described in [the label section
|
|
of the reference doc](reference.md#Toolchains).
|
|
|
|
Here's an example of when to use `target_cpu` vs `current_cpu`:
|
|
|
|
```
|
|
declare_args() {
|
|
# Applies only to toolchains targeting target_cpu.
|
|
sysroot = ""
|
|
}
|
|
|
|
config("my_config") {
|
|
# Uses current_cpu because compile flags are toolchain-dependent.
|
|
if (current_cpu == "arm") {
|
|
defines = [ "CPU_IS_32_BIT" ]
|
|
} else {
|
|
defines = [ "CPU_IS_64_BIT" ]
|
|
}
|
|
# Compares current_cpu with target_cpu to see whether current_toolchain
|
|
# has the same architecture as target_toolchain.
|
|
if (sysroot != "" && current_cpu == target_cpu) {
|
|
cflags = [
|
|
"-isysroot",
|
|
sysroot,
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
## As a //build/config or //build/toolchain author
|
|
|
|
The `default_toolchain` is declared in the `//build/config/BUILDCONFIG.gn`
|
|
file. Usually the `default_toolchain` should be the toolchain for the
|
|
`target_os` and `target_cpu`. The `current_toolchain` reflects the
|
|
toolchain that is currently in effect for a rule.
|
|
|
|
Be sure you understand the differences between `host_cpu`, `target_cpu`,
|
|
`current_cpu`, and `toolchain_cpu` (and the os equivalents). The first
|
|
two are set as described above. You are responsible for making sure that
|
|
`current_cpu` is set appropriately in your toolchain definitions; if you
|
|
are using the stock templates like `gcc_toolchain` and `msvc_toolchain`,
|
|
that means you are responsible for making sure that `toolchain_cpu` and
|
|
`toolchain_os` are set as appropriate in the template invocations.
|