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 [stripped out](http://blogs.msdn.com/b/oldnewthing/archive/2014/03/21/10509670.aspx)
30 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) | `//build/config/sanitizers/sanitizers.gni` |
170 | `branding` ("Chromium"/"Chrome") | `is_chrome_branded` (true/false) | `//build/config/chrome_build.gni` |
171 | `build_for_tool=="drmemory"` | `enable_iterator_debugging=false` | (internal to `//build/config/BUILD.gn`) |
172 | `build_for_tool=="tsan"` | `enable_iterator_debugging=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) | `enable_iterator_debugging` (true/false) | (internal to `//build/config/BUILD.gn`) |
180 | `fastbuild` (0/1/2) | `symbol_level` (2/1/0 — values inverted) | `//build/config/compiler/compiler.gni` |
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) | `//build/config/sanitizers/sanitizers.gni` |
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) | `//build/config/sanitizers/sanitizers.gni` |
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) | `//build/config/sanitizers/sanitizers.gni` |
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/macros.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 [tools/gyp/pylib/gyp/xcode_emulation.py](https://code.google.com/p/chromium/codesearch#chromium/src/tools/gyp/pylib/gyp/xcode_emulation.py). GYP uses this file to decode
364 the Xcode settings into command line flags for the ninja build.
366 ### wexit-time destructors
371 'enable_wexit_time_destructors': 1,
377 configs += [ "//build/config/compiler:wexit_time_destructors" ]
382 In GYP code is "non-Chromium" by default, and you opt into higher warning levels using:
388 In GN, all code is Chromium code by default. If you're compiling a
389 static library that needs more lax warnings, opt out of the
390 Chromium-code settings with:
393 configs -= [ "//build/config/compiler:chromium_code" ]
394 configs += [ "//build/config/compiler:no_chromium_code" ]
399 All symbols in the build have "hidden" visibility by default (this means
400 that symbols aren't exported from shared libraries, a concept different
401 than GN's target visibility). If you needed to export all symbols (for a
402 third party library) by default in GYP you would do:
406 'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO', # no -fvisibility=hidden
409 '-fvisibility=hidden',
413 In GN the equivalent is:
417 configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
421 ### Dependent settings
423 In GYP you'll see stuff like this, especially in third-party code.
426 'direct_dependent_settings': {
428 '.', # This directory.
429 '../..', # Root "src" path.
437 Note that many of the includes are trying to add the root "src"
438 directory to the include path. This is always present in GN so you can
441 GYP also requires you do duplicate these settings, once for the target
442 itself, and once for the direct/all dependent settings. In GN,
443 public/all dependent configs also apply to the current target so you
444 only need to specify it once.
446 In GN, put the settings in a config (declared above your target), and
447 then reference that as a public config in your target:
450 config("foo_config") {
451 include_dirs = [ "." ]
457 public_configs = [ ":foo_config" ]
461 Targets that depend on `foo` will now get `foo_config` applied.
463 GYP would say `export_dependent_settings` to forward
464 `direct_dependent_settings` up the dependency chain. In GN, put the
465 dependency in the `public_deps` section and this will happen
468 ### MSVS disabled warnings
470 In GYP you'll see for third-party code:
473 'msvs_disabled_warnings': [ 4018, 4244, 4267, ],
476 At least half of the warnings in these blocks are already disabled
477 globally (we added more global ones later). From the command line, do:
480 $ cd src/build/config
482 compiler/BUILD.gn: "/wd4018", # Comparing signed and unsigned values.
485 tells us that warning 4018 is already disabled globally from the
486 `default_warning_flags` variable in `//build/config/compiler`, and the same
487 for 4244. So ignore these.
489 Always comment what the warning is. Use your favorite search engine and
490 type "vc warning 4267" to look it up. You'll end up with:
495 "/wd4267", # Conversion from size_t to 'type'.
500 (Use `=` instead of `+=` is you haven't already defined a `cflags` variable.)
504 GN knows to convert `.framework` files in the `libs` list to the right
505 thing on Mac. You don't need to specify the directories either. So
511 '$(SDKROOT)/System/Library/Frameworks/Accelerate.framework',
519 libs = [ "Accelerate.framework" ]
524 GYP code sometimes sets
527 'hard_dependency': 1,
530 to indicate that the current target must be build before its dependents.
531 GN can deduce this internally, so you can ignore this directive.
535 GYP has `win_use_allocator_shim` and `use_allocator`. In GN, these are
536 merged into `use_allocator` which is defined in
537 `//build/config/allocator.gni`. _However_ you should almost never need
538 to use this flag. The `//base/allocator` target will change depending on
539 the current allocator flag, so you can unconditionally depend on this
540 target to pick up the current build defaults.
545 ['use_allocator!='none'', {
546 'dependencies': [ '../base/allocator/allocator.gyp:allocator' ]
548 ['win_use_allocator_shim==1', {
549 'dependencies': [ '<(allocator_target)' ],
556 deps = [ "//base/allocator" ]
559 As in GYP, the allocator should only be depended on by executables (and
560 tests). Libraries should not set the allocator.
570 only affects Windows and will optimize for speed rather than size. To
571 get the same behavior in GN, do:
574 if (!is_debug && is_win) {
575 configs -= [ "//build/config/compiler:default_optimization" ]
576 configs += [ "//build/config/compiler:optimize_max" ]
580 The `is_win` check is needed because the `optimize_max` config also
581 affects Posix systems. Some components might additionally specify `-O2`
582 on Posix further optimize, in which case you can remove the `is_win`
588 import("//third_party/protobuf/proto_library.gni")
590 proto_library("myproto") {
591 sources = [ "foo.proto" ]
595 See the `third_party/protobuf/proto_library.gni` file for full
596 documentation and extra flags.
600 JNI generator in GYP:
604 'target_name': 'foo_headers',
606 'sources': [ <java files> ]
607 'variables': { 'jni_gen_package': 'foobar' }
608 'includes': [ 'build/jni_generator.gypi' ]
617 import("//build/config/android/rules.gni")
622 generate_jni("foo_headers") {
623 sources = [ <java files> ]
624 jni_package = "foobar"
632 import("//tools/grit/grit_rule.gni")
635 source = "my_resources.grd"
639 See `src/build/secondary/tools/grit/grit_rule.gni` for more documentation.
644 import("//mojo/public/tools/bindings/mojom.gni")
646 mojom("mojo_bindings") {