Add some more docs on source sets, static libraries, and shlibs.

Hopefully this clarifies the decision process for when to use
which a little bit more.

Change-Id: If23015e935b90af5031e86e03962a4dbfb618147
Reviewed-on: https://gn-review.googlesource.com/c/3100
Reviewed-by: Brett Wilson <brettw@google.com>
Commit-Queue: Dirk Pranke <dpranke@chromium.org>
diff --git a/docs/style_guide.md b/docs/style_guide.md
index 295d08a..743ae8c 100644
--- a/docs/style_guide.md
+++ b/docs/style_guide.md
@@ -156,7 +156,8 @@
 
 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.
+to cause problems, but on a large project using the right kind of target can
+be important, so you should know about the following tradeoffs.
 
 Static libraries follow different linking rules. When a static library is
 included in a link, only the object files that contain unresolved symbols will
@@ -177,13 +178,15 @@
     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.
+  * On some platforms, static libraries may 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. Some platforms (or toolchains) may
+    support something called "thin archives" which don't have this problem;
+    but you can't rely on this as a portable solution.
 
   * Source sets can have no sources, while static libraries will give strange
     platform-specific errors if they have no sources. If a target has only
@@ -197,13 +200,22 @@
     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
+### Components versus shared libraries versus source sets
 
-A component is a Chrome primitive (rather than a built-in GN concept) that
+A component is a Chrome template (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.
+libraries for most operations. Chrome developers should almost always use
+a component instead of shared library directly.
+
+Much like the source set versus static library tradeoff, there's no hard
+and fast rule as to when you should use a component or not. Using
+components can significantly speed up incremental builds by making
+linking much faster, but they require you to have to think about which
+symbols need to be exported from the target.
+
+### Loadable modules versus shared libraries
 
 A shared library will be listed on the link line of dependent targets and will
 be loaded automatically by the operating system when the application starts
@@ -219,9 +231,7 @@
 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
+Use loadable modules for things like plugins. 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
@@ -293,4 +303,4 @@
 ```
 _this_var_will_not_be_exported = 1
 but_this_one_will = 2
-```
\ No newline at end of file
+```