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