3 # Any copyright is dedicated to the Public Domain.
4 # http://creativecommons.org/publicdomain/zero/1.0/
6 # Generate SOURCES in sources.mozbuild files from ICU's Makefile.in
7 # files, and also build a standalone copy of ICU using its build
8 # system to generate a new copy of the in-tree ICU data file.
10 # This script expects to be run from `update-icu.sh` after the in-tree
11 # copy of ICU has been updated.
13 from __future__
import print_function
22 from mozpack
import path
as mozpath
25 def find_source_file(dir, filename
):
26 base
= os
.path
.splitext(filename
)[0]
27 for ext
in ('.cpp', '.c'):
28 f
= mozpath
.join(dir, base
+ ext
)
31 raise Exception("Couldn't find source file for: %s" % filename
)
34 def get_sources_from_makefile(makefile
):
36 from pymake
.parserdata
import SetVariable
37 srcdir
= os
.path
.dirname(makefile
)
38 for statement
in pymake
.parser
.parsefile(makefile
):
39 if (isinstance(statement
, SetVariable
) and
40 statement
.vnameexp
.is_static_string
and
41 statement
.vnameexp
.s
== 'OBJECTS'):
42 return sorted((find_source_file(srcdir
, s
)
43 for s
in statement
.value
.split()),
44 key
=lambda x
: x
.lower())
47 def list_headers(path
):
49 for name
in os
.listdir(path
):
50 f
= mozpath
.join(path
, name
)
53 return sorted(result
, key
=lambda x
: x
.lower())
56 def write_sources(mozbuild
, sources
, headers
):
57 with
open(mozbuild
, 'wb') as f
:
58 f
.write('# THIS FILE IS GENERATED BY /intl/icu_sources_data.py ' +
61 f
.write(''.join(" '/%s',\n" % s
for s
in sources
))
63 f
.write('EXPORTS.unicode += [\n')
64 f
.write(''.join(" '/%s',\n" % s
for s
in headers
))
68 def update_sources(topsrcdir
):
69 print('Updating ICU sources lists...')
70 sys
.path
.append(mozpath
.join(topsrcdir
, 'build/pymake'))
71 for d
in ['common', 'i18n']:
72 base_path
= mozpath
.join(topsrcdir
, 'intl/icu/source/%s' % d
)
73 makefile
= mozpath
.join(base_path
, 'Makefile.in')
74 mozbuild
= mozpath
.join(topsrcdir
,
75 'config/external/icu/%s/sources.mozbuild' % d
)
76 sources
= [mozpath
.relpath(s
, topsrcdir
)
77 for s
in get_sources_from_makefile(makefile
)]
78 headers
= [mozpath
.normsep(os
.path
.relpath(s
, topsrcdir
))
79 for s
in list_headers(mozpath
.join(base_path
, 'unicode'))]
80 write_sources(mozbuild
, sources
, headers
)
83 def try_run(name
, command
, cwd
=None, **kwargs
):
85 with tempfile
.NamedTemporaryFile(prefix
=name
, delete
=False) as f
:
86 subprocess
.check_call(command
, cwd
=cwd
, stdout
=f
,
87 stderr
=subprocess
.STDOUT
, **kwargs
)
88 except subprocess
.CalledProcessError
:
89 print('''Error running "{}" in directory {}
90 See output in {}'''.format(' '.join(command
), cwd
, f
.name
),
98 def get_data_file(data_dir
):
99 files
= glob
.glob(mozpath
.join(data_dir
, 'icudt*.dat'))
100 return files
[0] if files
else None
103 def update_data_file(topsrcdir
):
104 objdir
= tempfile
.mkdtemp(prefix
='icu-obj-')
105 configure
= mozpath
.join(topsrcdir
, 'intl/icu/source/configure')
106 env
= dict(os
.environ
)
107 # bug 1262101 - these should be shared with the moz.build files
109 'CPPFLAGS': ('-DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1 ' +
110 '-DUCONFIG_NO_LEGACY_CONVERSION ' +
111 '-DUCONFIG_NO_TRANSLITERATION ' +
112 '-DUCONFIG_NO_REGULAR_EXPRESSIONS ' +
113 '-DUCONFIG_NO_BREAK_ITERATION ' +
114 '-DU_CHARSET_IS_UTF8')
116 print('Running ICU configure...')
120 '--with-data-packaging=archive',
132 print('Running ICU make...')
133 if not try_run('icu-make', ['make'], cwd
=objdir
):
135 print('Copying ICU data file...')
136 tree_data_path
= mozpath
.join(topsrcdir
,
137 'config/external/icu/data/')
138 old_data_file
= get_data_file(tree_data_path
)
139 if not old_data_file
:
140 print('Error: no ICU data file in %s' % tree_data_path
,
143 new_data_file
= get_data_file(mozpath
.join(objdir
, 'data/out'))
144 if not new_data_file
:
145 print('Error: no ICU data in ICU objdir', file=sys
.stderr
)
147 if os
.path
.basename(old_data_file
) != os
.path
.basename(new_data_file
):
148 # Data file name has the major version number embedded.
149 os
.unlink(old_data_file
)
150 shutil
.copy(new_data_file
, tree_data_path
)
152 shutil
.rmtree(objdir
)
154 print('Warning: failed to remove %s' % objdir
, file=sys
.stderr
)
159 if len(sys
.argv
) != 2:
160 print('Usage: icu_sources_data.py <mozilla topsrcdir>',
164 topsrcdir
= mozpath
.abspath(sys
.argv
[1])
165 update_sources(topsrcdir
)
166 if not update_data_file(topsrcdir
):
167 print('Error updating ICU data file', file=sys
.stderr
)
171 if __name__
== '__main__':