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