OLD | NEW |
(Empty) | |
| 1 # Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import("//build/split_static_library.gni") # When someone uses that target_type |
| 6 |
| 7 declare_args() { |
| 8 # If true, use a jumbo build (files compiled together) to speed up |
| 9 # compilation. |
| 10 use_jumbo_build = false |
| 11 |
| 12 # A target to exclude from jumbo builds, for optimal round trip time |
| 13 # when frequently changing a single cpp file. |
| 14 jumbo_build_excluded = "" |
| 15 |
| 16 # How many files to group at most. Smaller numbers give more |
| 17 # parallellism, higher numbers give less total CPU usage. Higher |
| 18 # numbers also give longer single-file recompilation times. |
| 19 # |
| 20 # Recommendations: |
| 21 # Higher numbers than 200 does not reduce wall clock compile times |
| 22 # for 4 cores or less. |
| 23 # 200 uses 8% less total CPU than 100 when compiling content and 10% |
| 24 # less wall clock when compiling with 4 cores. |
| 25 jumbo_file_merge_limit = 200 |
| 26 } |
| 27 |
| 28 # Use this to generate a target which merges sources if possible to |
| 29 # compile much faster. |
| 30 # |
| 31 # Special values. |
| 32 # |
| 33 # target_type |
| 34 # The kind of target to build. For example the string |
| 35 # "static_library". |
| 36 # |
| 37 # always_build_jumbo |
| 38 # If set and set to true, then use jumbo compile even when it is |
| 39 # globally disabled. Otherwise it has no effect. |
| 40 # |
| 41 # never_build_jumbo |
| 42 # If set and set to true, then do not jumbo compile even if it is |
| 43 # globally enabled. Otherwise it has no effect. |
| 44 # |
| 45 # jumbo_excluded_sources |
| 46 # If set to a list of files, those files will not be merged with |
| 47 # the rest. This can be necessary if merging the files causes |
| 48 # compilation issues and fixing the issues is impractical. |
| 49 template("jumbo_target") { |
| 50 use_jumbo_build_for_target = use_jumbo_build |
| 51 if (defined(invoker.always_build_jumbo) && invoker.always_build_jumbo) { |
| 52 use_jumbo_build_for_target = true |
| 53 } |
| 54 if (defined(invoker.never_build_jumbo) && invoker.never_build_jumbo) { |
| 55 use_jumbo_build_for_target = false |
| 56 } |
| 57 if (target_name == jumbo_build_excluded) { |
| 58 use_jumbo_build_for_target = false |
| 59 } |
| 60 |
| 61 excluded_sources = [] |
| 62 if (defined(invoker.jumbo_excluded_sources)) { |
| 63 excluded_sources += invoker.jumbo_excluded_sources |
| 64 } |
| 65 |
| 66 invoker_sources = invoker.sources |
| 67 gen_target_dir = get_path_info(invoker_sources[0], "gen_dir") |
| 68 assert(excluded_sources != [] || true) # Prevent "unused variable". |
| 69 assert(gen_target_dir != "") # Prevent "unused variable". |
| 70 |
| 71 if (use_jumbo_build_for_target) { |
| 72 jumbo_files = [] |
| 73 |
| 74 # Split the sources list into chunks that are not excessively large |
| 75 files_per_chunk = jumbo_file_merge_limit |
| 76 current_file_index = 0 |
| 77 next_chunk_start = 0 |
| 78 next_chunk_number = 1 |
| 79 foreach(source_file, invoker.sources) { |
| 80 if (current_file_index == next_chunk_start) { |
| 81 jumbo_files += [ "$gen_target_dir/" + target_name + "_jumbo_" + |
| 82 next_chunk_number + ".cc" ] |
| 83 next_chunk_number += 1 |
| 84 next_chunk_start += files_per_chunk |
| 85 } |
| 86 current_file_index += 1 |
| 87 } |
| 88 |
| 89 merge_action_name = target_name + "__jumbo_merge" |
| 90 |
| 91 # Create an action that calls a script that merges all the source files. |
| 92 action(merge_action_name) { |
| 93 script = "//build/config/merge_for_jumbo.py" |
| 94 response_file_contents = |
| 95 rebase_path(invoker.sources - excluded_sources, gen_target_dir) |
| 96 outputs = jumbo_files |
| 97 args = [ "--outputs" ] + rebase_path(outputs, root_build_dir) + |
| 98 [ "--file-list={{response_file_name}}" ] |
| 99 } |
| 100 } |
| 101 |
| 102 target_type = invoker.target_type |
| 103 if (use_jumbo_build_for_target && target_type == "split_static_library") { |
| 104 # Meaningless and also impossible if split_count > len(jumbo_files) |
| 105 target_type = "static_library" |
| 106 |
| 107 # Prevent "unused variable" warning. |
| 108 assert(!defined(invoker.split_count) || invoker.split_count > 0) |
| 109 } |
| 110 |
| 111 # Perform the actual operation, either on the original sources or |
| 112 # the sources post-jumbo merging. |
| 113 target(target_type, target_name) { |
| 114 deps = [] |
| 115 if (defined(invoker.deps)) { |
| 116 deps += invoker.deps |
| 117 } |
| 118 |
| 119 # Take everything else not handled above from the invoker. |
| 120 variables_to_not_forward = [ "deps" ] |
| 121 if (use_jumbo_build_for_target) { |
| 122 deps += [ ":" + merge_action_name ] |
| 123 variables_to_not_forward += [ "sources" ] |
| 124 assert(jumbo_files != []) |
| 125 sources = jumbo_files + excluded_sources |
| 126 |
| 127 # Need to keep the headers in sources so that dependency checks |
| 128 # work, and we need to keep Objective-C code since they |
| 129 # cannot be merged into a cc file (FIXME). |
| 130 foreach(source_file, invoker.sources) { |
| 131 source_ext = get_path_info(source_file, "extension") |
| 132 if (source_ext == "h" || source_ext == "mm") { |
| 133 sources += [ source_file ] |
| 134 } |
| 135 } |
| 136 } |
| 137 forward_variables_from(invoker, "*", variables_to_not_forward) |
| 138 } |
| 139 } |
| 140 |
| 141 set_defaults("jumbo_target") { |
| 142 # This sets the default list of configs when the content_source_set target |
| 143 # is defined. The default_compiler_configs comes from BUILDCONFIG.gn and |
| 144 # is the list normally applied to static libraries and source sets. |
| 145 configs = default_compiler_configs |
| 146 } |
OLD | NEW |