# 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. mojom_generator_root = "//mojo/public/tools/bindings" mojom_generator_script = "$mojom_generator_root/mojom_bindings_generator.py" mojom_generator_sources = [ "$mojom_generator_root/generators/mojom_cpp_generator.py", "$mojom_generator_root/generators/mojom_js_generator.py", "$mojom_generator_root/generators/mojom_java_generator.py", "$mojom_generator_root/pylib/mojom/__init__.py", "$mojom_generator_root/pylib/mojom/error.py", "$mojom_generator_root/pylib/mojom/generate/__init__.py", "$mojom_generator_root/pylib/mojom/generate/constant_resolver.py", "$mojom_generator_root/pylib/mojom/generate/data.py", "$mojom_generator_root/pylib/mojom/generate/generator.py", "$mojom_generator_root/pylib/mojom/generate/module.py", "$mojom_generator_root/pylib/mojom/generate/pack.py", "$mojom_generator_root/pylib/mojom/generate/template_expander.py", "$mojom_generator_root/pylib/mojom/parse/__init__.py", "$mojom_generator_root/pylib/mojom/parse/ast.py", "$mojom_generator_root/pylib/mojom/parse/lexer.py", "$mojom_generator_root/pylib/mojom/parse/parser.py", "$mojom_generator_root/pylib/mojom/parse/translate.py", "$mojom_generator_script", ] if (!is_ios) { _bindings_configuration_files = [ "//mojo/public/tools/bindings/chromium_bindings_configuration.gni", "//mojo/public/tools/bindings/blink_bindings_configuration.gni", ] } else { _bindings_configuration_files = [ "//mojo/public/tools/bindings/chromium_bindings_configuration.gni" ] } _bindings_configurations = [] foreach(config_file, _bindings_configuration_files) { _bindings_configurations += [ read_file(config_file, "scope") ] } foreach(configuration, _bindings_configurations) { foreach(typemap, configuration.typemaps) { # Check that the mojom field of each typemap refers to a mojom that exists. read_file(typemap.mojom, "") } } # Generate C++/JavaScript/Java source files from mojom files. The output files # will go under the generated file directory tree with the same path as each # input file. # # Parameters: # # sources (optional if one of the deps sets listed below is present) # List of source .mojom files to compile. # # deps (optional) # Note: this can contain only other mojom targets. # # DEPRECATED: This is synonymous with public_deps because all mojom # dependencies must be public by design. Please use public_deps. # # public_deps (optional) # Note: this can contain only other mojom targets. # # import_dirs (optional) # List of import directories that will get added when processing sources. # # testonly (optional) # # visibility (optional) # # use_new_wrapper_types (optional) # If set to true, mojom array/map/string will be mapped to STL (for # chromium variant) or WTF (for blink) types. Otherwise, they will be # mapped to mojo::Array/Map/String/etc. # Default value is false. # TODO(yzshen): # - flip the flag and make use_new_wrapper_types=true the default; # - convert all users to use the new mode; # - remove support for the old mode. template("mojom") { assert( defined(invoker.sources) || defined(invoker.deps) || defined(invoker.public_deps), "\"sources\" or \"deps\" must be defined for the $target_name template.") all_deps = [] if (defined(invoker.deps)) { all_deps += invoker.deps } if (defined(invoker.public_deps)) { all_deps += invoker.public_deps } group("${target_name}__is_mojom") { } # Explicitly ensure that all dependencies (invoker.deps and # invoker.public_deps) are mojom targets. group("${target_name}__check_deps_are_all_mojom") { deps = [] foreach(d, all_deps) { name = get_label_info(d, "label_no_toolchain") toolchain = get_label_info(d, "toolchain") deps += [ "${name}__is_mojom(${toolchain})" ] } } foreach(bindings_configuration, _bindings_configurations) { cpp_only = false variant_suffix = "" if (defined(bindings_configuration.variant)) { variant = bindings_configuration.variant variant_suffix = "_${variant}" cpp_only = true } type_mappings_target_name = "${target_name}${variant_suffix}__type_mappings" type_mappings_path = "$target_gen_dir/${target_name}${variant_suffix}__type_mappings" active_typemaps = [] cpp_sources_suffix = "cpp_sources" cpp_sources_target_name = "${target_name}${variant_suffix}_${cpp_sources_suffix}" enabled_sources = [] if (defined(invoker.sources)) { generator_cpp_outputs = [] generator_js_outputs = [] generator_java_outputs = [] variant_dash_suffix = "" if (defined(variant)) { variant_dash_suffix = "-${variant}" } generator_cpp_outputs += [ "{{source_gen_dir}}/{{source_name_part}}.mojom${variant_dash_suffix}.cc", "{{source_gen_dir}}/{{source_name_part}}.mojom${variant_dash_suffix}.h", "{{source_gen_dir}}/{{source_name_part}}.mojom${variant_dash_suffix}-internal.h", ] enabled_sources = [] if (defined(bindings_configuration.blacklist)) { foreach(source, invoker.sources) { blacklisted = false foreach(blacklisted_source, bindings_configuration.blacklist) { if (get_path_info(source, "abspath") == blacklisted_source) { blacklisted = true } } if (!blacklisted) { enabled_sources += [ source ] } } } else { enabled_sources = invoker.sources } foreach(source, enabled_sources) { # TODO(sammc): Use a map instead of a linear scan when GN supports maps. foreach(typemap, bindings_configuration.typemaps) { if (get_path_info(source, "abspath") == typemap.mojom) { active_typemaps += [ typemap ] } } } if (!cpp_only) { generator_js_outputs = [ "{{source_gen_dir}}/{{source_name_part}}.mojom.js" ] generator_java_outputs = [ "{{source_gen_dir}}/{{source_name_part}}.mojom.srcjar" ] } generator_target_name = "${target_name}${variant_suffix}__generator" action_foreach(generator_target_name) { script = mojom_generator_script inputs = mojom_generator_sources sources = invoker.sources deps = [ ":$type_mappings_target_name", "//mojo/public/tools/bindings:precompile_templates", ] outputs = generator_cpp_outputs + generator_java_outputs + generator_js_outputs args = [ "--use_bundled_pylibs", "generate", "{{source}}", "-d", rebase_path("//", root_build_dir), "-I", rebase_path("//", root_build_dir), "-o", rebase_path(root_gen_dir), "--bytecode_path", rebase_path("$root_gen_dir/mojo/public/tools/bindings"), ] if (defined(invoker.import_dirs)) { foreach(import_dir, invoker.import_dirs) { args += [ "-I", rebase_path(import_dir, root_build_dir), ] } } if (cpp_only) { args += [ "-g", "c++", ] } else { args += [ "-g", "c++,javascript,java", ] } if (defined(bindings_configuration.variant)) { args += [ "--variant", bindings_configuration.variant, ] } args += [ "--typemap", rebase_path(type_mappings_path, root_build_dir), ] if (defined(bindings_configuration.for_blink) && bindings_configuration.for_blink) { args += [ "--for_blink" ] } if (defined(invoker.use_new_wrapper_types) && invoker.use_new_wrapper_types) { args += [ "--use_new_wrapper_types" ] } } } action(type_mappings_target_name) { inputs = _bindings_configuration_files outputs = [ type_mappings_path, ] script = "$mojom_generator_root/generate_type_mappings.py" deps = [] args = [ "--output", rebase_path(type_mappings_path, root_build_dir), ] foreach(d, all_deps) { name = get_label_info(d, "label_no_toolchain") toolchain = get_label_info(d, "toolchain") dependency_output = "${name}${variant_suffix}__type_mappings" dependency_target = "${dependency_output}(${toolchain})" deps += [ dependency_target ] dependency_output_dir = get_label_info(dependency_output, "target_gen_dir") dependency_name = get_label_info(dependency_output, "name") dependency_path = rebase_path("$dependency_output_dir/${dependency_name}", root_build_dir) args += [ "--dependency", dependency_path, ] } if (enabled_sources != []) { # TODO(sammc): Pass the typemap description in a file to avoid command # line length limitations. typemap_description = [] foreach(typemap, active_typemaps) { typemap_description += [ "--start-typemap" ] if (defined(typemap.public_headers)) { foreach(value, typemap.public_headers) { typemap_description += [ "public_headers=$value" ] } } if (defined(typemap.traits_headers)) { foreach(value, typemap.traits_headers) { typemap_description += [ "traits_headers=$value" ] } } foreach(value, typemap.type_mappings) { typemap_description += [ "type_mappings=$value" ] } } args += typemap_description } } source_set("${target_name}${variant_suffix}") { if (defined(invoker.visibility)) { visibility = invoker.visibility } if (defined(invoker.testonly)) { testonly = invoker.testonly } if (defined(invoker.sources) && !defined(bindings_configuration.variant)) { data = process_file_template(enabled_sources, generator_js_outputs) } public_deps = [ ":${cpp_sources_target_name}", "//mojo/public/cpp/bindings", ] if (defined(invoker.deps)) { public_deps += invoker.deps } if (defined(invoker.public_deps)) { public_deps += invoker.public_deps } deps = [] if (defined(invoker.sources)) { public_deps += [ ":$generator_target_name" ] } } # The generated C++ source files. The main reason to introduce this target # is so that mojo/public/cpp/bindings can depend on mojom interfaces without # circular dependencies. It means that the target is missing the dependency # on mojo/public/cpp/bindings. No external targets should depend directly on # this target *except* mojo/public/cpp/bindings and other *_cpp_sources # targets. source_set(cpp_sources_target_name) { if (defined(invoker.testonly)) { testonly = invoker.testonly } if (enabled_sources != []) { sources = process_file_template(enabled_sources, generator_cpp_outputs) } deps = [ "//mojo/public/cpp/bindings:struct_traits", "//mojo/public/interfaces/bindings:bindings__generator", ] if (enabled_sources != []) { deps += [ ":$generator_target_name" ] } public_deps = [ "//base", ] foreach(d, all_deps) { # Resolve the name, so that a target //mojo/something becomes # //mojo/something:something and we can append cpp_sources_suffix to # get the cpp dependency name. full_name = get_label_info("$d", "label_no_toolchain") public_deps += [ "${full_name}${variant_suffix}_${cpp_sources_suffix}" ] } foreach(typemap, active_typemaps) { if (defined(typemap.public_headers)) { sources += typemap.public_headers } if (defined(typemap.traits_headers)) { sources += typemap.traits_headers } if (defined(typemap.sources)) { sources += typemap.sources } if (defined(typemap.public_deps)) { public_deps += typemap.public_deps } if (defined(typemap.deps)) { deps += typemap.deps } } if (defined(bindings_configuration.for_blink) && bindings_configuration.for_blink) { public_deps += [ "//mojo/public/cpp/bindings:wtf_support" ] } } if (!cpp_only && is_android) { import("//build/config/android/rules.gni") java_srcjar_target_name = target_name + "_java_sources" action(java_srcjar_target_name) { script = "//mojo/public/tools/gn/zip.py" inputs = [] if (enabled_sources != []) { inputs = process_file_template(enabled_sources, generator_java_outputs) } output = "$target_gen_dir/$target_name.srcjar" outputs = [ output, ] rebase_inputs = rebase_path(inputs, root_build_dir) rebase_output = rebase_path(output, root_build_dir) args = [ "--zip-inputs=$rebase_inputs", "--output=$rebase_output", ] deps = [] if (enabled_sources != []) { deps = [ ":$generator_target_name", ] } } java_target_name = target_name + "_java" android_library(java_target_name) { deps = [ "//base:base_java", "//mojo/public/java:bindings", "//mojo/public/java:system", ] foreach(d, all_deps) { # Resolve the name, so that a target //mojo/something becomes # //mojo/something:something and we can append "_java" to get the java # dependency name. full_name = get_label_info(d, "label_no_toolchain") deps += [ "${full_name}_java" ] } srcjar_deps = [ ":$java_srcjar_target_name" ] run_findbugs_override = false } } } }