chromium/third_party/protobuf/BUILD.gn

# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/linux/gtk/gtk.gni")
import("//build/config/sanitizers/sanitizers.gni")

# Includes default args like 'enable_js_protobuf'.
import("proto_library.gni")
import("proto_sources.gni")
if (enable_js_protobuf) {
  import("//third_party/closure_compiler/compile_js.gni")
}

config("protobuf_config") {
  include_dirs = [ "src" ]
  defines = [
    "GOOGLE_PROTOBUF_NO_RTTI",
    "GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
    "GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
  ]
  if (!is_win) {
    defines += [ "HAVE_PTHREAD" ]
  }
}

config("protobuf_warnings") {
  cflags = []
  if (is_clang) {
    # protobuf-3 contains a few functions that are unused.
    cflags += [ "-Wno-unused-function" ]
  }
}

config("protoc_warnings") {
  cflags = []
  if (is_clang) {
    # Some generates contain a few fields that are not used.
    cflags += [ "-Wno-unused-private-field" ]
  }
}

if (is_component_build) {
  config("protobuf_use_dlls") {
    defines = [ "PROTOBUF_USE_DLLS" ]
  }
}

# This config should be applied to targets using generated code from the proto
# compiler. It sets up the include directories properly.
config("using_proto") {
  include_dirs = [
    "src",
    "$root_gen_dir/protoc_out",
  ]
}

config("allow_deprecated_proto_fields") {
  if (is_clang) {
    cflags = [ "-DPROTOBUF_ALLOW_DEPRECATED=1" ]
  }
}

protobuf_lite_cflags = []
if (is_win) {
  protobuf_lite_cflags = [
    "/wd4018",  # signed/unsigned mismatch in comparison
    "/wd4065",  # switch statement contains 'default' but no 'case' labels
    "/wd4146",  # unary minus operator applied to unsigned type
    "/wd4244",  # implicit conversion, possible loss of data
    "/wd4267",  # size_t to int truncation
    "/wd4291",  # no matching operator delete for a placement new.
    "/wd4305",  # double to float truncation
    "/wd4355",  # 'this' used in base member initializer list
    "/wd4506",  # no definition for inline function (protobuf issue #240)
    "/wd4715",  # not all control paths return a value (fixed in trunk)
  ]
}

component("protobuf_lite") {
  sources = protobuf_lite_sources + protobuf_headers

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [
    "//build/config/compiler:no_chromium_code",

    # Must be after no_chromium_code for warning flags to be ordered
    # correctly.
    ":protobuf_warnings",
  ]

  # Build protobuf_lite with full optimizations so Clang can optimize the
  # initializer out. See 0029-make-initializers-optimizable.patch.
  if (!is_debug && is_android) {
    configs -= [ "//build/config/compiler:default_optimization" ]
    configs += [ "//build/config/compiler:optimize_max" ]
  }

  # Remove coverage and Sanitizers other than ASan for a performance boost when
  # fuzzing. ASan can't be removed here because of a bug preventing unsanitized
  # code from using libc++, which protobuf_full uses.
  configs -= not_fuzzed_remove_nonasan_configs
  configs += [ "//build/config/sanitizers:not_fuzzed" ]

  if (is_win) {
    configs -= [ "//build/config/win:lean_and_mean" ]
  }

  public_configs = [ ":protobuf_config" ]

  if (is_android) {
    libs = [ "log" ]  # Used by src/google/protobuf/stubs/common.cc
  }

  cflags = protobuf_lite_cflags

  # Required for component builds. See http://crbug.com/172800.
  if (is_component_build) {
    public_configs += [ ":protobuf_use_dlls" ]
    defines = [ "LIBPROTOBUF_EXPORTS" ]
  }
}

# This is the full, heavy protobuf lib that's needed for c++ .protos that don't
# specify the LITE_RUNTIME option. The protocol compiler itself (protoc) falls
# into that category. Do not use in Chrome code.
static_library("protobuf_full") {
  if (defined(build_with_chromium) && build_with_chromium) {
    # Prevent people from depending on this outside our file.
    visibility = [
      ":*",

      # Used for testing protobuf generation.
      "//base/test:proto_test_support",

      # requires descriptors & reflection; testonly.
      "//third_party/libprotobuf-mutator:*",

      # Chromecast requires descriptors and reflection.
      "//chromecast/*",

      # libassistant requires descriptors and reflection for testing.
      "//libassistant/*",

      # Perfetto uses the full library for testing.
      "//third_party/perfetto/gn:protobuf_full",

      # Some tests inside ChromeOS need reflection to parse golden files.
      # Not included in production code.
      "//chrome/browser/ash/child_accounts/time_limit_consistency_test:usage_time_limit_unittests",

      # The protobuf-based SQLite and GPU fuzzers need protobuf_full and are not
      # included in Chrome.
      "//gpu:gl_lpm_fuzzer_proto",
      "//gpu:gl_lpm_fuzzer_proto_gen",
      "//gpu:gl_lpm_shader_to_string_unittest",
      "//testing/libfuzzer/fuzzers:command_buffer_lpm_fuzzer_proto",
      "//testing/libfuzzer/fuzzers:command_buffer_lpm_fuzzer_proto_gen",
      "//third_party/sqlite:sqlite3_lpm_corpus_gen",

      # The protobuf-based Mojo LPM fuzzer needs protobuf_full and is not included
      # in Chrome.
      "//mojo/public/tools/fuzzers:mojolpm",

      # The root store tool is not part of Chrome itself, and needs to parse
      # human-readable protobufs. Protobuf is stored in //net/cert however as
      # browser needs to be able to parse serialized protobuf (which is exposed
      # as a separate lite BUILD rule).
      "//net/cert:root_store_proto_full",

      # The spirv-fuzz fuzzer tool needs protobuf_full and is not included in
      # Chrome.
      "//third_party/spirv-tools/src:spirv-fuzz",
      "//third_party/spirv-tools/src:spvtools_fuzz",
      "//third_party/spirv-tools/src:spvtools_fuzz_proto",

      # Some fuzzers for tint need protobuf_full and are not included in Chrome.
      "//third_party/dawn/src/tint/*",

      # Dawn LPM Fuzzers
      "//third_party/dawn/src/dawn/fuzzers:dawn_lpm_proto",
      "//third_party/dawn/src/dawn/fuzzers:dawn_lpm_proto_gen",

      # The Cast Core gRPC generator tool.
      "//third_party/cast_core/public/src/build/chromium:cast_core_grpc_generator",
    ]
  }

  deps = [ "//third_party/zlib" ]

  # In component build, protobuf_full can't depend on protobuf_lite because
  # it uses non-PROTOBUF_EXPORT symbols; in non-component build, protobuf_full
  # must have protobuf_lite as a dependency instead of building
  # protobuf_lite_sources to avoid ODR violations in targets that link both.
  # See crbug.com/1338164.
  if (is_component_build) {
    sources = protobuf_lite_sources + protobuf_sources + protobuf_headers
  } else {
    sources = protobuf_sources + protobuf_headers
    deps += [ ":protobuf_lite" ]
  }

  if (is_android) {
    libs = [ "log" ]  # Used by src/google/protobuf/stubs/common.cc
  }

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [
    "//build/config/compiler:no_chromium_code",

    # Must be after no_chromium_code for warning flags to be ordered
    # correctly.
    ":protobuf_warnings",
  ]

  # Remove coverage and Sanitizers other than ASan for a performance boost when
  # fuzzing. ASan can't be removed here because of a bug preventing unsanitized
  # code from using libc++, which protobuf_full uses.
  configs -= not_fuzzed_remove_nonasan_configs
  configs += [ "//build/config/sanitizers:not_fuzzed" ]

  if (is_win) {
    configs -= [ "//build/config/win:lean_and_mean" ]
  }
  public_configs = [ ":protobuf_config" ]

  cflags = protobuf_lite_cflags

  defines = [ "HAVE_ZLIB" ]
}

# Only compile the compiler for the host architecture.
if (current_toolchain == host_toolchain) {
  # protoc compiler is separated into protoc library and executable targets to
  # support protoc plugins that need to link libprotoc, but not the main()
  # itself. See src/google/protobuf/compiler/plugin.h
  source_set("protoc_java") {
    sources = protoc_java_sources + protoc_java_headers
    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [
      "//build/config/compiler:no_chromium_code",

      # Must be after no_chromium_code for warning flags to be ordered
      # correctly.
      ":protobuf_warnings",
      ":protoc_warnings",
    ]

    public_configs = [ ":protobuf_config" ]

    cflags = protobuf_lite_cflags

    public_deps = [ ":protobuf_full" ]
  }
  source_set("protoc_python") {
    sources = protoc_python_sources + protoc_python_headers
    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [
      "//build/config/compiler:no_chromium_code",

      # Must be after no_chromium_code for warning flags to be ordered
      # correctly.
      ":protobuf_warnings",
      ":protoc_warnings",
    ]

    public_configs = [ ":protobuf_config" ]

    cflags = protobuf_lite_cflags

    public_deps = [ ":protobuf_full" ]
  }
  static_library("protoc_lib") {
    sources = protoc_sources + protoc_headers

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [
      "//build/config/compiler:no_chromium_code",

      # Must be after no_chromium_code for warning flags to be ordered
      # correctly.
      ":protobuf_warnings",
      ":protoc_warnings",
    ]
    if (is_win) {
      # This is defined internally, don't warn on duplicate.
      configs -= [ "//build/config/win:lean_and_mean" ]
    }

    public_configs = [ ":protobuf_config" ]

    cflags = protobuf_lite_cflags

    public_deps = [ ":protobuf_full" ]
    deps = [
      ":protoc_java",
      ":protoc_python",
    ]
  }

  executable("protoc") {
    sources = [ "src/google/protobuf/compiler/main.cc" ]

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]

    cflags = protobuf_lite_cflags

    deps = [
      ":protoc_lib",

      # Default manifest on Windows (a no-op elsewhere).
      "//build/win:default_exe_manifest",
    ]
    if (enable_js_protobuf) {
      deps += [ "//third_party/protobuf-javascript:protoc-gen-js" ]
    }
  }
}

google_python_dir = "$root_out_dir/pyproto/google"

copy("copy_google_protobuf") {
  # TODO(ncarter): protoc's python generator treats descriptor.proto
  # specially, but only when the input path is exactly
  # "google/protobuf/descriptor.proto".  I'm not sure how to execute a rule
  # from a different directory.  For now, use a manually-generated copy of
  # descriptor_pb2.py.
  sources = pyproto_sources + [ "python/google/protobuf/descriptor_pb2.py" ]
  outputs = [ "$google_python_dir/protobuf/{{source_file_part}}" ]
}

copy("copy_google_protobuf_internal") {
  sources = pyproto_internal_sources
  outputs = [ "$google_python_dir/protobuf/internal/{{source_file_part}}" ]
}

# Build time dependency for action rules.
group("py_proto") {
  public_deps = [
    ":copy_google_protobuf",
    ":copy_google_protobuf_internal",
  ]
}

# Runtime dependency if the target needs the python scripts.
group("py_proto_runtime") {
  deps = [ ":py_proto" ]

  # Targets that depend on this should depend on the copied data files.
  data = get_target_outputs(":copy_google_protobuf")
  data += get_target_outputs(":copy_google_protobuf_internal")
}

# JS protobuf library.
if (enable_js_protobuf) {
  js_library("js_proto") {
    sources = [
      "//third_party/google-closure-library/closure/goog/array/array.js",
      "//third_party/google-closure-library/closure/goog/asserts/asserts.js",
      "//third_party/google-closure-library/closure/goog/base.js",
      "//third_party/google-closure-library/closure/goog/crypt/base64.js",
      "//third_party/google-closure-library/closure/goog/crypt/crypt.js",
      "//third_party/google-closure-library/closure/goog/debug/error.js",
      "//third_party/google-closure-library/closure/goog/dom/asserts.js",
      "//third_party/google-closure-library/closure/goog/dom/browserfeature.js",
      "//third_party/google-closure-library/closure/goog/dom/dom.js",
      "//third_party/google-closure-library/closure/goog/dom/htmlelement.js",
      "//third_party/google-closure-library/closure/goog/dom/nodetype.js",
      "//third_party/google-closure-library/closure/goog/dom/safe.js",
      "//third_party/google-closure-library/closure/goog/dom/tagname.js",
      "//third_party/google-closure-library/closure/goog/dom/tags.js",
      "//third_party/google-closure-library/closure/goog/fs/blob.js",
      "//third_party/google-closure-library/closure/goog/fs/url.js",
      "//third_party/google-closure-library/closure/goog/functions/functions.js",
      "//third_party/google-closure-library/closure/goog/goog.js",
      "//third_party/google-closure-library/closure/goog/html/safehtml.js",
      "//third_party/google-closure-library/closure/goog/html/safescript.js",
      "//third_party/google-closure-library/closure/goog/html/safestyle.js",
      "//third_party/google-closure-library/closure/goog/html/safestylesheet.js",
      "//third_party/google-closure-library/closure/goog/html/safeurl.js",
      "//third_party/google-closure-library/closure/goog/html/trustedresourceurl.js",
      "//third_party/google-closure-library/closure/goog/html/trustedtypes.js",
      "//third_party/google-closure-library/closure/goog/html/uncheckedconversions.js",
      "//third_party/google-closure-library/closure/goog/i18n/bidi.js",
      "//third_party/google-closure-library/closure/goog/labs/useragent/browser.js",
      "//third_party/google-closure-library/closure/goog/labs/useragent/engine.js",
      "//third_party/google-closure-library/closure/goog/labs/useragent/platform.js",
      "//third_party/google-closure-library/closure/goog/labs/useragent/useragent.js",
      "//third_party/google-closure-library/closure/goog/labs/useragent/util.js",
      "//third_party/google-closure-library/closure/goog/math/coordinate.js",
      "//third_party/google-closure-library/closure/goog/math/math.js",
      "//third_party/google-closure-library/closure/goog/math/size.js",
      "//third_party/google-closure-library/closure/goog/memoize/memoize.js",
      "//third_party/google-closure-library/closure/goog/object/object.js",
      "//third_party/google-closure-library/closure/goog/reflect/reflect.js",
      "//third_party/google-closure-library/closure/goog/string/const.js",
      "//third_party/google-closure-library/closure/goog/string/internal.js",
      "//third_party/google-closure-library/closure/goog/string/string.js",
      "//third_party/google-closure-library/closure/goog/string/typedstring.js",
      "//third_party/google-closure-library/closure/goog/useragent/product.js",
      "//third_party/google-closure-library/closure/goog/useragent/useragent.js",
      "//third_party/protobuf-javascript/src/asserts.js",
      "//third_party/protobuf-javascript/src/binary/arith.js",
      "//third_party/protobuf-javascript/src/binary/constants.js",
      "//third_party/protobuf-javascript/src/binary/decoder.js",
      "//third_party/protobuf-javascript/src/binary/encoder.js",
      "//third_party/protobuf-javascript/src/binary/reader.js",
      "//third_party/protobuf-javascript/src/binary/utils.js",
      "//third_party/protobuf-javascript/src/binary/writer.js",
      "//third_party/protobuf-javascript/src/map.js",
      "//third_party/protobuf-javascript/src/message.js",
    ]
  }
}