| # Copyright 2023 The Fuchsia 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("config.gni") |
| |
| # Generates an include file that includes all needed third_party/icu |
| # headers, and presents them as a build target. |
| # |
| # To use, do the following: |
| # |
| # - In your BUILD file: |
| # |
| # import("//build/icu/third_party_icu_headers.gni") |
| # |
| # third_party_icu_headers("some_headers") { |
| # headers = [ |
| # "third_party/icu/foo/bar/baz.h", |
| # ] |
| # } |
| # |
| # source_set("your_library") { |
| # # ... |
| # deps = [ ":some_headers" ] |
| # # ... |
| # } |
| # |
| # - In your source file: |
| # |
| # #include "your/source/file/directory/some_headers.h" |
| # |
| # This will produce a file `some_headers.h` in |
| # |
| # "${target_gen_dir}/your/source/file/directory/some_headers.h" |
| # |
| # which consists of only includes of the named headers, but with the initial |
| # "third_party/icu" substituted with the content of `$icu_root`. If |
| # the value was set to `icu_root = "//other_dir/icu", the resulting file |
| # content would be: |
| # |
| # #include "other_dir/icu/foo/bar/baz.h" |
| # |
| # for each header listed in the `headers` parameter. |
| # |
| # This allows us to place the library `//third_party/icu` into a different |
| # directory, in a way that is transparent to the library users, so long as |
| # the headers are declared using `third_party_icu_headers`. |
| # |
| # We use this approach because we must vary the path to the ICU library to |
| # account for issues in our build process for some products. The key variable |
| # is $icu_root, which determines where the build system will look for the ICU |
| # library. However, since the header files are also included in our source |
| # files, and their names vary with the choice of the ICU library location, we |
| # must fix up those include paths as well. Since there is no elegant way to do |
| # this in source directly, we generate the appropriate headers and include |
| # those. |
| # |
| # Args: |
| # |
| # headers: list(target): a list of headers from "third_party/icu" that you |
| # need to include. |
| # |
| # icu_assembly: bool: if set, builds ICU assembly flavors of this target. |
| # This is useful for a gradual rollout of flavored builds. |
| template("third_party_icu_headers") { |
| forward_variables_from(invoker, |
| [ |
| "headers", |
| "icu_assembly", |
| ]) |
| |
| icu_target_name = target_name |
| |
| _header_name = "${target_gen_dir}/${icu_target_name}.h" |
| |
| icu_assembly = false |
| if (defined(invoker.icu_assembly)) { |
| icu_assembly = invoker.icu_assembly |
| } |
| |
| # Separate source targets, one for each ICU flavor supported. All built from |
| # the same file, which has different FUCHSIA_ICU_VARIANT env variables defined. |
| if (icu_assembly) { |
| foreach(icu_flavor, icu_flavors) { |
| source_set( |
| "${icu_target_name}.icu_${icu_flavor.name}_${icu_flavor.commit_id}") { |
| # gn check is wrong about includes here. Don't check. |
| # See the same declaration at the very bottom of this file for the |
| # reason. |
| check_includes = false |
| sources = [ _header_name ] |
| public_deps = [ "//third_party/icu/${icu_flavor.name}:icu" ] |
| public_configs = [ |
| # defines FUCHSIA_ICU_VARIANT |
| "//src/lib/icu:${icu_flavor.name}", |
| ] |
| } |
| } |
| } |
| |
| # Writes out the header file contents during the analysis phase. |
| _contents = [] |
| |
| # "//third_party/icu" --> "third_party/icu" |
| _icu_dir = string_replace(icu_root, "//", "", 1) |
| |
| if (icu_assembly) { |
| _icu_dirs = { |
| default = "third_party/icu/default" |
| stable = "third_party/icu/stable" |
| latest = "third_party/icu/latest" |
| } |
| } |
| |
| _contents_map = { |
| default = [] |
| latest = [] |
| stable = [] |
| } |
| foreach(_header, headers) { |
| # #include "third_party/icu/blah" --> #include "${icu_root}/blah" |
| _fixed_header_path = string_replace(_header, "third_party/icu", _icu_dir, 1) |
| _contents += [ "#include \"${_fixed_header_path}\"" ] |
| |
| if (icu_assembly) { |
| # Same as above, but for flavors. |
| _header_path = { |
| } |
| _header_path = { |
| default = |
| string_replace(_header, "third_party/icu", _icu_dirs.default, 1) |
| stable = string_replace(_header, "third_party/icu", _icu_dirs.stable, 1) |
| latest = string_replace(_header, "third_party/icu", _icu_dirs.latest, 1) |
| } |
| |
| _contents_map.default += [ "#include \"${_header_path.default}\"" ] |
| _contents_map.stable += [ "#include \"${_header_path.stable}\"" ] |
| _contents_map.latest += [ "#include \"${_header_path.latest}\"" ] |
| } |
| } |
| |
| _all_contents = |
| [ |
| "/* Autogenerated by //build/icu/third_party_icu_headers. */", |
| "#ifndef FUCHSIA_ICU_VARIANT /* For non-varianted builds. */", |
| ] + _contents + |
| [ "#elif FUCHSIA_ICU_VARIANT == 0 /* //src/lib/icu:default */" ] + |
| _contents_map.default + |
| [ "#elif FUCHSIA_ICU_VARIANT == 1 /* //src/lib/icu:stable */" ] + |
| _contents_map.stable + |
| [ "#elif FUCHSIA_ICU_VARIANT == 2 /* //src/lib/icu:latest */" ] + |
| _contents_map.latest + |
| [ "#elif FUCHSIA_ICU_VARIANT == 3 /* //src/lib/icu:icu_root */" ] + |
| _contents + |
| [ |
| "#else", |
| "/* Refer to //src/lib/icu:{default,stable,latest,icu_root} */", |
| "# error FUCHSIA_ICU_VARIANT needs a value between 0 or 3", |
| "#endif", |
| ] |
| |
| write_file(_header_name, _all_contents, "list lines") |
| |
| source_set("${icu_target_name}") { |
| # gn check is wrong about includes here. Don't check. |
| # |
| # gn check does not seem to take the preprocessor results when checking |
| # for inclusion. The generated file here has several mutually exclusive |
| # ifdefs, each including its appropriate public_deps. Each such ifdef |
| # branch has its includes and deps set correctly, but gn does not know |
| # that and objects about missing deps for includes that are effectively |
| # ifdef'd out. |
| check_includes = false |
| sources = [ _header_name ] |
| public_deps = [ |
| "//src/lib/icu:data", |
| "//src/lib/icu:lib", |
| ] |
| public_configs = [ |
| "${icu_root}:icu_config", |
| |
| # defines FUCHSIA_ICU_VARIANT |
| "//src/lib/icu:icu_root", |
| ] |
| } |
| } |