blob: 9f80b4074cd4dbeb00b5c169dc73f6fc401e7bbd [file] [log] [blame] [view]
# Migrating GYP to GN
Cobalt is currently in the process of migrating from our current build system
which uses [GYP][gyp_home] to an updated one with
[Generate Ninja (GN)][gn_home]. This allows us to remove our dependencies on
Python 2.
## Getting Started with GN
### Getting the Binary
There are a few ways to get a binary. Follow the instructions for whichever way
you prefer [here][gn_getting_a_binary].
### Setup your workstation and developer tools
Some environment settings and tools have changed with the GN migration. Please
go through the [setup guide][dev_setup_linux] to make sure your development
environment is properly configured.
### Read the Docs
Most of the documentation for GN is located [here][gn_doc_home].
* For a hands-on example with GN, check out the
[Quick Start Guide][gn_quick_start] and walk through the example.
* To learn more about the language and coding in it, read through the
[Language page][gn_language] and the [Style Guide][gn_style_guide].
* For a full reference of the language, run `gn help` or use the
[Reference page][gn_reference].
If you're familiar with GYP but not with GN, it may be helpful to read
Chromium's [GYP->GN Conversion Cookbook][gyp_to_gn_cookbook]. Keep in mind we
don't want to follow everything that's recommended here—much of the advice is
specific to Chromium. In particular:
* Whenever possible, avoid using a `source_set`. Instead, use a
`static_library`.
* Many of the flags under [Variable Mappings][gyp_to_gn_variable_mappings] do
not apply to Cobalt.
* Cobalt code is not Chromium code by default, so you can ignore
[that section][gyp_to_gn_chromium_code].
### Know the Tools
The flow of GN is fairly similar to that of GYP: you'll configure a build then
actually build it (using ninja). Here's how to build `nplb` target for
`stub_debug`:
```
$ gn gen out/stub_debug --args='target_platform="stub" build_type="debug"'
$ ninja -C out/stub_debug nplb
```
You can change the directory argument to `gn gen` (`out/stub_debug`) if you'd
like; unlike GYP, we can put the build root wherever we want.
There are some additional important tools: `gn format`, which is a code
formatter for GN, and `gn check`, which checks that build dependencies are
correctly set. See the documentation for [gn format][gn_format_tool] and
[gn check][gn_check_tool] for how to use both. The full list of commands GN
supports can be found on the [reference page][gn_reference].
## Migrating a Single Target
GYP and GN are very similar within the scope of a single target. The GYP->GN
Conversion Cookbook is a good reference for this, particularly
[this section][gyp_to_gn_typical_modifications]. The GYP syntax stays very
similar in general, though configuration will differ: in GN, you should create a
`config` targets and have your target add that to their list of configs:
```
config("foo_config") {
cflags = ...
}
static_library("foo") {
sources = ...
deps = ...
configs += [ ":foo_config" ]
}
```
You also may need to remove default configs. The default configs are listed in
[BUILDCONFIG.gn](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/config/BUILDCONFIG.gn).
You remove a config like so:
```
static_library("foo") {
configs -= [ "//full/path/to/config:config_name" ]
}
```
## Migrating a Platform
When porting your platform with GYP following
[the porting guide][cobalt_porting_guide], we expected a few build files to be
present under your starboard path:
* `gyp_configuration.py`
* `gyp_configuration.gypi`
* `starboard_platform.gyp`
These contain your toolchain, your compilation flags, your platform-specific
build variables, and your definition of the `starboard_platform` target. This
maps to the GN files needed to port your platform:
* Your toolchain: `toolchain/BUILD.gn`
* Your compilation flags: `platform_configuration/BUILD.gn`
* Your platform-specific build variables:
`platform_configuration/configuration.gni`
* Your definition of the `starboard_platform` target: `BUILD.gn`
Some of these files need to define certain targets:
* `toolchain/BUILD.gn`
The toolchain implementation is discussed in more detail
[below](#migrating-a-toolchain).
```
toolchain("host") {
...
}
toolchain("target") {
...
}
```
* `platform_configuration/BUILD.gn`
```
config("platform_configuration") {
# Set the flags that were in gyp_configuration.gypi.
}
```
* `BUILD.gn`
```
static_library("starboard_platform") {
# Largely the same as the current starboard_platform.gyp.
}
```
### Adding Your Platform to Starboard
Instead of implicitly searching directories for certain files like GYP did, we
explicitly enumerate our ports and their locations.
[platforms.gni](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/build/platforms.gni)
contains all of this information, and you'll need to add your platform to that
list following the same format.
### Migrating a Family of Platforms
Cobalt's reference platforms when implemented in GYP mainly used variables to
share sources and dependencies. In GN, we prefer putting shared sources and
dependencies in a static_library that we depend on in the final
`starboard_platform` `static_library` target. This means that configurations to
particular files should be in the same `static_library` that files are in.
### Migrating a Toolchain
Cobalt expects you to set a target and a host toolchain for your build like so:
```
toolchain("host") {
...
}
toolchain("target") {
...
}
```
You may define a toolchain from scratch following the [reference][gn_toolchain],
or you can use the
[gcc/clang templates](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/build/toolchain/gcc_toolchain.gni)
provided. Almost all of the reference platforms use these templates, so look to
those as examples for how to use it correctly. Here's the linux-x64x11
[toolchain/BUILD.gn file](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/starboard/linux/x64x11/toolchain/BUILD.gn).
When migrating a host toolchain, you'll need to set the `toolchain_args` within
it. This should always set the `current_os` and `current_cpu` if the `host_os`
and `host_cpu` differ from the `target_os` and `target_cpu`, respectively. V8
requires that 32 bit targets be compiled with 32 bit-compatible hosts (see
[here](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/third_party/v8/src/base/build_config.h)),
so you should make sure the `current_cpu` set in the `"host"` toolchain is
compatible with your `target_cpu`.
## Checking Your Migration
There are a few different ways to ensure you've migrated a target successfully.
You'll of course want to make sure you can build things after you've migrated
them.
### Validating a Target
If you're migrating a single target, it's simple to check: just configure the
build using the the necessary arguments then build that target with `ninja`,
i.e.:
```
static_library("new_target") { ... }
```
```
$ gn gen out/stub_debug --args='target_platform="stub" build_type="debug"'
$ gn check out/stub_debug
$ ninja -C out/stub_debug new_target
```
If this was equivalent to a GYP target, you can compare the ninja compilation
databases by using
[format_ninja.py](https://cobalt.googlesource.com/cobalt/+/refs/heads/master/tools/format_ninja.py)
and a comparison tool, i.e. [meld](https://meldmerge.org/). This will allow you
to see any changes in commands, i.e. with flags or otherwise.
The following differences for ninja flags between GYP and GN don't cause any
issues:
1. The name of the intermediate .o, .d files is different in both cases: Here
is an example while compiling the same source file
```
starboard/common/new.cc
```
GYP generates:
```
obj/starboard/common/common.new.cc.o
```
GN generates:
```
obj/starboard/common/common/new.o
```
1. The `-x` flag for specifying language is not present in GN migration. For
example GYP specifies `-x c` flag while building c language files for
certain targets. This flag is not specified while building any GN targets.
### Validating a Platform
Checking that an entire platform has been migrated successfully is slightly more
involved. It can be easiest to start by copying provided stub implementation and
continuously migrating it over, checking that it builds as you go along. If you
don't go this route, you can instead start by building a small target (with few
dependencies) then work your way up to building the `all` target.
You can use the same comparison method of using `format_ninja.py` as discussed
[in the section above](#validating-a-target).
### Step by Step Stub to Your Platform Migration Guide
This [document](./gn_migrate_stub_to_platform.md) outlines a step by step
process for converting the stub platform's GN files to GN files that will be
able to be built for your platform.
[cobalt_porting_guide]: https://cobalt.dev/starboard/porting.html
[dev_setup_linux]: https://cobalt.dev/development/setup-linux.html
[gn_check_tool]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#cmd_check
[gn_doc_home]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs
[gn_format_tool]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#cmd_format
[gn_getting_a_binary]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/#getting-a-binary
[gn_home]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/
[gn_language]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/language.md
[gn_reference]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md
[gn_style_guide]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/style_guide.md
[gn_toolchain]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/reference.md#func_toolchain
[gn_quick_start]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/quick_start.md
[gyp_home]: https://gyp.gsrc.io/index.md
[gyp_to_gn_chromium_code]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md#chromium-code
[gyp_to_gn_cookbook]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md
[gyp_to_gn_typical_modifications]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md#typical-sources-and-deps-modifications
[gyp_to_gn_variable_mappings]: https://cobalt.googlesource.com/third_party/gn/+/refs/heads/main/docs/cookbook.md#variable-mappings