@@ -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
@@ -236,16 +242,31 @@ parser.add_option('--with-etw',
236
242
dest = 'with_etw' ,
237
243
help = 'build with ETW (default is true on Windows)' )
238
244
245
+ parser .add_option ('--download' ,
246
+ action = 'store' ,
247
+ dest = 'download_list' ,
248
+ help = nodedownload .help ())
249
+
239
250
parser .add_option ('--with-icu-path' ,
240
251
action = 'store' ,
241
252
dest = 'with_icu_path' ,
242
253
help = 'Path to icu.gyp (ICU i18n, Chromium version only.)' )
243
254
255
+ parser .add_option ('--with-icu-locales' ,
256
+ action = 'store' ,
257
+ dest = 'with_icu_locales' ,
258
+ help = 'Comma-separated list of locales for "small-icu". Default: "root,en". "root" is assumed.' )
259
+
244
260
parser .add_option ('--with-intl' ,
245
261
action = 'store' ,
246
262
dest = 'with_intl' ,
247
263
help = 'Intl mode: none, full-icu, small-icu (default is none)' )
248
264
265
+ parser .add_option ('--with-icu-source' ,
266
+ action = 'store' ,
267
+ dest = 'with_icu_source' ,
268
+ help = 'Intl mode: optional local path to icu/ dir, or path/URL of icu source archive.' )
269
+
249
270
parser .add_option ('--with-perfctr' ,
250
271
action = 'store_true' ,
251
272
dest = 'with_perfctr' ,
@@ -294,6 +315,8 @@ parser.add_option('--xcode',
294
315
295
316
(options , args ) = parser .parse_args ()
296
317
318
+ # set up auto-download list
319
+ auto_downloads = nodedownload .parse (options .download_list )
297
320
298
321
def b (value ):
299
322
"""Returns the string 'true' if value is truthy, 'false' otherwise."""
@@ -712,6 +735,35 @@ def glob_to_var(dir_base, dir_sub):
712
735
return list
713
736
714
737
def configure_intl (o ):
738
+ icus = [
739
+ {
740
+ 'url' : 'http://download.icu-project.org/files/icu4c/54.1/icu4c-54_1-src.zip' ,
741
+ # from https://ssl.icu-project.org/files/icu4c/54.1/icu4c-src-54_1.md5:
742
+ 'md5' : '6b89d60e2f0e140898ae4d7f72323bca' ,
743
+ },
744
+ ]
745
+ def icu_download (path ):
746
+ # download ICU, if needed
747
+ for icu in icus :
748
+ url = icu ['url' ]
749
+ md5 = icu ['md5' ]
750
+ local = url .split ('/' )[- 1 ]
751
+ targetfile = os .path .join (root_dir , 'deps' , local )
752
+ if not os .path .isfile (targetfile ):
753
+ if nodedownload .candownload (auto_downloads , "icu" ):
754
+ nodedownload .retrievefile (url , targetfile )
755
+ else :
756
+ print ' Re-using existing %s' % targetfile
757
+ if os .path .isfile (targetfile ):
758
+ sys .stdout .write (' Checking file integrity with MD5:\r ' )
759
+ gotmd5 = nodedownload .md5sum (targetfile )
760
+ print ' MD5: %s %s' % (gotmd5 , targetfile )
761
+ if (md5 == gotmd5 ):
762
+ return targetfile
763
+ else :
764
+ print ' Expected: %s *MISMATCH*' % md5
765
+ print '\n ** Corrupted ZIP? Delete %s to retry download.\n ' % targetfile
766
+ return None
715
767
icu_config = {
716
768
'variables' : {}
717
769
}
@@ -723,11 +775,11 @@ def configure_intl(o):
723
775
write (icu_config_name , do_not_edit +
724
776
pprint .pformat (icu_config , indent = 2 ) + '\n ' )
725
777
726
- # small ICU is off by default.
727
778
# always set icu_small, node.gyp depends on it being defined.
728
779
o ['variables' ]['icu_small' ] = b (False )
729
780
730
781
with_intl = options .with_intl
782
+ with_icu_source = options .with_icu_source
731
783
have_icu_path = bool (options .with_icu_path )
732
784
if have_icu_path and with_intl :
733
785
print 'Error: Cannot specify both --with-icu-path and --with-intl'
@@ -739,13 +791,26 @@ def configure_intl(o):
739
791
o ['variables' ]['icu_gyp_path' ] = options .with_icu_path
740
792
return
741
793
# --with-intl=<with_intl>
794
+ # set the default
795
+ if with_intl is None :
796
+ with_intl = 'none' # The default mode of Intl
797
+ # sanity check localelist
798
+ if options .with_icu_locales and (with_intl != 'small-icu' ):
799
+ print 'Error: --with-icu-locales only makes sense with --with-intl=small-icu'
800
+ sys .exit (1 )
742
801
if with_intl == 'none' or with_intl is None :
743
802
o ['variables' ]['v8_enable_i18n_support' ] = 0
744
803
return # no Intl
745
804
elif with_intl == 'small-icu' :
746
805
# small ICU (English only)
747
806
o ['variables' ]['v8_enable_i18n_support' ] = 1
748
807
o ['variables' ]['icu_small' ] = b (True )
808
+ with_icu_locales = options .with_icu_locales
809
+ if not with_icu_locales :
810
+ with_icu_locales = 'root,en'
811
+ locs = set (with_icu_locales .split (',' ))
812
+ locs .add ('root' ) # must have root
813
+ o ['variables' ]['icu_locales' ] = string .join (locs ,',' )
749
814
elif with_intl == 'full-icu' :
750
815
# full ICU
751
816
o ['variables' ]['v8_enable_i18n_support' ] = 1
@@ -769,20 +834,78 @@ def configure_intl(o):
769
834
# Note: non-ICU implementations could use other 'with_intl'
770
835
# values.
771
836
837
+ # this is just the 'deps' dir. Used for unpacking.
838
+ icu_parent_path = os .path .join (root_dir , 'deps' )
839
+
840
+ # The full path to the ICU source directory.
841
+ icu_full_path = os .path .join (icu_parent_path , 'icu' )
842
+
843
+ # icu-tmp is used to download and unpack the ICU tarball.
844
+ icu_tmp_path = os .path .join (icu_parent_path , 'icu-tmp' )
845
+
846
+ # --with-icu-source processing
847
+ # first, check that they didn't pass --with-icu-source=deps/icu
848
+ if with_icu_source and os .path .abspath (icu_full_path ) == os .path .abspath (with_icu_source ):
849
+ print 'Ignoring redundant --with-icu-source=%s' % (with_icu_source )
850
+ with_icu_source = None
851
+ # if with_icu_source is still set, try to use it.
852
+ if with_icu_source :
853
+ if os .path .isdir (icu_full_path ):
854
+ print 'Deleting old ICU source: %s' % (icu_full_path )
855
+ shutil .rmtree (icu_full_path )
856
+ # now, what path was given?
857
+ if os .path .isdir (with_icu_source ):
858
+ # it's a path. Copy it.
859
+ print '%s -> %s' % (with_icu_source , icu_full_path )
860
+ shutil .copytree (with_icu_source , icu_full_path )
861
+ else :
862
+ # could be file or URL.
863
+ # Set up temporary area
864
+ if os .path .isdir (icu_tmp_path ):
865
+ shutil .rmtree (icu_tmp_path )
866
+ os .mkdir (icu_tmp_path )
867
+ icu_tarball = None
868
+ if os .path .isfile (with_icu_source ):
869
+ # it's a file. Try to unpack it.
870
+ icu_tarball = with_icu_source
871
+ else :
872
+ # Can we download it?
873
+ local = os .path .join (icu_tmp_path , with_icu_source .split ('/' )[- 1 ]) # local part
874
+ icu_tarball = nodedownload .retrievefile (with_icu_source , local )
875
+ # continue with "icu_tarball"
876
+ nodedownload .unpack (icu_tarball , icu_tmp_path )
877
+ # Did it unpack correctly? Should contain 'icu'
878
+ tmp_icu = os .path .join (icu_tmp_path , 'icu' )
879
+ if os .path .isdir (tmp_icu ):
880
+ os .rename (tmp_icu , icu_full_path )
881
+ shutil .rmtree (icu_tmp_path )
882
+ else :
883
+ print ' Error: --with-icu-source=%s did not result in an "icu" dir.' % with_icu_source
884
+ shutil .rmtree (icu_tmp_path )
885
+ sys .exit (1 )
886
+
772
887
# ICU mode. (icu-generic.gyp)
773
888
byteorder = sys .byteorder
774
889
o ['variables' ]['icu_gyp_path' ] = 'tools/icu/icu-generic.gyp'
775
890
# ICU source dir relative to root
776
- icu_full_path = os .path .join (root_dir , 'deps/icu' )
777
891
o ['variables' ]['icu_path' ] = icu_full_path
778
892
if not os .path .isdir (icu_full_path ):
779
- print 'Error: ICU path is not a directory: %s' % (icu_full_path )
893
+ print '* ECMA-402 (Intl) support didn\' t find ICU in %s..' % (icu_full_path )
894
+ # can we download (or find) a zipfile?
895
+ localzip = icu_download (icu_full_path )
896
+ if localzip :
897
+ nodedownload .unpack (localzip , icu_parent_path )
898
+ if not os .path .isdir (icu_full_path ):
899
+ print ' Cannot build Intl without ICU in %s.' % (icu_full_path )
900
+ print ' (Fix, or disable with "--with-intl=none" )'
780
901
sys .exit (1 )
902
+ else :
903
+ print '* Using ICU in %s' % (icu_full_path )
781
904
# Now, what version of ICU is it? We just need the "major", such as 54.
782
905
# uvernum.h contains it as a #define.
783
906
uvernum_h = os .path .join (icu_full_path , 'source/common/unicode/uvernum.h' )
784
907
if not os .path .isfile (uvernum_h ):
785
- print 'Error: could not load %s - is ICU installed?' % uvernum_h
908
+ print ' Error: could not load %s - is ICU installed?' % uvernum_h
786
909
sys .exit (1 )
787
910
icu_ver_major = None
788
911
matchVerExp = r'^\s*#define\s+U_ICU_VERSION_SHORT\s+"([^"]*)".*'
@@ -792,7 +915,7 @@ def configure_intl(o):
792
915
if m :
793
916
icu_ver_major = m .group (1 )
794
917
if not icu_ver_major :
795
- print 'Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h
918
+ print ' Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h
796
919
sys .exit (1 )
797
920
icu_endianness = sys .byteorder [0 ]; # TODO(srl295): EBCDIC should be 'e'
798
921
o ['variables' ]['icu_ver_major' ] = icu_ver_major
@@ -819,8 +942,8 @@ def configure_intl(o):
819
942
# this is the icudt*.dat file which node will be using (platform endianness)
820
943
o ['variables' ]['icu_data_file' ] = icu_data_file
821
944
if not os .path .isfile (icu_data_path ):
822
- print 'Error: ICU prebuilt data file %s does not exist.' % icu_data_path
823
- print 'See the README.md.'
945
+ print ' Error: ICU prebuilt data file %s does not exist.' % icu_data_path
946
+ print ' See the README.md.'
824
947
# .. and we're not about to build it from .gyp!
825
948
sys .exit (1 )
826
949
# map from variable name to subdirs
0 commit comments