1 # GYP->GN Conversion Cookbook
8 |:-------------------------------------------------|:---------------------------------------------------|
9 | `'type': 'static_library', 'name': 'foo',` | `static_library("foo") {` or `source_set("foo") {` |
10 | `'type': 'shared_library', 'name': 'foo',` | `shared_library("foo") {` |
11 | `'type': '<(component)', 'name': 'foo',` | `component("foo") {` |
12 | `'type': 'executable', 'name': 'foo',` | `executable("foo") {` |
13 | `'type': '<(gtest_target_type)', 'name': 'foo',` | `test("foo") {` |
14 | `'type': 'none', 'name': 'foo',` | `group("foo") {` |
16 ### Note on static libraries
18 A source\_set is basically a transparent static\_library. The source files
19 are compiled with the given options but not linked into anything.
20 Targets that depend on a source set get the source set's object files
21 linked into it. This saves the overhead of creating a static library on
22 disk, avoids weird linker issues when a static library has no source
23 files, and you can link source sets into shared libraries and have
24 symbols exported from the shared library.
26 The last issue is a cause of a lot of headaches in the GYP build. If you
27 annotate a symbol as exported (i.e. `BASE_EXPORT`) then you can't have
28 it in a file that goes into a static library because the function might
29 be [http://blogs.msdn.com/b/oldnewthing/archive/2014/03/21/10509670.aspx
30 stripped out] if it's not called from within the static library. This
31 prevents composing components of static libraries and exporting their
32 symbols. A source set avoids this issue and `EXPORT` has the desired
33 meaning of "export from the component this gets linked into" with no
34 surprising dead code stripping behavior.
36 A disadvantage of source sets is that if an object file is completely
37 unused, it will still be linked into the result, which is not the case
38 for static libraries. A few places in the build depend on this behavior
39 (deliberately or accidentally). In general, small libraries that we
40 expect to be entirely used, test helpers, etc. can be source sets. There
41 is slightly less risk of subtle issues if you keep static libraries
42 static libraries, however.
51 'inputs': [ 'bar.py' ],
52 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/bar.out' ],
53 'action': ['python', 'bar.py', '--la_dee_da' ],
57 Unlike GYP, where an action is a part of a target, GN actions are
58 separate targets that you then depend on via deps from other targets:
63 outputs = [ "$target_gen_dir/bar.out" ]
64 args = [ "--la_dee_da" ]
67 executable('foo.exe') {
69 deps = [ ":foo" ] # Depend on the action to make sure it runs.
73 Rules in GYP become `action_foreach` in GN which work like actions but
74 iterate over a set of sources.
79 |:-------------------------------------|:---------------------|
80 | `'conditions': [['OS=="win"', {` | `if (is_win) {` |
81 | `'conditions': [['OS=="linux"', {` | `if (is_linux) {` |
82 | `'conditions': [['OS=="android"', {` | `if (is_android) {` |
83 | `'conditions': [['OS=="mac"', {` | `if (is_mac) {` |
84 | `'conditions': [['OS=="ios"', {` | `if (is_ios) {` |
85 | `'conditions': [['chromeos==1', {` | `if (is_chromeos) {` |
87 ## Typical sources and deps modifications
97 '<(DEPTH)/base/base.gyp:foo',
108 '<(DEPTH)/base/base.gyp:bar',
112 ['exclude', '^b\\.cc$'],
130 sources -= [ "a.cc" ]
131 sources += [ "foo.cc" ]
132 deps += [ "//base:bar" ]
134 sources -= [ "b.cc" ]
140 ### Build configuration
142 Build configuration and feature flags are usually global in GYP. In GN
143 we try to limit global variables and instead put variables used by only
144 some files into `.gni` files. These files are then imported into your
145 buildfile by specifying at the top:
148 import("//build/config/features.gni")
150 # ... now you can use the variables declared in features.gni.
154 if (cld_version == 2) {
159 Other flags only apply to one `BUILD.gn` file and those flags are
160 declared directly in that file (so other files can't use them). These
161 places are noted in the table below.
163 | *GYP* | *GN* | *GN import* |
164 |:------------------------------------------------|:-------------------------------------------|:-----------------------------------------------|
165 | `arm_float_abi` | `arm_float_abi` | `//build/config/arm.gni` |
166 | `arm_neon` (0/1) | `arm_use_neon` (true/false) | `//build/config/arm.gni` |
167 | `arm_neon_optional` (0/1) | `arm_optionally_use_neon` (true/false) | `//build/config/arm.gni` |
168 | `arm_version` | `arm_version` | `//build/config/arm.gni` |
169 | `asan` (0/1) | `is_asan` (true/false) | (global) |
170 | `branding` ("Chromium"/"Chrome"") | `is_chrome_branded` (true/false) | `//build/config/chrome_build.gni` |
171 | `build_for_tool=="drmemory"` | `disable_iterator_debugging` (true/false) | (internal to `//build/config/BUILD.gn`) |
172 | `build_for_tool=="tsan"` | `disable_iterator_debugging` (true/false) | (internal to `//build/config/BUILD.gn`) |
173 | `buildtype` ("Official"/"Dev") | `is_official_build` (true/false) | `//build/config/chrome_build.gni` |
174 | `chrome_multiple_dll` (0/1) | `is_multi_dll_chrome` (true/false) | `//build/config/chrome_build.gni` |
175 | `clang` (0/1) | `is_clang` (true/false) | (global) |
176 | `clang_use_chrome_plugins` (0/1) | `clang_use_chrome_plugins` (true/false) | (internal to `//build/config/clang/BUILD.gn`) |
177 | `component` ("shared_library"/"static_library") | `is_component_build` (true/false) | (global) |
178 | `desktop_linux` (0/1) | `is_desktop_linux` (true/false) | (global) |
179 | `disable_glibcxx_debug` (0/1) | `disable_iterator_debugging` (true/false) | (internal to `//build/config/BUILD.gn`) |
180 | `fastbuild` (0/1/2) | `symbol_level` (2/1/0 — values inverted) | (global) |
181 | `gomadir` | `goma_dir` | `//build/toolchain/goma.gni` |
182 | `ios_deployment_target` (string) | `ios_deployment_target` | `//build/config/ios/ios_sdk.gni` |
183 | `GYP_MSVS_OVERRIDE_PATH` environment variable | `visual_studio_path` | `//build/config/win/visual_studio_version.gni` |
184 | `GYP_MSVS_VERSION` environment variable | (none) | |
185 | `ios_sdk_path` | `ios_sdk_path` and `use_ios_simulator` | `//build/config/ios/ios_sdk.gni` |
186 | `lsan` (0/1) | `is_lsan` (true/false) | (global) |
187 | `mac_sdk_min` | `mac_sdk_min` | `//build/config/mac/mac_sdk.gni` |
188 | `mac_sdk_path` | `mac_sdk_path` | `//build/config/mac/mac_sdk.gni` |
189 | `mac_sdk` | `mac_sdk_version` | `//build/config/mac/mac_sdk.gni` |
190 | `msan` (0/1) | `is_msan` (true/false) | (global) |
191 | `SDKROOT` (Mac) | `sysroot` | `//build/config/sysroot.gni` |
192 | `sysroot` | `sysroot` | `//build/config/sysroot.gni` |
193 | `target_arch` ("ia32"/"x64"/"arm"/"mipsel") | `target_arch` ("x86"/"x64"/"arm"/"mipsel") | (global) |
194 | `toolkit_views` (0/1) | `toolkit_views` | `//build/config/ui.gni` |
195 | `tsan` (0/1) | `is_tsan` (true/false) | (global) |
196 | `windows_sdk_path` | `windows_sdk_path` | (internal to `//build/config/win/BUILD.gn`) |
200 | *GYP* | *GN* | *GN import* |
201 |:----------------------------------------|:-----------------------------------------------|:------------------------------|
202 | `cld_version` (number) | `cld_version` (number) | `//build/config/features.gni` |
203 | `configuration_policy` (0/1) | `enable_configuration_policy` (true/false) | `//build/config/features.gni` |
204 | `debug_devtools` (0/1) | `debug_devtools` (true/false) | `//build/config/features.gni` |
205 | `disable_ftp_support` (0/1) | `disable_ftp_support` (true/false) | `//build/config/features.gni` |
206 | `disable_nacl` (0/1) | `enable_nacl` (true/false) | `//build/config/features.gni` |
207 | `enable_app_list` (0/1) | `enable_app_list` (true/false) | `//build/config/features.gni` |
208 | `enable_autofill_dialog` (0/1) | `enable_autofill_dialog` (true/false) | `//build/config/features.gni` |
209 | `enable_background` (0/1) | `enable_background` (true/false) | `//build/config/features.gni` |
210 | `enable_captive_portal_detection` (0/1) | `enable_captive_portal_detection` (true/false) | `//build/config/features.gni` |
211 | `enable_chromevox_next` (0/1) | `enable_chromevox_next` (true/false) | `//build/config/features.gni` |
212 | `enable_extensions` (0/1) | `enable_extensions` (true/false) | `//build/config/features.gni` |
213 | `enable_google_now` (0/1) | `enable_google_now` (true/false) | `//build/config/features.gni` |
214 | `enable_hidpi` (0/1) | `enable_hidpi` (true/false) | `//build/config/ui.gni` |
215 | `enable_managed_users` (0/1) | `enable_managed_users` (true/false) | `//build/config/features.gni` |
216 | `enable_mdns` (0/1) | `enable_mdns` (true/false) | `//build/config/features.gni` |
217 | `enable_one_click_signin` (0/1) | `enable_one_click_signin` (true/false) | `//build/config/features.gni` |
218 | `enable_pepper_cdms` (0/1) | `enable_pepper_cdms` (true/false) | `//build/config/features.gni` |
219 | `enable_plugins` (0/1) | `enable_plugins` (true/false) | `//build/config/features.gni` |
220 | `enable_plugin_installation` (0/1) | `enable_plugin_installation` (true/false) | `//build/config/features.gni` |
221 | `enable_basic_printing` (0/1) | `enable_basic_printing` (true/false) | `//build/config/features.gni` |
222 | `enable_print_preview` (0/1) | `enable_print_preview` (true/false) | `//build/config/features.gni` |
223 | `enable_rlz` (0/1) | `enable_rlz` (true/false) | `//build/config/features.gni` |
224 | `enable_service_discovery` (0/1) | `enable_service_discovery` (true/false) | `//build/config/features.gni` |
225 | `enable_spellcheck` (0/1) | `enable_spellcheck` (true/false) | `//build/config/features.gni` |
226 | `enable_session_service` (0/1) | `enable_session_service` (true/false) | `//build/config/features.gni` |
227 | `enable_settings_app` (0/1) | `enable_settings_app` (true/false) | `//build/config/features.gni` |
228 | `enable_task_manager` (0/1) | `enable_task_manager` (true/false) | `//build/config/features.gni` |
229 | `enable_themes` (0/1) | `enable_themes` (true/false) | `//build/config/features.gni` |
230 | `enable_webrtc` (0/1) | `enable_webrtc` (true/false) | `//build/config/features.gni` |
231 | `enable_wifi_bootstrapping` (0/1) | `enable_wifi_bootstrapping` (true/false) | `//build/config/features.gni` |
232 | `image_loader_extension` (0/1) | `enable_image_loader_extension` (true/false) | `//build/config/features.gni` |
233 | `input_speech` (0/1) | `enable_speech_input` (true/false) | `//build/config/features.gni` |
234 | `notifications` (0/1) | `enable_notifications` (true/false) | `//build/config/features.gni` |
235 | `ozone_platform_dri` (0/1) | `ozone_platform_dri` (true/false) | `//build/config/ui.gni` |
236 | `remoting` (0/1) | `enable_remoting` (true/false) | `//build/config/features.gni` |
237 | `safe_browsing` (0/1/2) | `safe_browsing_mode` (0/1/2) | `//build/config/features.gni` |
238 | `use_allocator` (`'none'`|`'tcmalloc'`) | `use_allocator` (`"none"`|`"tcmalloc"`) | (See "Allocator" below) |
239 | `ui_compositor_image_transport` (0/1) | `ui_compositor_image_transport` (true/false) | `//build/config/ui.gni` |
240 | `use_ash` (0/1) | `use_ash` (true/false) | `//build/config/ui.gni` |
241 | `use_athena` (0/1) | `use_athena` (true/false) | `//build/config/ui.gni` |
242 | `use_aura` (0/1) | `use_aura` (true/false) | `//build/config/ui.gni` |
243 | `use_brlapi` (0/1) | `use_brlapi` (true/false) | `//build/config/features.gni` |
244 | `use_cairo` (0/1) | `use_cairo` (true/false) | `//build/config/ui.gni` |
245 | `use_clipboard_aurax11` (0/1) | `use_aura && use_x11` | |
246 | `use_cups` (0/1) | `use_cups` (true/false) | `//build/config/features.gni` |
247 | `use_dbus` (0/1) | `use_dbus` (true/false) | `//build/config/features.gni` |
248 | `use_gconf` (0/1) | `use_gconf` (true/false) | `//build/config/features.gni` |
249 | `use_glib` (0/1) | `is_linux` (true/false) | (global) |
250 | `use_gnome_keyring` (0/1) | `is_desktop_linux` (true/false) | |
251 | `use_goma` (0/1) | `use_goma` (true/false) | `//build/toolchain/goma.gni` |
252 | `use_nss_certs` (0/1) | `use_nss_certs` (true/false) | `//build/config/crypto.gni` (Many of these conditions can be deleted, see the "SSL" notes on targets below.) |
253 | `use_openssl` (0/1) | `use_openssl` (true/false) | `//build/config/crypto.gni` (Many of these conditions can be deleted, see the "SSL" notes on targets below.) |
254 | `use_pango` (0/1) | `use_pango` (true/false) | `//build/config/ui.gni` |
255 | `use_ozone` (0/1) | `use_ozone` (true/false) | `//build/config/ui.gni` |
256 | `use_seccomp_bpf` (0/1) | `use_seccomp_bpf` (true/false) | `//build/config/features.gni` |
257 | `use_udev` (0/1) | `use_udev` (true/false) | `//build/config/features.gni` |
258 | `use_x11` (0/1) | `use_x11` (true/false) | `//build/config/ui.gni` |
259 | `use_xi2_mt` (0/1) | `use_xi2_mt` (true/false) | `//build/config/ui.gni` |
260 | `win_pdf_metafile_for_printing` (0/1) | `win_pdf_metafile_for_printing` (true/false) | `//build/config/features.gni` |
261 | `win_use_allocator_shim` (0/1) | | (See "Allocator" below) |
263 ### Common target conversion
265 Some targets that lots of projects depend on and how the GN ones
266 correspond to GYP ones. (This is for commonly-depended-on or weird
267 targets only, don't add stuff here just because you converted it.)
269 | *GYP* | *GN* | *Notes* (see below) |
270 |:-----------------------------------------------------------------------------------|:-----------------------------------------|:---------------------|
271 | `base/base.gyp:base` | `//base` | |
272 | `base/base.gyp:base_i18n` | `//base:i18n` | |
273 | `base/base.gyp:run_all_unittests` | `//base/test:run_all_unittests` | |
274 | `base/base.gyp:test_support_base` | `//base/test:test_support` | |
275 | `base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations` | `//base/third_party/dynamic_annotations` | |
276 | `build/linux/system.gyp:*` (except ssl) | `//build/config/linux:*` | Linux system targets |
277 | `build/linux/system.gyp:ssl` | `//crypto:platform` | SSL |
278 | `net/third_party/nss/ssl.gyp:libssl` | `//crypto:platform` | SSL |
279 | `skia/skia.gyp:skia` | `//skia` | |
280 | `testing/gmock.gyp:gmock` | `//testing/gmock` | Secondary tree |
281 | `testing/gtest.gyp:gtest` | `//testing/gtest` | Secondary treeo |
282 | `third_party/icu/icu.gyp:icui18n` | `//third_party/icu` | Secondary tree, ICU |
283 | `third_party/icu/icu.gyp:icuuc` | `//third_party/icu` | Secondary tree, ICU |
284 | `url/url.gyp:url_lib` | `//url` || ||
288 * *ICU:* GN has separate `//third_party/icu:icuuc` and
289 `//third_party/icu:icui18n` targets just like GYP. You can use these
290 if you only need one of them. Most targets want both, so GN made a
291 meta target that's just `//third_party/icu` which you can use that
292 redirects to both "uc" and "i18n".
294 * *Linux system targets:* Generally the names in GN patch the GYP
295 names for the Linux system-related stuff. However, most of them are
296 configs instead of actual targets (in GYP they're all targets). For
297 example, since "x11" is just a list of libraries and include
298 directories, and includes no sources it's a config that just adds
299 this configuration to your target. To use a config, do `configs += [
300 "//build/config/linux:x11" ]`
302 * *Secondary tree:* Some projects are DEPSed in and we want it to look
303 like a BUILD.gn file is in that directory without checking it in to
304 the upstream repo. The directory `build/secondary` mirrors the main
305 tree and is checked for BUILD.gn files if an expected file in the
306 main tree wasn't found.
308 * *SSL:* In GYP there are lots of conditions around NSS vs. OpenSSL
309 and different platforms that determine which of the different SSL
310 libraries is linked. In GN, there is a meta-target
311 `//crypto:platform` that will "do the right thing" according to the
312 current build platform and flags. Generally its safe to replace any
313 conditional reference to a SSL library with this one.
315 ## Visibility and header file issues
317 GN is much more strict about header file checking. You may encounter
318 errors that your target doesn't depend on the target containing a
319 certain header file. The most common example is including
320 `base/basictypes.h` without having `//base` in your project's dependency
321 list. The solution is to just add the missing dependency.
323 The dependency tree must be a DAG. Some components might share headers
324 between a number of internal targets that makes adding the "proper"
325 dependencies impossible. In this case, you can separate out a
326 `source_set` type target containing just the header(s) in question, and
327 make the targets that use that header depend on that source set to break
332 ### Target conditions
334 `target_conditions` are like normal conditions but expanded in a
335 different phase of GYP. You can generally just convert the conditions
336 inside and not worry about the `conditions`/`target_conditions`
341 Some xcode settings are obvious:
344 'xcode_settings': {'OTHER_LDFLAGS': ['-foo']},
347 Should just expand to:
353 Other flags are less obvious:
356 'xcode_settings': { 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO', },
359 These all correspond to various flags that get passed to the compiler or
360 linker. You can use your favorite search engine to see what it
361 corresponds to, but many of them are not well documented. You can also
362 search for the string in
363 [https://code.google.com/p/chromium/codesearch#chromium/src/tools/gyp/pylib/gyp/xcode_emulation.py
364 tools/gyp/pylib/gyp/xcode_emulation.py]. GYP uses this file to decode
365 the Xcode settings into command line flags for the ninja build.
367 ### wexit-time destructors
372 'enable_wexit_time_destructors': 1,
378 configs += [ "//build/config/compiler:wexit_time_destructors" ]
383 In GYP code is "non-Chromium" by default, and you opt into higher warning levels using:
389 In GN, all code is Chromium code by default. If you're compiling a
390 static library that needs more lax warnings, opt out of the
391 Chromium-code settings with:
394 configs -= [ "//build/config/compiler:chromium_code" ]
395 configs += [ "//build/config/compiler:no_chromium_code" ]
400 All symbols in the build have "hidden" visibility by default (this means
401 that symbols aren't exported from shared libraries, a concept different
402 than GN's target visibility). If you needed to export all symbols (for a
403 third party library) by default in GYP you would do:
407 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO', # no -fvisibility=hidden
410 '-fvisibility=hidden',
414 In GN the equivalent is:
418 configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
422 ### Dependent settings
424 In GYP you'll see stuff like this, especially in third-party code.
427 'direct_dependent_settings': {
429 '.', # This directory.
430 '../..', # Root "src" path.
438 Note that many of the includes are trying to add the root "src"
439 directory to the include path. This is always present in GN so you can
442 GYP also requires you do duplicate these settings, once for the target
443 itself, and once for the direct/all dependent settings. In GN,
444 public/all dependent configs also apply to the current target so you
445 only need to specify it once.
447 In GN, put the settings in a config (declared above your target), and
448 then reference that as a public config in your target:
451 config("foo_config") {
452 include_dirs = [ "." ]
458 public_configs = [ ":foo_config" ]
462 Targets that depend on `foo` will now get `foo_config` applied.
464 GYP would say `export_dependent_settings` to forward
465 `direct_dependent_settings` up the dependency chain. In GN, put the
466 dependency in the `public_deps` section and this will happen
469 ### MSVS disabled warnings
471 In GYP you'll see for third-party code:
474 'msvs_disabled_warnings': [ 4018, 4244, 4267, ],
477 At least half of the warnings in these blocks are already disabled
478 globally (we added more global ones later). From the command line, do:
481 $ cd src/build/config
483 compiler/BUILD.gn: "/wd4018", # Comparing signed and unsigned values.
486 tells us that warning 4018 is already disabled globally from the
487 `//build/config/compiler:default_warnings` config, and the same for
488 4244. So ignore these.
490 Always comment what the warning is. Use your favorite search engine and
491 type "vc warning 4267" to look it up. You'll end up with:
496 "/wd4267", # Conversion from size_t to 'type'.
501 (Use `=` instead of `+=` is you haven't already defined a `cflags` variable.)
505 GN knows to convert `.framework` files in the `libs` list to the right
506 thing on Mac. You don't need to specify the directories either. So
512 '$(SDKROOT)/System/Library/Frameworks/Accelerate.framework',
520 libs = [ "Accelerate.framework" ]
525 GYP code sometimes sets
528 'hard_dependency': 1,
531 to indicate that the current target must be build before its dependents.
532 GN can deduce this internally, so you can ignore this directive.
536 GYP has `win_use_allocator_shim` and `use_allocator`. In GN, these are
537 merged into `use_allocator` which is defined in
538 `//build/config/allocator.gni`. _However_ you should almost never need
539 to use this flag. The `//base/allocator` target will change depending on
540 the current allocator flag, so you can unconditionally depend on this
541 target to pick up the current build defaults.
546 ['use_allocator!='none'', {
547 'dependencies': [ '../base/allocator/allocator.gyp:allocator' ]
549 ['win_use_allocator_shim==1', {
550 'dependencies': [ '<(allocator_target)' ],
557 deps = [ "//base/allocator" ]
560 As in GYP, the allocator should only be depended on by executables (and
561 tests). Libraries should not set the allocator.
571 only affects Windows and will optimize for speed rather than size. To
572 get the same behavior in GN, do:
575 if (!is_debug && is_win) {
576 configs -= [ "//build/config/compiler:optimize" ]
577 configs += [ "//build/config/compiler:optimize_max" ]
581 The `is_win` check is needed because the `optimize_max` config also
582 affects Posix systems. Some components might additionally specify `-O2`
583 on Posix further optimize, in which case you can remove the `is_win`
589 import("//third_party/protobuf/proto_library.gni")
591 proto_library("myproto") {
592 sources = [ "foo.proto" ]
596 See the `third_party/protobuf/proto_library.gni` file for full
597 documentation and extra flags.
601 JNI generator in GYP:
605 'target_name': 'foo_headers',
607 'sources': [ <java files> ]
608 'variables': { 'jni_gen_package': 'foobar' }
609 'includes': [ 'build/jni_generator.gypi' ]
618 import("//build/config/android/rules.gni")
623 generate_jni("foo_headers") {
624 sources = [ <java files> ]
625 jni_package = "foobar"
633 import("//tools/grit/grit_rule.gni")
636 source = "my_resources.grd"
640 See `src/build/secondary/tools/grit/grit_rule.gni` for more documentation.
645 import("//mojo/public/tools/bindings/mojom.gni")
647 mojom("mojo_bindings") {