• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/config/features.gni")
6import("//build/config/host_byteorder.gni")
7import("config.gni")
8import("sources.gni")
9
10if (is_android) {
11  import("//build/config/android/rules.gni")
12}
13
14if (is_mac && !icu_is_in_fuchsia) {
15  import("//build/config/sanitizers/sanitizers.gni")
16}
17
18assert(!icu_disable_thin_archive || !is_component_build,
19       "icu_disable_thin_archive only works in static library builds")
20
21# Meta target that includes both icuuc and icui18n. Most targets want both.
22# You can depend on the individually if you need to.
23group("icu") {
24  public_deps = [
25    ":icui18n",
26    ":icuuc",
27  ]
28}
29
30# Shared config used by ICU and all dependents.
31config("icu_config") {
32  defines = [
33    # Tell ICU to not insert |using namespace icu;| into its headers,
34    # so that chrome's source explicitly has to use |icu::|.
35    "U_USING_ICU_NAMESPACE=0",
36
37    # We don't use ICU plugins and dyload is only necessary for them.
38    # NaCl-related builds also fail looking for dlfcn.h when it's enabled.
39    "U_ENABLE_DYLOAD=0",
40
41    # v8/Blink need to know whether Chromium's copy of ICU is used or not.
42    "USE_CHROMIUM_ICU=1",
43
44    # Enable tracing to connect to UMA but disable tracing of resource
45    # to avoid performance issues.
46    "U_ENABLE_TRACING=1",
47    "U_ENABLE_RESOURCE_TRACING=0",
48  ]
49
50  if (!is_component_build) {
51    defines += [ "U_STATIC_IMPLEMENTATION" ]
52  }
53
54  include_dirs = [
55    "source/common",
56    "source/i18n",
57  ]
58
59  if (icu_use_data_file) {
60    defines += [ "ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE" ]
61  } else {
62    defines += [ "ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC" ]
63  }
64}
65
66# Config used only by ICU code.
67config("icu_code") {
68  cflags = []
69  defines = [
70    "HAVE_DLOPEN=0",
71
72    # Only build encoding coverters and detectors necessary for HTML5.
73    "UCONFIG_ONLY_HTML_CONVERSION=1",
74
75    "UCONFIG_USE_ML_PHRASE_BREAKING=1",
76
77    # TODO(jshin): do we still need this?
78    "UCONFIG_USE_WINDOWS_LCID_MAPPING_API=0",
79
80    # No dependency on the default platform encoding.
81    # Will cut down the code size.
82    "U_CHARSET_IS_UTF8=1",
83  ]
84
85  if (is_win) {
86    # Disable some compiler warnings.
87    cflags += [
88      "/wd4005",  # Macro redefinition.
89      "/wd4068",  # Unknown pragmas.
90      "/wd4267",  # Conversion from size_t on 64-bits.
91      "/utf-8",  # ICU source files are in UTF-8.
92    ]
93    if (!is_clang) {
94      cflags += [
95        # Ignore some msvc warnings here because V8 still supports msvc.
96        "/wd4244",  # Conversion: possible loss of data.
97      ]
98      defines += [
99        # https://crbug.com/1274247
100        # <ctgmath> is deprecated in C++17, but ICU still uses it, so we should
101        # silence the warning for now.
102        "_SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING",
103      ]
104    }
105  } else if (is_linux || is_chromeos || is_android || icu_is_in_fuchsia) {
106    cflags += [ "-Wno-unused-function" ]
107  }
108  if (is_clang) {
109    cflags += [
110      # ICU has some code with the pattern:
111      #   if (found = uprv_getWindowsTimeZoneInfo(...))
112      "-Wno-parentheses",
113
114      # ucnv2022.cpp contains three functions that are only used when
115      # certain preprocessor defines are set.
116      # unistr.cpp also has an unused function for non-component builds.
117      "-Wno-unused-function",
118
119      # putil.cpp contains unused variables when building for iOS simulators.
120      "-Wno-unused-variable",
121
122      # ICU has decided not to fix this warning as doing so would break its
123      # stable API.
124      "-Wno-ambiguous-reversed-operator",
125    ]
126  }
127  if (is_clang || is_linux || is_chromeos || is_android || icu_is_in_fuchsia) {
128    cflags += [
129      # ICU uses its own deprecated functions.
130      "-Wno-deprecated-declarations",
131    ]
132  }
133  if (icu_is_in_fuchsia) {
134    cflags += [
135      # Disable spurious thread safety errors in umutex.cpp
136      "-Wno-thread-safety",
137
138      # Can probably remove the below after
139      # https://unicode-org.atlassian.net/projects/ICU/issues/ICU-20869
140      # is fixed.
141      "-Wno-implicit-int-float-conversion",
142      "-Wno-conversion",
143
144      # Needed for C++20
145      "-Wno-ambiguous-reversed-operator",
146      "-Wno-rewrite-not-bool",
147      "-Wno-deprecated-anon-enum-enum-conversion",
148      "-Wno-deprecated-array-compare",
149      "-Wno-deprecated-pragma",
150
151      # Used for conditional changes to the compilation process that
152      # are only needed for the Fuchsia toolchain.
153      "-DICU_IS_IN_FUCHSIA",
154    ] + icu_fuchsia_extra_compile_flags
155  }
156  if (current_cpu == "wasm") {
157    # Tell ICU that we are a 32 bit platform, otherwise,
158    # double-conversion-utils.h doesn't know how to operate.
159    defines += [ "__i386__" ]
160  }
161}
162
163# Config used to set default visibility to hidden.
164config("visibility_hidden") {
165  cflags = []
166  if (is_mac || is_linux || is_chromeos || is_android || is_fuchsia) {
167    cflags += [ "-fvisibility=hidden" ]
168  }
169}
170
171template("generate_icu_component") {
172  if (icu_is_in_fuchsia) {
173    target(default_library_type, target_name) {
174      forward_variables_from(invoker,
175                             "*",
176                             [
177                               "testonly",
178                               "visibility",
179                             ])
180      assert(fuchsia_output_name_postfix == "")
181
182      # If icu_use_target_out_dir is defined and set, then the component
183      # will be output in the regular target_out_dir, rather than the default
184      # root_build_dir.
185      # See README.fuchsia for details.
186      if (defined(icu_use_target_out_dir) && icu_use_target_out_dir) {
187        output_dir = target_out_dir
188      }
189
190      # ICU uses RTTI, replace the default "no rtti" config (if applied).
191      configs += [
192        "//build/config:no_rtti",
193        "//build/config:symbol_visibility_hidden",
194      ]
195      configs -= [
196        "//build/config:no_rtti",
197        "//build/config:symbol_visibility_hidden",
198      ]
199
200      configs += [ "//build/config:rtti" ]
201
202      # These need to be applied after the main configs so the "-Wno-*" options
203      # take effect.
204      configs += [ ":icu_code" ]
205      configs += extra_configs
206      public_configs = [ ":icu_config" ]
207    }
208  } else {
209    component(target_name) {
210      forward_variables_from(invoker,
211                             "*",
212                             [
213                               "testonly",
214                               "visibility",
215                             ])
216
217      # If icu_use_target_output_dir is defined and set, then the component
218      # will be output in the regular target_out_dir, rather than the default
219      # root_build_dir.
220      # See README.fuchsia for details.
221      if (defined(icu_use_target_output_dir) && icu_use_target_output_dir) {
222        output_dir = target_out_dir
223      }
224
225      if (is_fuchsia) {
226        base_output_name = target_name
227        if (defined(invoker.output_name)) {
228          base_output_name = invoker.output_name
229        }
230
231        # Fuchsia puts its own libicu*.so in /system/lib where we need to put our
232        # .so when doing component builds, so we need to give this a different name.
233        output_name = "${base_output_name}_cr${fuchsia_output_name_postfix}"
234      } else {
235        assert(fuchsia_output_name_postfix == "")
236      }
237
238      # ICU uses RTTI, replace the default "no rtti" config (if applied).
239      configs += [
240        "//build/config/compiler:no_rtti",
241        "//build/config/compiler:chromium_code",
242      ]
243      configs -= [
244        "//build/config/compiler:no_rtti",
245        "//build/config/compiler:chromium_code",
246      ]
247      configs += [
248        "//build/config/compiler:rtti",
249        "//build/config/compiler:no_chromium_code",
250      ]
251
252      # These need to be applied after the main configs so the "-Wno-*" options
253      # take effect.
254      configs += [ ":icu_code" ]
255      configs += extra_configs
256      public_configs = [ ":icu_config" ]
257
258      # Make icu into a standalone static library. Currently This is only useful
259      # on Chrome OS.
260      if (icu_disable_thin_archive) {
261        configs -= [ "//build/config/compiler:thin_archive" ]
262        complete_static_lib = true
263      }
264    }
265  }
266}
267
268template("generate_icui18n") {
269  generate_icu_component(target_name) {
270    assert(defined(invoker.icuuc_deps), "Need the 'icuuc_deps' parameter.")
271    icuuc_deps = invoker.icuuc_deps
272
273    fuchsia_output_name_postfix = ""
274    if (defined(invoker.fuchsia_output_name_postfix)) {
275      fuchsia_output_name_postfix = invoker.fuchsia_output_name_postfix
276    }
277
278    forward_variables_from(invoker,
279                           "*",
280                           [
281                             "testonly",
282                             "visibility",
283                           ])
284
285    sources = icu18n_sources
286    public = icu18n_public
287
288    defines = [ "U_I18N_IMPLEMENTATION" ]
289    deps = icuuc_deps
290
291    # TODO(fxbug.dev/98632): workaround for toolchain issues, see bug
292    if (icu_is_in_fuchsia && is_fuchsia) {
293      deps += [ "//build/config/fuchsia:uses-outline-atomics-fxbug98632" ]
294    }
295  }
296}
297
298generate_icui18n("icui18n") {
299  extra_configs = []
300  icuuc_deps = [ ":icuuc_private" ]
301}
302
303generate_icui18n("icui18n_hidden_visibility") {
304  extra_configs = [ ":visibility_hidden" ]
305  icuuc_deps = [ ":icuuc_private_hidden_visibility" ]
306  if (is_fuchsia && !icu_is_in_fuchsia) {
307    fuchsia_output_name_postfix = "_hidden_visibility"
308  }
309}
310
311template("generate_icuuc") {
312  generate_icu_component(target_name) {
313    fuchsia_output_name_postfix = ""
314    if (defined(invoker.fuchsia_output_name_postfix)) {
315      fuchsia_output_name_postfix = invoker.fuchsia_output_name_postfix
316    }
317
318    forward_variables_from(invoker,
319                           "*",
320                           [
321                             "testonly",
322                             "visibility",
323                           ])
324
325    sources = icuuc_sources
326    public_deps = [ ":icuuc_public" ]
327
328    defines = [ "U_COMMON_IMPLEMENTATION" ]
329    deps = [ ":icudata" ]
330
331    if (is_chromeos) {
332      deps += [ ":icudata_hash" ]
333    }
334
335    if (icu_use_data_file && icu_use_stub_data) {
336      sources += [ "source/stubdata/stubdata.cpp" ]
337    }
338
339    defines += [ "U_ICUDATAENTRY_IN_COMMON" ]
340
341    # TODO(fxbug.dev/98632): workaround for toolchain issues, see bug
342    if (icu_is_in_fuchsia && is_fuchsia) {
343      deps += [ "//build/config/fuchsia:uses-outline-atomics-fxbug98632" ]
344    }
345  }
346}
347
348group("icuuc") {
349  public_deps = [ ":icuuc_private" ]
350}
351
352group("icuuc_hidden_visibility") {
353  public_deps = [ ":icuuc_private_hidden_visibility" ]
354}
355
356source_set("icuuc_public") {
357  sources = icuuc_public
358}
359
360generate_icuuc("icuuc_private") {
361  extra_configs = []
362  output_name = "icuuc"
363  visibility = [
364    ":icui18n",
365    ":icuuc",
366  ]
367}
368
369generate_icuuc("icuuc_private_hidden_visibility") {
370  extra_configs = [ ":visibility_hidden" ]
371  output_name = "icuuc_hidden_visibility"
372  visibility = [
373    ":icui18n_hidden_visibility",
374    ":icuuc_hidden_visibility",
375  ]
376  if (is_fuchsia && !icu_is_in_fuchsia) {
377    fuchsia_output_name_postfix = "_hidden_visibility"
378  }
379}
380
381if (is_android && enable_java_templates) {
382  android_assets("icu_assets") {
383    if (icu_use_data_file) {
384      sources = [ "$root_out_dir/icudtl.dat" ]
385      deps = [ ":icudata" ]
386      disable_compression = true
387    }
388  }
389}
390
391if (is_android) {
392  data_dir = "android"
393} else if (is_ios && !use_blink) {
394  data_dir = "ios"
395} else if (is_chromeos) {
396  data_dir = "chromeos"
397} else if (current_cpu == "wasm") {
398  data_dir = "flutter"
399} else if (icu_is_in_fuchsia && icu_fuchsia_override_data_dir != "") {
400  # See //config.gni for details.
401  data_dir = icu_fuchsia_override_data_dir
402} else {
403  data_dir = "common"
404}
405
406if (current_cpu == "mips" || current_cpu == "mips64" ||
407    host_byteorder == "big") {
408  data_bundle_prefix = "icudtb"
409} else {
410  data_bundle_prefix = "icudtl"
411}
412data_bundle = "${data_bundle_prefix}.dat"
413
414# Some code paths end up not using these, marking them to avoid build
415# breaks.
416# See README.fuchsia for details.
417not_needed([
418             "data_bundle",
419             "data_bundle_prefix",
420             "data_dir",
421           ])
422
423if (icu_copy_icudata_to_root_build_dir) {
424  copy("copy_icudata") {
425    sources = [ "$data_dir/$data_bundle" ]
426    outputs = [ "$root_out_dir/$data_bundle" ]
427    data = [ "$root_out_dir/$data_bundle" ]
428  }
429}
430
431if (icu_use_data_file) {
432  if (is_ios) {
433    bundle_data("icudata") {
434      sources = [ "$data_dir/$data_bundle" ]
435      outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
436    }
437  } else {
438    group("icudata") {
439      if (icu_copy_icudata_to_root_build_dir) {
440        # Guarded by a flag, to avoid name clashes if other build processes
441        # also happen to generate the output file by the same name.
442        # See README.fuchsia for details.
443        public_deps = [ ":copy_icudata" ]
444      }
445    }
446  }
447
448  if (is_chromeos) {
449    copy("icudata_hash") {
450      sources = [ "chromeos/icudtl.dat.hash" ]
451      outputs = [ "$root_out_dir/icudtl.dat.hash" ]
452      if (icu_copy_icudata_to_root_build_dir) {
453        data = [ "$root_out_dir/icudtl.dat.hash" ]
454      }
455    }
456  }
457} else {
458  if (current_cpu == "wasm") {
459    data_assembly = "$target_gen_dir/${data_bundle_prefix}_dat.cpp"
460  } else {
461    data_assembly = "$target_gen_dir/${data_bundle_prefix}_dat.S"
462  }
463  inline_data_assembly = "$target_gen_dir/${data_bundle_prefix}_dat.cc"
464  action("make_data_assembly") {
465    if (current_cpu == "wasm") {
466      # See scripts/make_data_cpp.py for details on building ICU for wasm.
467      script = "scripts/make_data_cpp.py"
468      inputs = [ "$data_dir/$data_bundle" ]
469      outputs = [ data_assembly ]
470      args = [
471        rebase_path(inputs[0], root_build_dir),
472        rebase_path(data_assembly, root_build_dir),
473      ]
474    } else {
475      script = "scripts/make_data_assembly.py"
476      inputs = [ "$data_dir/$data_bundle" ]
477      outputs = [ data_assembly ]
478      args = [
479        rebase_path(inputs[0], root_build_dir),
480        rebase_path(data_assembly, root_build_dir),
481      ]
482      if (is_mac || is_ios) {
483        args += [ "--mac" ]
484      } else if (is_win) {
485        args += [ "--win" ]
486      }
487    }
488  }
489
490  if (is_win) {
491    action("make_inline_data_assembly") {
492      deps = [ ":make_data_assembly" ]
493      script = "scripts/asm_to_inline_asm.py"
494      inputs = [ data_assembly ]
495      outputs = [ inline_data_assembly ]
496      args = rebase_path([
497                           data_assembly,
498                           inline_data_assembly,
499                         ],
500                         root_build_dir)
501    }
502  } else {
503    not_needed([ "inline_data_assembly" ])
504  }
505
506  source_set("icudata") {
507    defines = [ "U_HIDE_DATA_SYMBOL" ]
508    if (is_win) {
509      sources = [ inline_data_assembly ]
510      deps = [ ":make_inline_data_assembly" ]
511    } else {
512      sources = [ data_assembly ]
513      deps = [ ":make_data_assembly" ]
514      asmflags = []
515      if (current_cpu == "arm64") {
516        import("//build/config/arm.gni")
517        if (arm_control_flow_integrity == "standard") {
518          asmflags += [ "-mmark-bti-property" ]
519        }
520      }
521    }
522  }
523}
524