@@ -6,13 +6,19 @@ import re
6
6
import shlex
7
7
import subprocess
8
8
import sys
9
+ import shutil
10
+ import string
9
11
10
12
CC = os .environ .get ('CC' , 'cc' )
11
13
12
14
root_dir = os .path .dirname (__file__ )
13
15
sys .path .insert (0 , os .path .join (root_dir , 'tools' , 'gyp' , 'pylib' ))
14
16
from gyp .common import GetFlavor
15
17
18
+ # imports in tools/configure.d
19
+ sys .path .insert (0 , os .path .join (root_dir , 'tools' , 'configure.d' ))
20
+ import nodedownload
21
+
16
22
# parse our options
17
23
parser = optparse .OptionParser ()
18
24
@@ -216,16 +222,31 @@ parser.add_option('--with-etw',
216
222
dest = 'with_etw' ,
217
223
help = 'build with ETW (default is true on Windows)' )
218
224
225
+ parser .add_option ('--download' ,
226
+ action = 'store' ,
227
+ dest = 'download_list' ,
228
+ help = nodedownload .help ())
229
+
219
230
parser .add_option ('--with-icu-path' ,
220
231
action = 'store' ,
221
232
dest = 'with_icu_path' ,
222
233
help = 'Path to icu.gyp (ICU i18n, Chromium version only.)' )
223
234
235
+ parser .add_option ('--with-icu-locales' ,
236
+ action = 'store' ,
237
+ dest = 'with_icu_locales' ,
238
+ help = 'Comma-separated list of locales for "small-icu". Default: "root,en". "root" is assumed.' )
239
+
224
240
parser .add_option ('--with-intl' ,
225
241
action = 'store' ,
226
242
dest = 'with_intl' ,
227
243
help = 'Intl mode: none, full-icu, small-icu (default is none)' )
228
244
245
+ parser .add_option ('--with-icu-source' ,
246
+ action = 'store' ,
247
+ dest = 'with_icu_source' ,
248
+ help = 'Intl mode: optional local path to icu/ dir, or path/URL of icu source archive.' )
249
+
229
250
parser .add_option ('--with-perfctr' ,
230
251
action = 'store_true' ,
231
252
dest = 'with_perfctr' ,
@@ -274,6 +295,8 @@ parser.add_option('--xcode',
274
295
275
296
(options , args ) = parser .parse_args ()
276
297
298
+ # set up auto-download list
299
+ auto_downloads = nodedownload .parse (options .download_list )
277
300
278
301
def b (value ):
279
302
"""Returns the string 'true' if value is truthy, 'false' otherwise."""
@@ -632,6 +655,35 @@ def glob_to_var(dir_base, dir_sub):
632
655
return list
633
656
634
657
def configure_intl (o ):
658
+ icus = [
659
+ {
660
+ 'url' : 'http://download.icu-project.org/files/icu4c/54.1/icu4c-54_1-src.zip' ,
661
+ # from https://ssl.icu-project.org/files/icu4c/54.1/icu4c-src-54_1.md5:
662
+ 'md5' : '6b89d60e2f0e140898ae4d7f72323bca' ,
663
+ },
664
+ ]
665
+ def icu_download (path ):
666
+ # download ICU, if needed
667
+ for icu in icus :
668
+ url = icu ['url' ]
669
+ md5 = icu ['md5' ]
670
+ local = url .split ('/' )[- 1 ]
671
+ targetfile = os .path .join (root_dir , 'deps' , local )
672
+ if not os .path .isfile (targetfile ):
673
+ if nodedownload .candownload (auto_downloads , "icu" ):
674
+ nodedownload .retrievefile (url , targetfile )
675
+ else :
676
+ print ' Re-using existing %s' % targetfile
677
+ if os .path .isfile (targetfile ):
678
+ sys .stdout .write (' Checking file integrity with MD5:\r ' )
679
+ gotmd5 = nodedownload .md5sum (targetfile )
680
+ print ' MD5: %s %s' % (gotmd5 , targetfile )
681
+ if (md5 == gotmd5 ):
682
+ return targetfile
683
+ else :
684
+ print ' Expected: %s *MISMATCH*' % md5
685
+ print '\n ** Corrupted ZIP? Delete %s to retry download.\n ' % targetfile
686
+ return None
635
687
icu_config = {
636
688
'variables' : {}
637
689
}
@@ -643,11 +695,11 @@ def configure_intl(o):
643
695
write (icu_config_name , do_not_edit +
644
696
pprint .pformat (icu_config , indent = 2 ) + '\n ' )
645
697
646
- # small ICU is off by default.
647
698
# always set icu_small, node.gyp depends on it being defined.
648
699
o ['variables' ]['icu_small' ] = b (False )
649
700
650
701
with_intl = options .with_intl
702
+ with_icu_source = options .with_icu_source
651
703
have_icu_path = bool (options .with_icu_path )
652
704
if have_icu_path and with_intl :
653
705
print 'Error: Cannot specify both --with-icu-path and --with-intl'
@@ -659,13 +711,26 @@ def configure_intl(o):
659
711
o ['variables' ]['icu_gyp_path' ] = options .with_icu_path
660
712
return
661
713
# --with-intl=<with_intl>
714
+ # set the default
715
+ if with_intl is None :
716
+ with_intl = 'none' # The default mode of Intl
717
+ # sanity check localelist
718
+ if options .with_icu_locales and (with_intl != 'small-icu' ):
719
+ print 'Error: --with-icu-locales only makes sense with --with-intl=small-icu'
720
+ sys .exit (1 )
662
721
if with_intl == 'none' or with_intl is None :
663
722
o ['variables' ]['v8_enable_i18n_support' ] = 0
664
723
return # no Intl
665
724
elif with_intl == 'small-icu' :
666
725
# small ICU (English only)
667
726
o ['variables' ]['v8_enable_i18n_support' ] = 1
668
727
o ['variables' ]['icu_small' ] = b (True )
728
+ with_icu_locales = options .with_icu_locales
729
+ if not with_icu_locales :
730
+ with_icu_locales = 'root,en'
731
+ locs = set (with_icu_locales .split (',' ))
732
+ locs .add ('root' ) # must have root
733
+ o ['variables' ]['icu_locales' ] = string .join (locs ,',' )
669
734
elif with_intl == 'full-icu' :
670
735
# full ICU
671
736
o ['variables' ]['v8_enable_i18n_support' ] = 1
@@ -689,20 +754,78 @@ def configure_intl(o):
689
754
# Note: non-ICU implementations could use other 'with_intl'
690
755
# values.
691
756
757
+ # this is just the 'deps' dir. Used for unpacking.
758
+ icu_parent_path = os .path .join (root_dir , 'deps' )
759
+
760
+ # The full path to the ICU source directory.
761
+ icu_full_path = os .path .join (icu_parent_path , 'icu' )
762
+
763
+ # icu-tmp is used to download and unpack the ICU tarball.
764
+ icu_tmp_path = os .path .join (icu_parent_path , 'icu-tmp' )
765
+
766
+ # --with-icu-source processing
767
+ # first, check that they didn't pass --with-icu-source=deps/icu
768
+ if with_icu_source and os .path .abspath (icu_full_path ) == os .path .abspath (with_icu_source ):
769
+ print 'Ignoring redundant --with-icu-source=%s' % (with_icu_source )
770
+ with_icu_source = None
771
+ # if with_icu_source is still set, try to use it.
772
+ if with_icu_source :
773
+ if os .path .isdir (icu_full_path ):
774
+ print 'Deleting old ICU source: %s' % (icu_full_path )
775
+ shutil .rmtree (icu_full_path )
776
+ # now, what path was given?
777
+ if os .path .isdir (with_icu_source ):
778
+ # it's a path. Copy it.
779
+ print '%s -> %s' % (with_icu_source , icu_full_path )
780
+ shutil .copytree (with_icu_source , icu_full_path )
781
+ else :
782
+ # could be file or URL.
783
+ # Set up temporary area
784
+ if os .path .isdir (icu_tmp_path ):
785
+ shutil .rmtree (icu_tmp_path )
786
+ os .mkdir (icu_tmp_path )
787
+ icu_tarball = None
788
+ if os .path .isfile (with_icu_source ):
789
+ # it's a file. Try to unpack it.
790
+ icu_tarball = with_icu_source
791
+ else :
792
+ # Can we download it?
793
+ local = os .path .join (icu_tmp_path , with_icu_source .split ('/' )[- 1 ]) # local part
794
+ icu_tarball = nodedownload .retrievefile (with_icu_source , local )
795
+ # continue with "icu_tarball"
796
+ nodedownload .unpack (icu_tarball , icu_tmp_path )
797
+ # Did it unpack correctly? Should contain 'icu'
798
+ tmp_icu = os .path .join (icu_tmp_path , 'icu' )
799
+ if os .path .isdir (tmp_icu ):
800
+ os .rename (tmp_icu , icu_full_path )
801
+ shutil .rmtree (icu_tmp_path )
802
+ else :
803
+ print ' Error: --with-icu-source=%s did not result in an "icu" dir.' % with_icu_source
804
+ shutil .rmtree (icu_tmp_path )
805
+ sys .exit (1 )
806
+
692
807
# ICU mode. (icu-generic.gyp)
693
808
byteorder = sys .byteorder
694
809
o ['variables' ]['icu_gyp_path' ] = 'tools/icu/icu-generic.gyp'
695
810
# ICU source dir relative to root
696
- icu_full_path = os .path .join (root_dir , 'deps/icu' )
697
811
o ['variables' ]['icu_path' ] = icu_full_path
698
812
if not os .path .isdir (icu_full_path ):
699
- print 'Error: ICU path is not a directory: %s' % (icu_full_path )
813
+ print '* ECMA-402 (Intl) support didn\' t find ICU in %s..' % (icu_full_path )
814
+ # can we download (or find) a zipfile?
815
+ localzip = icu_download (icu_full_path )
816
+ if localzip :
817
+ nodedownload .unpack (localzip , icu_parent_path )
818
+ if not os .path .isdir (icu_full_path ):
819
+ print ' Cannot build Intl without ICU in %s.' % (icu_full_path )
820
+ print ' (Fix, or disable with "--with-intl=none" )'
700
821
sys .exit (1 )
822
+ else :
823
+ print '* Using ICU in %s' % (icu_full_path )
701
824
# Now, what version of ICU is it? We just need the "major", such as 54.
702
825
# uvernum.h contains it as a #define.
703
826
uvernum_h = os .path .join (icu_full_path , 'source/common/unicode/uvernum.h' )
704
827
if not os .path .isfile (uvernum_h ):
705
- print 'Error: could not load %s - is ICU installed?' % uvernum_h
828
+ print ' Error: could not load %s - is ICU installed?' % uvernum_h
706
829
sys .exit (1 )
707
830
icu_ver_major = None
708
831
matchVerExp = r'^\s*#define\s+U_ICU_VERSION_SHORT\s+"([^"]*)".*'
@@ -712,7 +835,7 @@ def configure_intl(o):
712
835
if m :
713
836
icu_ver_major = m .group (1 )
714
837
if not icu_ver_major :
715
- print 'Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h
838
+ print ' Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h
716
839
sys .exit (1 )
717
840
icu_endianness = sys .byteorder [0 ]; # TODO(srl295): EBCDIC should be 'e'
718
841
o ['variables' ]['icu_ver_major' ] = icu_ver_major
@@ -739,8 +862,8 @@ def configure_intl(o):
739
862
# this is the icudt*.dat file which node will be using (platform endianness)
740
863
o ['variables' ]['icu_data_file' ] = icu_data_file
741
864
if not os .path .isfile (icu_data_path ):
742
- print 'Error: ICU prebuilt data file %s does not exist.' % icu_data_path
743
- print 'See the README.md.'
865
+ print ' Error: ICU prebuilt data file %s does not exist.' % icu_data_path
866
+ print ' See the README.md.'
744
867
# .. and we're not about to build it from .gyp!
745
868
sys .exit (1 )
746
869
# map from variable name to subdirs
0 commit comments