1# Copyright 2014 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 5assert(is_win) 6 7import("//build/config/win/visual_studio_version.gni") 8 9# This template defines a rule to invoke the MS IDL compiler. The generated 10# source code will be compiled and linked into targets that depend on this. 11# 12# Parameters 13# 14# sources 15# List of .idl file to process. 16# 17# header_file (optional) 18# File name of generated header file. Defaults to the basename of the 19# source idl file with a .h extension. 20# 21# out_dir (optional) 22# Directory to write the generated files to. Defaults to target_gen_dir. 23# 24# generated_dir (optional) 25# Directory where generated files were previously persisted. 26# Defaults to third_party\win_build_output\midl\|out_dir|. 27# 28# dynamic_guids (optional) 29# If the GUIDs are not constant across builds, the current GUID 30# substitutions. 31# |dynamic_guids| is of the form: 32# "PLACEHOLDER-GUID-158428a4-6014-4978-83ba-9fad0dabe791=" 33# "3d852661-c795-4d20-9b95-5561e9a1d2d9," 34# "PLACEHOLDER-GUID-63B8FFB1-5314-48C9-9C57-93EC8BC6184B=" 35# "D0E1CACC-C63C-4192-94AB-BF8EAD0E3B83". 36# See midl.py for more details. 37# 38# writes_tlb (optional) 39# Whether a .tlb file should be added to outputs. Defaults to false. 40# 41# writes_proxy(optional) 42# Whether a _p.c file should be added to outputs. Defaults to true. 43# 44# writes_dlldata(optional) 45# Whether a .dlldata.c file should be added to outputs. Defaults to true. 46# 47# deps (optional) 48# 49# defines (optional) 50# Build time defines to be passed to midl.exe as /D parameter. 51# 52# testonly (optional) 53# 54# visibility (optional) 55 56template("midl") { 57 action_name = "${target_name}_idl_action" 58 source_set_name = target_name 59 60 assert(defined(invoker.sources), "Source must be defined for $target_name") 61 62 if (defined(invoker.out_dir)) { 63 out_dir = invoker.out_dir 64 } else { 65 out_dir = target_gen_dir 66 } 67 68 if (defined(invoker.generated_dir)) { 69 generated_dir = rebase_path(invoker.generated_dir, root_build_dir) 70 } else { 71 # midl.py expects 'gen' to be replaced with 'midl'. 72 generated_dir = 73 rebase_path("//third_party/win_build_output", root_build_dir) + 74 "/midl/" + rebase_path(out_dir, root_gen_dir) 75 } 76 77 if (defined(invoker.dynamic_guids)) { 78 dynamic_guids = invoker.dynamic_guids 79 } else { 80 dynamic_guids = "none" 81 } 82 83 if (defined(invoker.header_file)) { 84 header_file = invoker.header_file 85 } else { 86 header_file = "{{source_name_part}}.h" 87 } 88 89 if (defined(invoker.writes_tlb)) { 90 writes_tlb = invoker.writes_tlb 91 } else { 92 writes_tlb = false 93 } 94 95 if (defined(invoker.writes_proxy)) { 96 writes_proxy = invoker.writes_proxy 97 } else { 98 writes_proxy = true 99 } 100 101 if (defined(invoker.writes_dlldata)) { 102 writes_dlldata = invoker.writes_dlldata 103 } else { 104 writes_dlldata = true 105 } 106 107 if (writes_tlb) { 108 type_library_file = "{{source_name_part}}.tlb" 109 } else { 110 type_library_file = "none" 111 } 112 113 if (writes_dlldata) { 114 dlldata_file = "{{source_name_part}}.dlldata.c" 115 } else { 116 dlldata_file = "none" 117 } 118 119 if (writes_proxy) { 120 proxy_file = "{{source_name_part}}_p.c" 121 } else { 122 proxy_file = "none" 123 } 124 125 interface_identifier_file = "{{source_name_part}}_i.c" 126 127 action_foreach(action_name) { 128 visibility = [ ":$source_set_name" ] 129 script = "//build/toolchain/win/midl.py" 130 131 sources = invoker.sources 132 133 outputs = [ 134 "$out_dir/$header_file", 135 "$out_dir/$interface_identifier_file", 136 ] 137 138 # These files are only added to outputs if the invoker so desires, as it 139 # they are not always generated depending on the content of the input idl 140 # file. 141 if (writes_tlb) { 142 outputs += [ "$out_dir/$type_library_file" ] 143 } 144 if (writes_dlldata) { 145 outputs += [ "$out_dir/$dlldata_file" ] 146 } 147 if (writes_proxy) { 148 outputs += [ "$out_dir/$proxy_file" ] 149 } 150 151 if (current_cpu == "x86") { 152 win_tool_arch = "environment.x86" 153 idl_target_platform = "win32" 154 } else if (current_cpu == "x64") { 155 win_tool_arch = "environment.x64" 156 idl_target_platform = "x64" 157 } else if (current_cpu == "arm64") { 158 win_tool_arch = "environment.arm64" 159 idl_target_platform = "arm64" 160 } else { 161 assert(false, "Need environment for this arch") 162 } 163 164 args = [ 165 win_tool_arch, 166 generated_dir, 167 rebase_path(out_dir, root_build_dir), 168 dynamic_guids, 169 type_library_file, 170 header_file, 171 dlldata_file, 172 interface_identifier_file, 173 proxy_file, 174 rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang-cl.exe", 175 root_build_dir), 176 "{{source}}", 177 "/char", 178 "signed", 179 "/env", 180 idl_target_platform, 181 "/Oicf", 182 ] 183 184 if (defined(invoker.defines)) { 185 foreach(define, invoker.defines) { 186 args += [ "/D" + define ] 187 } 188 } 189 190 forward_variables_from(invoker, 191 [ 192 "deps", 193 "testonly", 194 ]) 195 } 196 197 source_set(target_name) { 198 forward_variables_from(invoker, 199 [ 200 "testonly", 201 "visibility", 202 ]) 203 204 # We only compile the IID files from the IDL tool rather than all outputs. 205 sources = process_file_template(invoker.sources, 206 [ "$out_dir/$interface_identifier_file" ]) 207 208 public_deps = [ ":$action_name" ] 209 } 210} 211