diff --git a/configure.py b/configure.py index a96f3bbdc7cc84..6537a62d3954d8 100755 --- a/configure.py +++ b/configure.py @@ -443,6 +443,14 @@ 'the icu4c source archive. ' 'v%d.x or later recommended.' % icu_versions['minimum_icu']) +intl_optgroup.add_option('--with-icu-default-data-dir', + action='store', + dest='with_icu_default_data_dir', + help='Path to the icuXXdt{lb}.dat file. If unspecified, ICU data will ' + 'only be read if the NODE_ICU_DATA environment variable or the ' + '--icu-data-dir runtime argument is used. This option has effect ' + 'only when Node.js is built with --with-intl=small-icu.') + parser.add_option('--with-ltcg', action='store_true', dest='with_ltcg', @@ -1370,6 +1378,7 @@ def write_config(data, name): locs.add('root') # must have root o['variables']['icu_locales'] = ','.join(str(loc) for loc in locs) # We will check a bit later if we can use the canned deps/icu-small + o['variables']['icu_default_data'] = options.with_icu_default_data_dir or '' elif with_intl == 'full-icu': # full ICU o['variables']['v8_enable_i18n_support'] = 1 diff --git a/node.gypi b/node.gypi index 1f14dc989d7518..4ee7bad0104040 100644 --- a/node.gypi +++ b/node.gypi @@ -103,6 +103,13 @@ 'conditions': [ [ 'icu_small=="true"', { 'defines': [ 'NODE_HAVE_SMALL_ICU=1' ], + 'conditions': [ + [ 'icu_default_data!=""', { + 'defines': [ + 'NODE_ICU_DEFAULT_DATA_DIR="<(icu_default_data)"', + ], + }], + ], }]], }], [ 'node_no_browser_globals=="true"', { diff --git a/src/node.cc b/src/node.cc index 5c0ed444087699..20a627c0ba2a5e 100644 --- a/src/node.cc +++ b/src/node.cc @@ -79,6 +79,7 @@ #if defined(NODE_HAVE_I18N_SUPPORT) #include +#include #endif @@ -831,6 +832,25 @@ int InitializeNodeWithArgs(std::vector* argv, if (per_process::cli_options->icu_data_dir.empty()) credentials::SafeGetenv("NODE_ICU_DATA", &per_process::cli_options->icu_data_dir); + +#ifdef NODE_ICU_DEFAULT_DATA_DIR + // If neither the CLI option nor the environment variable was specified, + // fall back to the configured default + if (per_process::cli_options->icu_data_dir.empty()) { + // Check whether the NODE_ICU_DEFAULT_DATA_DIR contains the right data + // file and can be read. + static const char full_path[] = + NODE_ICU_DEFAULT_DATA_DIR "/" U_ICUDATA_NAME ".dat"; + + FILE* f = fopen(full_path, "rb"); + + if (f != nullptr) { + fclose(f); + per_process::cli_options->icu_data_dir = NODE_ICU_DEFAULT_DATA_DIR; + } + } +#endif // NODE_ICU_DEFAULT_DATA_DIR + // Initialize ICU. // If icu_data_dir is empty here, it will load the 'minimal' data. if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) {