# Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import("//third_party/blink/renderer/core/core_idl_files.gni") import("//third_party/blink/renderer/modules/modules_idl_files.gni") bindings_scripts_dir = get_path_info(".", "abspath") bindings_scripts_output_dir = "$root_gen_dir/third_party/blink/renderer/bindings/scripts" jinja_module_files = [ "//third_party/jinja2/__init__.py", "//third_party/markupsafe/__init__.py", # jinja2 dep ] idl_lexer_parser_files = get_path_info([ # PLY (Python Lex-Yacc) "//third_party/ply/lex.py", "//third_party/ply/yacc.py", # Web IDL lexer/parser (base parser) "//tools/idl_parser/idl_lexer.py", "//tools/idl_parser/idl_node.py", "//tools/idl_parser/idl_parser.py", # Blink IDL lexer/parser/constructor "blink_idl_lexer.py", "blink_idl_parser.py", ], "abspath") idl_compiler_files = get_path_info( [ "idl_compiler.py", # Blink IDL front end (ex-lexer/parser) "idl_definitions.py", "idl_reader.py", "idl_types.py", "idl_validator.py", "interface_dependency_resolver.py", # V8 code generator "code_generator.py", "code_generator_v8.py", "code_generator_web_agent_api.py", "v8_attributes.py", "v8_callback_function.py", "v8_callback_interface.py", "v8_dictionary.py", "v8_globals.py", "v8_interface.py", "v8_methods.py", "v8_types.py", "v8_union.py", "v8_utilities.py", "//third_party/blink/renderer/build/scripts/blinkbuild/name_style_converter.py", ], "abspath") web_idl_scripts = get_path_info([ "web_idl/argument.py", "web_idl/attribute.py", "web_idl/callback_function.py", "web_idl/collection.py", "web_idl/collector.py", "web_idl/constant.py", "web_idl/dictionary.py", "web_idl/ecma_script_types.py", "web_idl/enumeration.py", "web_idl/extended_attribute.py", "web_idl/idl_types.py", "web_idl/implements.py", "web_idl/interface.py", "web_idl/literal_token.py", "web_idl/namespace.py", "web_idl/operation.py", "web_idl/typedef.py", "web_idl/utilities.py", "web_idl/idl_definition_builder.py", ], "abspath") # Calls the compute_interfaces_info_individual script. # # Parameters: # sources = list of IDL files to pass as inputs # interfaces_info_file = output pickle file for interfaces info. # component_info_file = output pickle file for component wide info. # deps = dependencies template("compute_interfaces_info_individual") { action(target_name) { script = "$bindings_scripts_dir/compute_interfaces_info_individual.py" if (defined(invoker.visibility)) { visibility = invoker.visibility } inputs = [ "$bindings_scripts_dir/utilities.py" ] + invoker.sources outputs = [ invoker.interfaces_info_file, invoker.component_info_file, ] response_file_contents = rebase_path(invoker.sources, root_build_dir) args = [ "--cache-directory", rebase_path(bindings_scripts_output_dir, root_build_dir), "--idl-files-list", "{{response_file_name}}", "--interfaces-info-file", rebase_path(invoker.interfaces_info_file, root_build_dir), "--component-info-file", rebase_path(invoker.component_info_file, root_build_dir), ] deps = [ "//third_party/blink/renderer/bindings/scripts:cached_lex_yacc_tables" ] + invoker.deps } } # Calls generate_event_interfaces # # Parameters: # sources = A list of IDL files to process. # output_file = The .in file to write, relative to the blink_gen_dir. # suffix = (Optional) String to be passed to script via --suffix template("generate_event_interfaces") { action(target_name) { # Write the file list to a unique temp file to avoid blowing out the # command line length limit. idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp" write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir)) inputs = [ "//third_party/blink/renderer/bindings/scripts/utilities.py", idl_files_list, ] + invoker.sources output_file = "$root_gen_dir/third_party/blink/renderer/" + invoker.output_file outputs = [ output_file, ] script = "//third_party/blink/renderer/bindings/scripts/generate_event_interfaces.py" args = [ "--event-idl-files-list", rebase_path(idl_files_list, root_build_dir), "--event-interfaces-file", rebase_path(output_file, root_build_dir), ] if (defined(invoker.suffix)) { args += [ "--suffix", invoker.suffix, ] } } } # Runs the idl_compiler script over a list of sources. # # Parameters: # sources = list of IDL files to compile # output_dir = string containing the directory to put the output files. # output_name_suffix = a suffix after the basename of the output file names. # target_component = component to generate code for. template("idl_compiler") { output_dir = invoker.output_dir output_name_suffix = invoker.output_name_suffix # TODO(brettw): we used to add a "-S" before the script name to skip # "import site" to speed up startup. Figure out if we need this and do # something similar (not really expressible in GN now). _script = "//third_party/blink/renderer/bindings/scripts/idl_compiler.py" _inputs = idl_lexer_parser_files + idl_compiler_files # to be explicit (covered by parsetab) _inputs += [ "$bindings_scripts_output_dir/lextab.py", "$bindings_scripts_output_dir/parsetab.pickle", "$bindings_scripts_output_dir/cached_jinja_templates.stamp", "$bindings_dir/IDLExtendedAttributes.txt", # If the dependency structure or public interface info (e.g., # [ImplementedAs]) changes, we rebuild all files, since we're not # computing dependencies file-by-file in the build. # This data is generally stable. "$bindings_modules_output_dir/InterfacesInfoOverall.pickle", ] # Further, if any dependency (partial interface or implemented # interface) changes, rebuild everything, since every IDL potentially # depends on them, because we're not computing dependencies # file-by-file. # FIXME: This is too conservative, and causes excess rebuilds: # compute this file-by-file. http://crbug.com/341748 # This should theoretically just be the IDL files passed in. _inputs += core_all_dependency_idl_files + modules_all_dependency_idl_files _public_deps = [ "//third_party/blink/renderer/bindings/core:core_global_constructors_idls", # FIXME: should be interfaces_info_core (w/o modules) # http://crbug.com/358074 "//third_party/blink/renderer/bindings/modules:interfaces_info", "//third_party/blink/renderer/bindings/modules:modules_core_global_constructors_idls", "//third_party/blink/renderer/bindings/modules:modules_global_constructors_idls", "//third_party/blink/renderer/bindings/scripts:cached_jinja_templates", "//third_party/blink/renderer/bindings/scripts:cached_lex_yacc_tables", "//third_party/blink/renderer/core:generated_testing_idls", ] # Spawning a python process per IDL file is slow. Use a single action # instead (crbug.com/821256). action(target_name) { script = _script inputs = _inputs public_deps = _public_deps sources = invoker.sources outputs = [] foreach(_source, sources) { _name_part = get_path_info(_source, "name") outputs += [ "$output_dir/v8_${_name_part}${output_name_suffix}.cc", "$output_dir/v8_${_name_part}${output_name_suffix}.h", ] } idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp" write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir)) inputs += [ idl_files_list ] args = [ "--cache-dir", rebase_path(bindings_scripts_output_dir, root_build_dir), "--output-dir", rebase_path(output_dir, root_build_dir), "--info-dir", rebase_path("$bindings_output_dir", root_build_dir), "--target-component", invoker.target_component, "--read-idl-list-from-file", rebase_path(idl_files_list, root_build_dir), ] } } # Runs idl_compiler.py to generate IDL dictionary impl files, unions and # callback functions. # # Parameters: # dict_idls = a list of dictionary IDL files to process. the callback and # union IDL file names are already known and do not need to be # specified. # non_dict_outputs = a list of files generated from callback functions and # unions. the list of files generated from |dict_idls| is # added automatically and does not need to be specified. # non_dict_output_dir = the directory to put the non-dict output files. # target_component = component to generate code for template("idl_impl") { dictionary_impl_output_dir = "$root_gen_dir/third_party/blink/renderer/" action(target_name) { script = "//third_party/blink/renderer/bindings/scripts/idl_compiler.py" idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp" write_file(idl_files_list, rebase_path(invoker.dict_idls, root_build_dir)) inputs = idl_lexer_parser_files + idl_compiler_files # to be explicit (covered by parsetab) inputs += [ "$bindings_scripts_output_dir/lextab.py", "$bindings_scripts_output_dir/parsetab.pickle", "$bindings_scripts_output_dir/cached_jinja_templates.stamp", "$bindings_dir/IDLExtendedAttributes.txt", ] inputs += [ idl_files_list ] + invoker.dict_idls outputs = invoker.non_dict_outputs # Derive the names of the generated dictionary impl files. Contrary to # generated interfaces, callbacks and unions, these files go to # $root_gen_dir/third_party/blink/renderer/{core,modules}//.{cpp,h}. foreach(dict_idl, invoker.dict_idls) { rel_path = rebase_path(dict_idl, "//third_party/blink/renderer") impl_dir = get_path_info(rel_path, "dir") idl_name = get_path_info(rel_path, "name") outputs += [ "${dictionary_impl_output_dir}$impl_dir/$idl_name.cc", "${dictionary_impl_output_dir}$impl_dir/$idl_name.h", ] } args = [ "--cache-dir", rebase_path(bindings_scripts_output_dir, root_build_dir), "--output-dir", rebase_path(invoker.non_dict_output_dir, root_build_dir), "--impl-output-dir", rebase_path(dictionary_impl_output_dir, root_build_dir), "--info-dir", rebase_path("$bindings_output_dir", root_build_dir), "--target-component", invoker.target_component, "--generate-impl", rebase_path(idl_files_list, root_build_dir), ] deps = [ # FIXME: should be interfaces_info_core (w/o modules) # http://crbug.com/358074 "//third_party/blink/renderer/bindings/core:interfaces_info_individual_core", "//third_party/blink/renderer/bindings/modules:interfaces_info", "//third_party/blink/renderer/bindings/modules:interfaces_info_individual_modules", "//third_party/blink/renderer/bindings/scripts:cached_jinja_templates", "//third_party/blink/renderer/bindings/scripts:cached_lex_yacc_tables", ] } } # Calls the aggregate_generated_bindings script. # # Parameters: # sources = a list of source IDL files. # component = a name of directory for these files (one word, no slashes). # outputs = a name of file to write to. template("aggregate_generated_bindings") { action(target_name) { script = "//third_party/blink/renderer/bindings/scripts/aggregate_generated_bindings.py" inputs = invoker.sources outputs = invoker.outputs response_file_contents = rebase_path(inputs, root_build_dir) args = [ "--component", invoker.component, "{{response_file_name}}", ] args += rebase_path(outputs, root_build_dir) public_deps = invoker.public_deps } } # Calls the compute_global_objects script. # # Parameters: # sources = a list of source IDL files. # sources_generated = a list of generated pickle sources. # output_file = a pickle file to write to (need to specify directory) # template("compute_global_objects") { action(target_name) { script = "//third_party/blink/renderer/bindings/scripts/compute_global_objects.py" # Write the file list to a unique temp file to avoid blowing out the # command line length limit. idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp" write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir)) inputs = [ "//third_party/blink/renderer/bindings/scripts/utilities.py", idl_files_list, ] + invoker.sources_generated + invoker.sources outputs = [ invoker.output_file, ] args = [ "--idl-files-list", rebase_path(idl_files_list, root_build_dir), ] foreach(component, invoker.sources_generated) { args += [ "--global-objects-component-files", rebase_path(component, root_build_dir), ] } args += [ rebase_path(invoker.output_file, root_build_dir) ] deps = invoker.deps } } # Calls the generate_global_constructors script. # # Parameters: # sources = a list of source IDL files. # global_objects_file = a global objects file generated by compute_global_objects # interfaces = interfaces to generate global constructors for. # component = component to generate global constructors for. # output_dir = output directory to generate idl files and header files. # deps = dependencies # template("generate_global_constructors") { action(target_name) { script = "//third_party/blink/renderer/bindings/scripts/generate_global_constructors.py" # Write the file list to a unique temp file to avoid blowing out the # command line length limit. idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp" write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir)) inputs = [ "//third_party/blink/renderer/bindings/scripts/utilities.py", idl_files_list, invoker.global_objects_file, ] + invoker.sources args = [ "--idl-files-list", rebase_path(idl_files_list, root_build_dir), "--global-objects-file", rebase_path(invoker.global_objects_file, root_build_dir), "--", ] output_dir = invoker.output_dir component = invoker.component # generate outputs from invoker.interfaces and invoker.basenames. output_idl_files = [] output_header_files = [] # Need a variable due to a GN sytax restriction. We can't do "invoker.basenames[i]". basename_list = invoker.basenames i = 0 foreach(interface, invoker.interfaces) { basename = basename_list[i] args += [ interface ] output_idl_file = "$output_dir/${basename}_${component}_constructors.idl" args += [ rebase_path(output_idl_file, root_build_dir) ] output_idl_files += [ output_idl_file ] output_header_files += [ "$output_dir/${basename}_${component}_constructors.h" ] i += 1 } outputs = output_idl_files + output_header_files deps = invoker.deps } } # Calls the generate_origin_trial_features script. # # Parameters: # sources = a list of source IDL files. # component = component for which to generate origin trial feature bindings # ("core" or "modules") # output_dir = output directory to generate cpp file and header file. # deps = dependencies # template("generate_origin_trial_features") { action(target_name) { script = "//third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py" # Write the file list to a unique temp file to avoid blowing out the # command line length limit. idl_files_list = "$target_gen_dir/${target_name}_file_list.tmp" write_file(idl_files_list, rebase_path(invoker.sources, root_build_dir)) inputs = [ "//third_party/blink/renderer/bindings/scripts/utilities.py", "//third_party/blink/renderer/bindings/templates/origin_trial_features_for_${invoker.component}.cc.tmpl", "//third_party/blink/renderer/bindings/templates/origin_trial_features_for_${invoker.component}.h.tmpl", idl_files_list, ] + invoker.sources args = [ "--output-directory", rebase_path(invoker.output_dir, root_build_dir), "--info-dir", rebase_path("$bindings_output_dir", root_build_dir), "--cache-dir", rebase_path(bindings_scripts_output_dir, root_build_dir), "--target-component", invoker.component, "--idl-files-list", rebase_path(idl_files_list, root_build_dir), ] outputs = [ "${invoker.output_dir}/origin_trial_features_for_${invoker.component}.cc", "${invoker.output_dir}/origin_trial_features_for_${invoker.component}.h", ] # TODO: This should not always require modules; For core features, this # should be interfaces_info_core (w/o modules). This is the same issue as # above in the idl_compiler template. # http://crbug.com/358074 deps = invoker.deps + [ "//third_party/blink/renderer/bindings/modules:interfaces_info" ] } } template("generate_web_idl_collection") { action(target_name) { script = "${bindings_scripts_dir}/generate_web_idl_collection.py" output_dir = invoker.output_dir output_file_name = invoker.output output_path = "${output_dir}/${output_file_name}" inputs = [ script, "${bindings_scripts_dir}/utilities.py", ] + web_idl_scripts + invoker.sources outputs = [ output_path, ] # List input file names in a temporary file. response_file_contents = rebase_path(invoker.sources, root_build_dir) args = [ "--idl-list-file", "{{response_file_name}}", "--component", invoker.component, "--output", rebase_path(output_path, root_build_dir), ] } }