# 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("//build/config/features.gni")

declare_args() {
  if (is_android || is_ios) {
    cld2_table_size = 0  # Small, accurate tables
  } else {
    cld2_table_size = 2  # Larger, more accurate tables
  }
}

gypi_values = exec_script("//build/gypi_to_gn.py",
                          [ rebase_path("cld_2.gyp") ],
                          "scope",
                          [ "cld_2.gyp" ])

# This variable controls which dependency is resolved by the pass-through
# target 'cld2_platform_impl', and allows the embedder to choose which
# kind of CLD2 support is required at build time:
#
# - If the value is 'static', then the cld2_platform_impl target will depend
#   upon the cld2_static target
# - If the value is 'dynamic', then the cld2_platform_impl target will
#   depend upon the cld2_dynamic target.
#
# High-level targets for Chromium unit tests hard-code a dependency upon
# cld2_static because doing so makes sense for use cases that aren't
# affected by the loading of language detection data; however, most other
# targets (e.g. the final executables and interactive UI tests) should be
# linked against whatever the embedder needs.
#
# Maintainers:
# This value may be reasonably tweaked on a per-platform basis.
# Don't forget to update this file as well to match:
#   components/translate/content/browser/browser_cld_utils.cc
#   components/translate/content/renderer/renderer_cld_utils.cc
cld2_platform_support = "static"

config("cld2_data_warnings") {
  visibility = [ ":*" ]
  if (is_clang) {
    # The generated files don't have braces around subobject initializers.
    cflags = [ "-Wno-missing-braces" ]
  }
}

source_set("cld2_data") {
  sources = gypi_values.cld2_data_sources
  if (cld2_table_size == 0) {
    sources += gypi_values.cld2_data_smallest_sources
  } else if (cld2_table_size == 2) {
    sources += gypi_values.cld2_data_largest_sources
  }

  include_dirs = [
    "src/internal",
    "src/public",
  ]

  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.
    ":cld2_data_warnings",
  ]
}

# As in the corresponding gyp file, this just builds the core interfaces for
# CLD2. You must still declare a dependency on a specific data set, either
# cld2_dynamic or cld2_static.
source_set("cld_2") {
  sources = gypi_values.cld2_core_sources
  include_dirs = [
    "src/internal",
    "src/public",
  ]

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

source_set("cld2_platform_impl") {
  public_deps = []
  if (cld2_platform_support == "static") {
    public_deps += [ ":cld2_static" ]
  } else if (cld2_platform_support == "dynamic") {
    public_deps += [ ":cld2_dynamic" ]
  }
}

config("cld2_warnings") {
  if (is_clang) {
    cflags = [
      # cld_2 contains unused private fields.
      # https://code.google.com/p/cld2/issues/detail?id=37
      "-Wno-unused-private-field",

      # offsetmap.cc uses a char as a subscript.
      "-Wno-char-subscripts",
    ]
  }
}

static_library("cld2_static") {
  sources = gypi_values.cld2_core_impl_sources
  include_dirs = [
    "src/internal",
    "src/public",
  ]

  public_deps = [
    ":cld2_data",
    ":cld_2",
  ]
  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [
    "//build/config/compiler:no_chromium_code",
    ":cld2_warnings",
  ]
}

config("cld2_dynamic_mode_config") {
  defines = [ "CLD2_DYNAMIC_MODE" ]
}

static_library("cld2_dynamic") {
  sources = gypi_values.cld2_core_sources + gypi_values.cld2_core_impl_sources +
            gypi_values.cld2_dynamic_data_loader_sources
  include_dirs = [
    "src/internal",
    "src/public",
  ]

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

# Does not build on Windows, Android or iOS.
if (!is_win && !is_android && !is_ios) {
  executable("cld_2_dynamic_data_tool") {
    sources = [
      "src/internal/cld2_dynamic_data_extractor.cc",
      "src/internal/cld2_dynamic_data_extractor.h",
      "src/internal/cld2_dynamic_data_tool.cc",
    ]

    include_dirs = [
      "src/internal",
      "src/public",
    ]

    deps = [
      ":cld2_data",
      ":cld2_dynamic",
      "//build/config/sanitizers:deps",
    ]

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