Chromium Code Reviews| Index: tools/gn/docs/style_guide.md |
| diff --git a/tools/gn/docs/style_guide.md b/tools/gn/docs/style_guide.md |
| index cdb04ff728660e1383516794a64bf65e796d3b0c..156db92fe693cff058d505ef568ad41941282fe1 100644 |
| --- a/tools/gn/docs/style_guide.md |
| +++ b/tools/gn/docs/style_guide.md |
| @@ -18,7 +18,7 @@ changes are more focused. |
| more important targets will be first, and unit tests will follow the |
| corresponding target. If there's no clear ordering, consider |
| alphabetical order. |
| - * Test support libraries should be source sets named "test\_support". |
| + * Test support libraries should be static libraries named "test\_support". |
| So "//ui/compositor:test\_support". Test support libraries should |
| include as public deps the non-test-support version of the library |
| so tests need only depend on the test\_support target (rather than |
| @@ -53,7 +53,7 @@ Naming advice |
| Example for the `src/foo/BUILD.gn` file: |
| ``` |
| -# Copyright 2013 The Chromium Authors. All rights reserved. |
| +# Copyright 2016 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| @@ -81,7 +81,7 @@ source_set("bar") { |
| 1. `output_name` / `visibility` / `testonly` |
| 2. `sources` |
| 3. `cflags`, `include_dirs`, `defines`, `configs` etc. in whatever |
| - order makes sense to you. |
| + order makes sense to you. |
|
Dirk Pranke
2016/06/16 20:01:27
Nit: I would've thought the prior indentation was
brettw
2016/06/16 20:27:36
Whoops, it sure looks wrong though.
|
| 4. `public_deps` |
| 5. `deps` |
| @@ -150,10 +150,75 @@ import("//foo/bar/baz.gni") # Even if this file is in the foo/bar directory |
| ## Usage |
| -Use `source_set` rather than `static_library` unless you have a reason |
| -to do otherwise. A static library is a standalone library which can be |
| -slow to generate. A source set just links all the object files from that |
| -target into the targets depending on it, which saves the "lib" step. |
| +### Source sets versus static libraries |
| + |
| +Source sets and static libraries can be used interchangeably in most cases. If |
| +you're unsure what to use, a source set is almost never wrong and is less likely |
| +to cause problems. |
| + |
| +Static libraries follow different linking rules. When a static library is |
| +included in a link, only the object files that contain unresolved symbols will |
| +be brought into the build. Source sets result in every object file being added |
| +to the link line of the final binary. |
| + |
| + * If you're eventually linking code into a component, shared library, or |
| + loadable module, you normally need to use source sets. This is because |
| + object files with no symbols referenced from within the shared library will |
| + not be linked into the final library at all. This omission will happen even |
| + if that object file has a symbol marked for export that targets dependant |
| + on that shared library need. This will result in undefined symbols when |
| + linking later targets. |
|
Dirk Pranke
2016/06/16 20:01:27
This really applies to code that is exported from
brettw
2016/06/16 20:27:36
That's true, but I think a lot of people don't see
|
| + |
| + * Unit tests (and anything else with static initializers with side effects) |
| + must use source sets. The gtest TEST macros create static initializers |
| + that register the test. But since no code references symbols in the object |
| + file, linking a test into a static library and then into a test executable |
| + means the tests will get stripped. |
| + |
| + * Static libraries involve duplicating all of the data in the object files |
| + that comprise it. This takes more disk space and for certain very large |
| + libraries in configurations with very large object files can cause |
| + internal limits on the size of static libraries to be exceeded. Source |
| + sets do not have this limitation. Some targets switch between source sets |
| + and static libraries depending on the build configuration to avoid this |
| + problem. |
| + |
| + * In cases where a lot of the symbols are not needed for a particular link |
| + (this especially happens when linking test binaries), putting that code in |
| + a static library can dramatically increase linking performance. This is |
| + because the object files not needed for the link are never considered in |
| + the first place, rather than forcing the linker to strip the unused code |
| + in a later pass when nothing references it. |
| + |
| +### Loadable modules versus shared libraries versus components |
| + |
| +A component is a Chrome primitive (rather than a built-in GN concept) that |
| +expands either to a shared library or a static library / source set depending |
| +on the value of the `is_component_build` variable. This allows release builds |
| +to be linked statically in a large binary, but for developers to use shared |
| +libraries for most operations. |
| + |
| +A shared library will be listed on the link line of dependant targets and will |
| +be loaded automatically by the operating system when the application starts |
| +and symbols automatically resolved. A loadable module will not be linked |
| +directly and the application must manually load it. |
| + |
| +On Windows and Linux shared libraries and loadable modules result in the same |
| +type of file (`.dll` and `.so`, respectively). The only difference is in how |
| +they are linked to dependant targets. On these platforms, having a `deps` |
| +dependency on a loadable module is the same as having a `data_deps` |
| +(non-linked) dependency on a shared library. |
| + |
| +On Mac, these targets have different formats: a shared library will generate a |
| +`.dylib` file and a loadable module will generate a `.so` file. |
| + |
| +Use loadable modules for things like plugins. Shared libraries should be |
| +seldom-used outside of components because most Chrome code is shipped to the |
| +end-user as a small number of large binaries. In the case of plugin-like |
| +libraries, it's good practice to use both a loadable module for the target type |
| +(even for platforms where it doesn't matter) and data deps for targets that |
| +depend on it so it's clear from both places that how the library will be linked |
| +and loaded. |
| ## Build arguments |