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