OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 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 # Generates a header with preprocessor defines specified by the build file. |
| 6 # The GYP version of this (with instructions) is build/buildflag_header.gypi. |
| 7 # |
| 8 # The flags are converted to function-style defines with mangled names and |
| 9 # code uses an accessor macro to access the values. This is to try to |
| 10 # minimize bugs where code checks whether something is defined or not, and |
| 11 # the proper header isn't included, meaning the answer will always be silently |
| 12 # false or might vary across the code base. |
| 13 # |
| 14 # In the GN template, specify build flags in the template as a list |
| 15 # of strings that encode key/value pairs like this: |
| 16 # |
| 17 # flags = [ "ENABLE_FOO=1", "ENABLE_BAR=$enable_bar" ] |
| 18 # |
| 19 # The GN values "true" and "false" will be mapped to 0 and 1 for boolean |
| 20 # #if flags to be expressed naturally. This means you can't directly make a |
| 21 # define that generates C++ value of true or false for use in code. If you |
| 22 # REALLY need this, you can also use the string "(true)" and "(false)" to |
| 23 # prevent the rewriting. |
| 24 |
| 25 # To check the value of the flag in C code: |
| 26 # |
| 27 # #include "path/to/here/header_file.h" |
| 28 # |
| 29 # #if BUILDFLAG(ENABLE_FOO) |
| 30 # ... |
| 31 # #endif |
| 32 # |
| 33 # const char kSpamServerUrl[] = BUILDFLAG(SPAM_SERVER_URL); |
| 34 # |
| 35 # There will no #define called ENABLE_FOO so if you accidentally test for that |
| 36 # in an ifdef it will always be negative. |
| 37 # |
| 38 # |
| 39 # Template parameters |
| 40 # |
| 41 # flags [required, list of strings] |
| 42 # Flag values as described above. |
| 43 # |
| 44 # header [required, string] |
| 45 # File name for generated header. By default, this will go in the |
| 46 # generated file directory for this target, and you would include it |
| 47 # with: |
| 48 # #include "<path_to_this_BUILD_file>/<header>" |
| 49 # |
| 50 # header_dir [optional, string] |
| 51 # Override the default location of the generated header. The string will |
| 52 # be treated as a subdirectory of the root_gen_dir. For example: |
| 53 # header_dir = "foo/bar" |
| 54 # Then you can include the header as: |
| 55 # #include "foo/bar/baz.h" |
| 56 # |
| 57 # deps, public_deps, testonly, visibility |
| 58 # Normal meaning. |
| 59 # |
| 60 # |
| 61 # Grit defines |
| 62 # |
| 63 # If one .grd file uses a flag, just add to the grit target: |
| 64 # |
| 65 # defines = [ |
| 66 # "enable_doom_melon=$enable_doom_melon", |
| 67 # ] |
| 68 # |
| 69 # If multiple .grd files use it, you'll want to put the defines in a .gni file |
| 70 # so it can be shared. Generally this .gni file should include all grit defines |
| 71 # for a given module (for some definition of "module"). Then do: |
| 72 # |
| 73 # defines = ui_grit_defines |
| 74 # |
| 75 # If you forget to do this, the flag will be implicitly false in the .grd file |
| 76 # and those resources won't be compiled. You'll know because the resource |
| 77 # #define won't be generated and any code that uses it won't compile. If you |
| 78 # see a missing IDS_* string, this is probably the reason. |
| 79 # |
| 80 # |
| 81 # Example |
| 82 # |
| 83 # buildflag_header("foo_features") { |
| 84 # header = "foo_features.h" |
| 85 # |
| 86 # flags = [ |
| 87 # # This uses the GN build flag enable_doom_melon as the definition. |
| 88 # "ENABLE_DOOM_MELON=$enable_doom_melon", |
| 89 # |
| 90 # # This force-enables the flag. |
| 91 # "ENABLE_SPACE_LASER=true", |
| 92 # |
| 93 # # This will expand to the quoted C string when used in source code. |
| 94 # "SPAM_SERVER_URL=\"http://www.example.com/\"", |
| 95 # ] |
| 96 # } |
| 97 template("buildflag_header") { |
| 98 action(target_name) { |
| 99 script = "//build/write_buildflag_header.py" |
| 100 |
| 101 if (defined(invoker.header_dir)) { |
| 102 header_file = "${invoker.header_dir}/${invoker.header}" |
| 103 } else { |
| 104 # Compute the path from the root to this file. |
| 105 header_file = rebase_path(".", "//") + "/${invoker.header}" |
| 106 } |
| 107 |
| 108 outputs = [ |
| 109 "$root_gen_dir/$header_file", |
| 110 ] |
| 111 |
| 112 # Always write --flags to the file so it's not empty. Empty will confuse GN |
| 113 # into thinking the response file isn't used. |
| 114 response_file_contents = [ "--flags" ] |
| 115 if (defined(invoker.flags)) { |
| 116 response_file_contents += invoker.flags |
| 117 } |
| 118 |
| 119 args = [ |
| 120 "--output", |
| 121 header_file, # Not rebased, Python script puts it inside gen-dir. |
| 122 "--rulename", |
| 123 get_label_info(":$target_name", "label_no_toolchain"), |
| 124 "--gen-dir", |
| 125 rebase_path(root_gen_dir, root_out_dir), |
| 126 "--definitions", |
| 127 "{{response_file_name}}", |
| 128 ] |
| 129 |
| 130 forward_variables_from(invoker, |
| 131 [ |
| 132 "deps", |
| 133 "public_deps", |
| 134 "testonly", |
| 135 "visibility", |
| 136 ]) |
| 137 } |
| 138 } |
OLD | NEW |