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..29d6b31e418fd81f92f0c19c7ac1263287c0264c 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. |
@@ -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. |
+ |
+ * 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 |