xref: /aosp_15_r20/external/cronet/third_party/icu/BUILD.gn (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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      # Add Fuchsia-specific configs
207      configs += icu_fuchsia_extra_configs
208      # Remove Fuchsia-specific configs, the "add-then-remove" ensures that
209      # removing a config that is not there does not fail.
210      configs += icu_fuchsia_remove_configs
211      configs -= icu_fuchsia_remove_configs
212      public_configs = [ ":icu_config" ]
213    }
214  } else {
215    component(target_name) {
216      forward_variables_from(invoker,
217                             "*",
218                             [
219                               "testonly",
220                               "visibility",
221                             ])
222
223      # If icu_use_target_output_dir is defined and set, then the component
224      # will be output in the regular target_out_dir, rather than the default
225      # root_build_dir.
226      # See README.fuchsia for details.
227      if (defined(icu_use_target_output_dir) && icu_use_target_output_dir) {
228        output_dir = target_out_dir
229      }
230
231      if (is_fuchsia) {
232        base_output_name = target_name
233        if (defined(invoker.output_name)) {
234          base_output_name = invoker.output_name
235        }
236
237        # Fuchsia puts its own libicu*.so in /system/lib where we need to put our
238        # .so when doing component builds, so we need to give this a different name.
239        output_name = "${base_output_name}_cr${fuchsia_output_name_postfix}"
240      } else {
241        assert(fuchsia_output_name_postfix == "")
242      }
243
244      # ICU uses RTTI, replace the default "no rtti" config (if applied).
245      configs += [
246        "//build/config/compiler:no_rtti",
247        "//build/config/compiler:chromium_code",
248      ]
249      configs -= [
250        "//build/config/compiler:no_rtti",
251        "//build/config/compiler:chromium_code",
252      ]
253      configs += [
254        "//build/config/compiler:rtti",
255        "//build/config/compiler:no_chromium_code",
256      ]
257
258      # These need to be applied after the main configs so the "-Wno-*" options
259      # take effect.
260      configs += [ ":icu_code" ]
261      configs += extra_configs
262      # See a similar stanza above for details.
263      configs += icu_fuchsia_extra_configs
264      configs += icu_fuchsia_remove_configs
265      configs -= icu_fuchsia_remove_configs
266      public_configs = [ ":icu_config" ]
267
268      # Make icu into a standalone static library. Currently This is only useful
269      # on Chrome OS.
270      if (icu_disable_thin_archive) {
271        configs -= [ "//build/config/compiler:thin_archive" ]
272        complete_static_lib = true
273      }
274    }
275  }
276}
277
278template("generate_icui18n") {
279  generate_icu_component(target_name) {
280    assert(defined(invoker.icuuc_deps), "Need the 'icuuc_deps' parameter.")
281    icuuc_deps = invoker.icuuc_deps
282
283    fuchsia_output_name_postfix = ""
284    if (defined(invoker.fuchsia_output_name_postfix)) {
285      fuchsia_output_name_postfix = invoker.fuchsia_output_name_postfix
286    }
287
288    forward_variables_from(invoker,
289                           "*",
290                           [
291                             "testonly",
292                             "visibility",
293                           ])
294
295    sources = icu18n_sources
296    public = icu18n_public
297
298    defines = [ "U_I18N_IMPLEMENTATION" ]
299    deps = icuuc_deps
300
301    # TODO(fxbug.dev/42180987): workaround for toolchain issues, see bug
302    if (icu_is_in_fuchsia && is_fuchsia) {
303      deps += [ "//build/config/fuchsia:uses-outline-atomics-fxbug98632" ]
304    }
305  }
306}
307
308generate_icui18n("icui18n") {
309  extra_configs = []
310  if (icu_is_in_fuchsia) {
311      # See similar stanza above for details.
312      extra_configs += icu_fuchsia_extra_configs
313      extra_configs += icu_fuchsia_remove_configs
314      extra_configs -= icu_fuchsia_remove_configs
315  }
316  icuuc_deps = [ ":icuuc_private" ]
317}
318
319generate_icui18n("icui18n_hidden_visibility") {
320  extra_configs = [ ":visibility_hidden" ]
321  if (icu_is_in_fuchsia) {
322      # See similar stanza above for details.
323      extra_configs += icu_fuchsia_extra_configs
324      extra_configs += icu_fuchsia_remove_configs
325      extra_configs -= icu_fuchsia_remove_configs
326  }
327  icuuc_deps = [ ":icuuc_private_hidden_visibility" ]
328  if (is_fuchsia && !icu_is_in_fuchsia) {
329    fuchsia_output_name_postfix = "_hidden_visibility"
330  }
331}
332
333template("generate_icuuc") {
334  generate_icu_component(target_name) {
335    fuchsia_output_name_postfix = ""
336    if (defined(invoker.fuchsia_output_name_postfix)) {
337      fuchsia_output_name_postfix = invoker.fuchsia_output_name_postfix
338    }
339
340    forward_variables_from(invoker,
341                           "*",
342                           [
343                             "testonly",
344                             "visibility",
345                           ])
346
347    sources = icuuc_sources
348    public_deps = [ ":icuuc_public" ]
349
350    defines = [ "U_COMMON_IMPLEMENTATION" ]
351    deps = [ ":icudata" ]
352
353    if (is_chromeos) {
354      deps += [ ":icudata_hash" ]
355    }
356
357    if (icu_use_data_file && icu_use_stub_data) {
358      sources += [ "source/stubdata/stubdata.cpp" ]
359    }
360
361    defines += [ "U_ICUDATAENTRY_IN_COMMON" ]
362
363    # TODO(fxbug.dev/42180987): workaround for toolchain issues, see bug
364    if (icu_is_in_fuchsia && is_fuchsia) {
365      deps += [ "//build/config/fuchsia:uses-outline-atomics-fxbug98632" ]
366    }
367  }
368}
369
370group("icuuc") {
371  public_deps = [ ":icuuc_private" ]
372}
373
374group("icuuc_hidden_visibility") {
375  public_deps = [ ":icuuc_private_hidden_visibility" ]
376}
377
378source_set("icuuc_public") {
379  sources = icuuc_public
380}
381
382generate_icuuc("icuuc_private") {
383  extra_configs = []
384  if (icu_is_in_fuchsia) {
385      # See similar stanza above for details.
386      extra_configs += icu_fuchsia_extra_configs
387      extra_configs += icu_fuchsia_remove_configs
388      extra_configs -= icu_fuchsia_remove_configs
389  }
390  output_name = "icuuc"
391  visibility = [
392    ":icui18n",
393    ":icuuc",
394  ]
395}
396
397generate_icuuc("icuuc_private_hidden_visibility") {
398  extra_configs = [ ":visibility_hidden" ]
399  if (icu_is_in_fuchsia) {
400      # See similar stanza above for details.
401      extra_configs += icu_fuchsia_extra_configs
402      extra_configs += icu_fuchsia_remove_configs
403      extra_configs -= icu_fuchsia_remove_configs
404  }
405  output_name = "icuuc_hidden_visibility"
406  visibility = [
407    ":icui18n_hidden_visibility",
408    ":icuuc_hidden_visibility",
409  ]
410  if (is_fuchsia && !icu_is_in_fuchsia) {
411    fuchsia_output_name_postfix = "_hidden_visibility"
412  }
413}
414
415if (is_android && enable_java_templates) {
416  android_assets("icu_assets") {
417    if (icu_use_data_file) {
418      sources = [ "$root_out_dir/icudtl.dat" ]
419      deps = [ ":icudata" ]
420      disable_compression = true
421    }
422  }
423}
424
425if (is_android) {
426  data_dir = "android"
427} else if (is_ios && !use_blink) {
428  data_dir = "ios"
429} else if (is_chromeos) {
430  data_dir = "chromeos"
431} else if (current_cpu == "wasm") {
432  data_dir = "flutter"
433} else if (icu_is_in_fuchsia && icu_fuchsia_override_data_dir != "") {
434  # See //config.gni for details.
435  data_dir = icu_fuchsia_override_data_dir
436} else {
437  data_dir = "common"
438}
439
440if (current_cpu == "mips" || current_cpu == "mips64" ||
441    host_byteorder == "big") {
442  data_bundle_prefix = "icudtb"
443} else {
444  data_bundle_prefix = "icudtl"
445}
446data_bundle = "${data_bundle_prefix}.dat"
447
448# Some code paths end up not using these, marking them to avoid build
449# breaks.
450# See README.fuchsia for details.
451not_needed([
452             "data_bundle",
453             "data_bundle_prefix",
454             "data_dir",
455           ])
456
457if (icu_copy_icudata_to_root_build_dir) {
458  copy("copy_icudata") {
459    sources = [ "$data_dir/$data_bundle" ]
460    outputs = [ "$root_out_dir/$data_bundle" ]
461    data = [ "$root_out_dir/$data_bundle" ]
462  }
463}
464
465if (icu_use_data_file) {
466  if (is_ios) {
467    bundle_data("icudata") {
468      sources = [ "$data_dir/$data_bundle" ]
469      outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
470    }
471  } else {
472    group("icudata") {
473      if (icu_copy_icudata_to_root_build_dir) {
474        # Guarded by a flag, to avoid name clashes if other build processes
475        # also happen to generate the output file by the same name.
476        # See README.fuchsia for details.
477        public_deps = [ ":copy_icudata" ]
478      }
479    }
480  }
481
482  if (is_chromeos) {
483    copy("icudata_hash") {
484      sources = [ "chromeos/icudtl.dat.hash" ]
485      outputs = [ "$root_out_dir/icudtl.dat.hash" ]
486      if (icu_copy_icudata_to_root_build_dir) {
487        data = [ "$root_out_dir/icudtl.dat.hash" ]
488      }
489    }
490  }
491} else {
492  if (current_cpu == "wasm") {
493    data_assembly = "$target_gen_dir/${data_bundle_prefix}_dat.cpp"
494  } else {
495    data_assembly = "$target_gen_dir/${data_bundle_prefix}_dat.S"
496  }
497  inline_data_assembly = "$target_gen_dir/${data_bundle_prefix}_dat.cc"
498  action("make_data_assembly") {
499    if (current_cpu == "wasm") {
500      # See scripts/make_data_cpp.py for details on building ICU for wasm.
501      script = "scripts/make_data_cpp.py"
502      inputs = [ "$data_dir/$data_bundle" ]
503      outputs = [ data_assembly ]
504      args = [
505        rebase_path(inputs[0], root_build_dir),
506        rebase_path(data_assembly, root_build_dir),
507      ]
508    } else {
509      script = "scripts/make_data_assembly.py"
510      inputs = [ "$data_dir/$data_bundle" ]
511      outputs = [ data_assembly ]
512      args = [
513        rebase_path(inputs[0], root_build_dir),
514        rebase_path(data_assembly, root_build_dir),
515      ]
516      if (is_mac || is_ios) {
517        args += [ "--mac" ]
518      } else if (is_win) {
519        if (target_cpu == "arm64" || target_cpu == "x64") {
520          args += [ "--win64" ]
521        } else if (target_cpu == "arm" || target_cpu == "x86") {
522          args += [ "--win32" ]
523        } else {
524          assert(false)
525        }
526      }
527    }
528  }
529
530  if (is_win) {
531    action("make_inline_data_assembly") {
532      deps = [ ":make_data_assembly" ]
533      script = "scripts/asm_to_inline_asm.py"
534      inputs = [ data_assembly ]
535      outputs = [ inline_data_assembly ]
536      args = rebase_path([
537                           data_assembly,
538                           inline_data_assembly,
539                         ],
540                         root_build_dir)
541    }
542  } else {
543    not_needed([ "inline_data_assembly" ])
544  }
545
546  source_set("icudata") {
547    defines = [ "U_HIDE_DATA_SYMBOL" ]
548    if (is_win) {
549      sources = [ inline_data_assembly ]
550      deps = [ ":make_inline_data_assembly" ]
551    } else {
552      sources = [ data_assembly ]
553      deps = [ ":make_data_assembly" ]
554      asmflags = []
555      if (current_cpu == "arm64") {
556        import("//build/config/arm.gni")
557        if (arm_control_flow_integrity == "standard") {
558          asmflags += [ "-mmark-bti-property" ]
559        }
560      }
561    }
562  }
563}
564