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# visibility (optional) 53 54template("midl") { 55 action_name = "${target_name}_idl_action" 56 source_set_name = target_name 57 58 assert(defined(invoker.sources), "Source must be defined for $target_name") 59 60 if (defined(invoker.out_dir)) { 61 out_dir = invoker.out_dir 62 } else { 63 out_dir = target_gen_dir 64 } 65 66 if (defined(invoker.generated_dir)) { 67 generated_dir = rebase_path(invoker.generated_dir, root_build_dir) 68 } else { 69 # midl.py expects 'gen' to be replaced with 'midl'. 70 generated_dir = 71 rebase_path("//third_party/win_build_output", root_build_dir) + 72 "/midl/" + rebase_path(out_dir, root_gen_dir) 73 } 74 75 if (defined(invoker.dynamic_guids)) { 76 dynamic_guids = invoker.dynamic_guids 77 } else { 78 dynamic_guids = "none" 79 } 80 81 if (defined(invoker.header_file)) { 82 header_file = invoker.header_file 83 } else { 84 header_file = "{{source_name_part}}.h" 85 } 86 87 if (defined(invoker.writes_tlb)) { 88 writes_tlb = invoker.writes_tlb 89 } else { 90 writes_tlb = false 91 } 92 93 if (defined(invoker.writes_proxy)) { 94 writes_proxy = invoker.writes_proxy 95 } else { 96 writes_proxy = true 97 } 98 99 if (defined(invoker.writes_dlldata)) { 100 writes_dlldata = invoker.writes_dlldata 101 } else { 102 writes_dlldata = true 103 } 104 105 if (writes_tlb) { 106 type_library_file = "{{source_name_part}}.tlb" 107 } else { 108 type_library_file = "none" 109 } 110 111 if (writes_dlldata) { 112 dlldata_file = "{{source_name_part}}.dlldata.c" 113 } else { 114 dlldata_file = "none" 115 } 116 117 if (writes_proxy) { 118 proxy_file = "{{source_name_part}}_p.c" 119 } else { 120 proxy_file = "none" 121 } 122 123 interface_identifier_file = "{{source_name_part}}_i.c" 124 125 action_foreach(action_name) { 126 visibility = [ ":$source_set_name" ] 127 script = "//build/toolchain/win/midl.py" 128 129 sources = invoker.sources 130 131 outputs = [ 132 "$out_dir/$header_file", 133 "$out_dir/$interface_identifier_file", 134 ] 135 136 # These files are only added to outputs if the invoker so desires, as it 137 # they are not always generated depending on the content of the input idl 138 # file. 139 if (writes_tlb) { 140 outputs += [ "$out_dir/$type_library_file" ] 141 } 142 if (writes_dlldata) { 143 outputs += [ "$out_dir/$dlldata_file" ] 144 } 145 if (writes_proxy) { 146 outputs += [ "$out_dir/$proxy_file" ] 147 } 148 149 if (current_cpu == "x86") { 150 win_tool_arch = "environment.x86" 151 idl_target_platform = "win32" 152 } else if (current_cpu == "x64") { 153 win_tool_arch = "environment.x64" 154 idl_target_platform = "x64" 155 } else if (current_cpu == "arm64") { 156 win_tool_arch = "environment.arm64" 157 idl_target_platform = "arm64" 158 } else { 159 assert(false, "Need environment for this arch") 160 } 161 162 args = [ 163 win_tool_arch, 164 generated_dir, 165 rebase_path(out_dir, root_build_dir), 166 dynamic_guids, 167 type_library_file, 168 header_file, 169 dlldata_file, 170 interface_identifier_file, 171 proxy_file, 172 rebase_path("//third_party/llvm-build/Release+Asserts/bin/clang-cl.exe", 173 root_build_dir), 174 "{{source}}", 175 "/char", 176 "signed", 177 "/env", 178 idl_target_platform, 179 "/Oicf", 180 ] 181 182 if (defined(invoker.defines)) { 183 foreach(define, invoker.defines) { 184 args += [ "/D" + define ] 185 } 186 } 187 188 forward_variables_from(invoker, [ "deps" ]) 189 } 190 191 source_set(target_name) { 192 forward_variables_from(invoker, [ "visibility" ]) 193 194 # We only compile the IID files from the IDL tool rather than all outputs. 195 sources = process_file_template(invoker.sources, 196 [ "$out_dir/$interface_identifier_file" ]) 197 198 public_deps = [ ":$action_name" ] 199 } 200} 201