Node_Escargot_Release_210713_97834f7
[platform/framework/web/lwnode.git] / configure.py
1 from __future__ import print_function
2
3 import json
4 import sys
5 import errno
6 import optparse
7 import os
8 import pipes
9 import pprint
10 import re
11 import shlex
12 import subprocess
13 import shutil
14 import bz2
15 import io
16
17 from distutils.spawn import find_executable as which
18 from distutils.version import StrictVersion
19
20 # If not run from node/, cd to node/.
21 os.chdir(os.path.dirname(__file__) or '.')
22
23 original_argv = sys.argv[1:]
24
25 # gcc and g++ as defaults matches what GYP's Makefile generator does,
26 # except on OS X.
27 CC = os.environ.get('CC', 'cc' if sys.platform == 'darwin' else 'gcc')
28 CXX = os.environ.get('CXX', 'c++' if sys.platform == 'darwin' else 'g++')
29
30 sys.path.insert(0, os.path.join('tools', 'gyp', 'pylib'))
31 from gyp.common import GetFlavor
32
33 # imports in tools/configure.d
34 sys.path.insert(0, os.path.join('tools', 'configure.d'))
35 import nodedownload
36
37 # imports in tools/
38 sys.path.insert(0, 'tools')
39 import getmoduleversion
40 import getnapibuildversion
41 from gyp_node import run_gyp
42
43 # imports in deps/v8/tools/node
44 sys.path.insert(0, os.path.join('deps', 'v8', 'tools', 'node'))
45 from fetch_deps import FetchDeps
46
47 # parse our options
48 parser = optparse.OptionParser()
49
50 valid_os = ('win', 'mac', 'solaris', 'freebsd', 'openbsd', 'linux',
51             'android', 'aix', 'cloudabi')
52 valid_arch = ('arm', 'arm64', 'ia32', 'mips', 'mipsel', 'mips64el', 'ppc',
53               'ppc64', 'x32','x64', 'x86', 'x86_64', 's390x')
54 valid_arm_float_abi = ('soft', 'softfp', 'hard')
55 valid_arm_fpu = ('vfp', 'vfpv3', 'vfpv3-d16', 'neon')
56 valid_mips_arch = ('loongson', 'r1', 'r2', 'r6', 'rx')
57 valid_mips_fpu = ('fp32', 'fp64', 'fpxx')
58 valid_mips_float_abi = ('soft', 'hard')
59 valid_intl_modes = ('none', 'small-icu', 'full-icu', 'system-icu')
60 with open ('tools/icu/icu_versions.json') as f:
61   icu_versions = json.load(f)
62
63 # create option groups
64 shared_optgroup = optparse.OptionGroup(parser, "Shared libraries",
65     "Flags that allows you to control whether you want to build against "
66     "built-in dependencies or its shared representations. If necessary, "
67     "provide multiple libraries with comma.")
68 intl_optgroup = optparse.OptionGroup(parser, "Internationalization",
69     "Flags that lets you enable i18n features in Node.js as well as which "
70     "library you want to build against.")
71 http2_optgroup = optparse.OptionGroup(parser, "HTTP2",
72     "Flags that allows you to control HTTP2 features in Node.js")
73
74 # @lwnode
75 lwnode_optgroup = optparse.OptionGroup(parser, "LightWeight Node.js",
76     "Flags that allows you to control LWNode.js build options")
77
78 lwnode_optgroup.add_option('--engine',
79     action='store',
80     dest='engine',
81     default=False,
82     help='Use escargot JS engine)')
83
84 lwnode_optgroup.add_option('--tizen',
85     action='store_true',
86     dest='tizen',
87     default=False,
88     help='Platform: tizen')
89
90 lwnode_optgroup.add_option('--profile',
91     choices=['none', 'tv', 'kiosk'],
92     default='none',
93     help='Build profile: none | tv | kiosk')
94
95 lwnode_optgroup.add_option('--enable-external-builtin-scripts',
96     action='store_true',
97     dest='enable_external_builtin_scripts',
98     default=False,
99     help='Store builtin scripts outside of executable')
100
101 lwnode_optgroup.add_option('--static-escargot',
102     action='store_true',
103     dest='static_escargot',
104     help='link to a static escargot instead of shared linking')
105
106 parser.add_option_group(lwnode_optgroup)
107
108 def get_lwnode_gyp_options():
109   args = []
110
111   if options.debug:
112     args += ['-Dbuild_mode=debug']
113   else:
114     args += ['-Dbuild_mode=release']
115
116   if options.engine == 'escargot' :
117     args += ['-Dlwnode='+ 'true']
118
119     lwnode_jsengine_path = 'lwnode/code/escargotshim'
120     args += ['-Dlwnode_jsengine_path='+ lwnode_jsengine_path]
121
122     if options.enable_external_builtin_scripts:
123       args += ['-Denable_external_builtin_scripts=true']
124     else:
125       args += ['-Denable_external_builtin_scripts=false']
126   else:
127     args += ['-Dlwnode='+ 'false']
128
129   if options.tizen:
130     args += ['-Dtarget_os=tizen']
131     args += ['-Dprofile='+ str(options.profile)]
132     args += ['-Descargot_host=tizen_obs']
133   else:
134     args += ['-Dtarget_os=linux']
135
136   if options.static_escargot:
137     args += (['-Descargot_lib_type=static_lib'])
138   else:
139     args += (['-Descargot_lib_type=shared_lib'])
140
141   args += ['-Dnode_core_target_name=lwnode']
142   args += ['-Dnode_lib_target_name=liblwnode']
143
144   options.verbose = True
145   print_verbose("LWNode.js options: [" + " ".join(str(x) for x in args) + "]")
146   options.verbose = False
147
148   return args
149 # end of @lwnode
150
151 # Options should be in alphabetical order but keep --prefix at the top,
152 # that's arguably the one people will be looking for most.
153 parser.add_option('--prefix',
154     action='store',
155     dest='prefix',
156     default='/usr/local',
157     help='select the install prefix [default: %default]')
158
159 parser.add_option('--coverage',
160     action='store_true',
161     dest='coverage',
162     help='Build node with code coverage enabled')
163
164 parser.add_option('--debug',
165     action='store_true',
166     dest='debug',
167     help='also build debug build')
168
169 parser.add_option('--debug-node',
170     action='store_true',
171     dest='debug_node',
172     help='build the Node.js part of the binary with debugging symbols')
173
174 parser.add_option('--dest-cpu',
175     action='store',
176     dest='dest_cpu',
177     choices=valid_arch,
178     help='CPU architecture to build for ({0})'.format(', '.join(valid_arch)))
179
180 parser.add_option('--cross-compiling',
181     action='store_true',
182     dest='cross_compiling',
183     default=None,
184     help='force build to be considered as cross compiled')
185 parser.add_option('--no-cross-compiling',
186     action='store_false',
187     dest='cross_compiling',
188     default=None,
189     help='force build to be considered as NOT cross compiled')
190
191 parser.add_option('--dest-os',
192     action='store',
193     dest='dest_os',
194     choices=valid_os,
195     help='operating system to build for ({0})'.format(', '.join(valid_os)))
196
197 parser.add_option('--error-on-warn',
198     action='store_true',
199     dest='error_on_warn',
200     help='Turn compiler warnings into errors for node core sources.')
201
202 parser.add_option('--gdb',
203     action='store_true',
204     dest='gdb',
205     help='add gdb support')
206
207 parser.add_option('--no-ifaddrs',
208     action='store_true',
209     dest='no_ifaddrs',
210     help='use on deprecated SunOS systems that do not support ifaddrs.h')
211
212 parser.add_option("--fully-static",
213     action="store_true",
214     dest="fully_static",
215     help="Generate an executable without external dynamic libraries. This "
216          "will not work on OSX when using the default compilation environment")
217
218 parser.add_option("--partly-static",
219     action="store_true",
220     dest="partly_static",
221     help="Generate an executable with libgcc and libstdc++ libraries. This "
222          "will not work on OSX when using the default compilation environment")
223
224 parser.add_option("--enable-pgo-generate",
225     action="store_true",
226     dest="enable_pgo_generate",
227     help="Enable profiling with pgo of a binary. This feature is only available "
228          "on linux with gcc and g++ 5.4.1 or newer.")
229
230 parser.add_option("--enable-pgo-use",
231     action="store_true",
232     dest="enable_pgo_use",
233     help="Enable use of the profile generated with --enable-pgo-generate. This "
234          "feature is only available on linux with gcc and g++ 5.4.1 or newer.")
235
236 parser.add_option("--enable-lto",
237     action="store_true",
238     dest="enable_lto",
239     help="Enable compiling with lto of a binary. This feature is only available "
240          "on linux with gcc and g++ 5.4.1 or newer.")
241
242 parser.add_option("--link-module",
243     action="append",
244     dest="linked_module",
245     help="Path to a JS file to be bundled in the binary as a builtin. "
246          "This module will be referenced by path without extension; "
247          "e.g. /root/x/y.js will be referenced via require('root/x/y'). "
248          "Can be used multiple times")
249
250 parser.add_option('--openssl-default-cipher-list',
251     action='store',
252     dest='openssl_default_cipher_list',
253     help='Use the specified cipher list as the default cipher list')
254
255 parser.add_option("--openssl-no-asm",
256     action="store_true",
257     dest="openssl_no_asm",
258     help="Do not build optimized assembly for OpenSSL")
259
260 parser.add_option('--openssl-fips',
261     action='store',
262     dest='openssl_fips',
263     help='Build OpenSSL using FIPS canister .o file in supplied folder')
264
265 parser.add_option('--openssl-is-fips',
266     action='store_true',
267     dest='openssl_is_fips',
268     help='specifies that the OpenSSL library is FIPS compatible')
269
270 parser.add_option('--openssl-use-def-ca-store',
271     action='store_true',
272     dest='use_openssl_ca_store',
273     help='Use OpenSSL supplied CA store instead of compiled-in Mozilla CA copy.')
274
275 parser.add_option('--openssl-system-ca-path',
276     action='store',
277     dest='openssl_system_ca_path',
278     help='Use the specified path to system CA (PEM format) in addition to '
279          'the OpenSSL supplied CA store or compiled-in Mozilla CA copy.')
280
281 parser.add_option('--experimental-http-parser',
282     action='store_true',
283     dest='experimental_http_parser',
284     help='(no-op)')
285
286 shared_optgroup.add_option('--shared-http-parser',
287     action='store_true',
288     dest='shared_http_parser',
289     help='link to a shared http_parser DLL instead of static linking')
290
291 shared_optgroup.add_option('--shared-http-parser-includes',
292     action='store',
293     dest='shared_http_parser_includes',
294     help='directory containing http_parser header files')
295
296 shared_optgroup.add_option('--shared-http-parser-libname',
297     action='store',
298     dest='shared_http_parser_libname',
299     default='http_parser',
300     help='alternative lib name to link to [default: %default]')
301
302 shared_optgroup.add_option('--shared-http-parser-libpath',
303     action='store',
304     dest='shared_http_parser_libpath',
305     help='a directory to search for the shared http_parser DLL')
306
307 shared_optgroup.add_option('--shared-libuv',
308     action='store_true',
309     dest='shared_libuv',
310     help='link to a shared libuv DLL instead of static linking')
311
312 shared_optgroup.add_option('--shared-libuv-includes',
313     action='store',
314     dest='shared_libuv_includes',
315     help='directory containing libuv header files')
316
317 shared_optgroup.add_option('--shared-libuv-libname',
318     action='store',
319     dest='shared_libuv_libname',
320     default='uv',
321     help='alternative lib name to link to [default: %default]')
322
323 shared_optgroup.add_option('--shared-libuv-libpath',
324     action='store',
325     dest='shared_libuv_libpath',
326     help='a directory to search for the shared libuv DLL')
327
328 shared_optgroup.add_option('--shared-nghttp2',
329     action='store_true',
330     dest='shared_nghttp2',
331     help='link to a shared nghttp2 DLL instead of static linking')
332
333 shared_optgroup.add_option('--shared-nghttp2-includes',
334     action='store',
335     dest='shared_nghttp2_includes',
336     help='directory containing nghttp2 header files')
337
338 shared_optgroup.add_option('--shared-nghttp2-libname',
339     action='store',
340     dest='shared_nghttp2_libname',
341     default='nghttp2',
342     help='alternative lib name to link to [default: %default]')
343
344 shared_optgroup.add_option('--shared-nghttp2-libpath',
345     action='store',
346     dest='shared_nghttp2_libpath',
347     help='a directory to search for the shared nghttp2 DLLs')
348
349 shared_optgroup.add_option('--shared-openssl',
350     action='store_true',
351     dest='shared_openssl',
352     help='link to a shared OpenSSl DLL instead of static linking')
353
354 shared_optgroup.add_option('--shared-openssl-includes',
355     action='store',
356     dest='shared_openssl_includes',
357     help='directory containing OpenSSL header files')
358
359 shared_optgroup.add_option('--shared-openssl-libname',
360     action='store',
361     dest='shared_openssl_libname',
362     default='crypto,ssl',
363     help='alternative lib name to link to [default: %default]')
364
365 shared_optgroup.add_option('--shared-openssl-libpath',
366     action='store',
367     dest='shared_openssl_libpath',
368     help='a directory to search for the shared OpenSSL DLLs')
369
370 shared_optgroup.add_option('--shared-zlib',
371     action='store_true',
372     dest='shared_zlib',
373     help='link to a shared zlib DLL instead of static linking')
374
375 shared_optgroup.add_option('--shared-zlib-includes',
376     action='store',
377     dest='shared_zlib_includes',
378     help='directory containing zlib header files')
379
380 shared_optgroup.add_option('--shared-zlib-libname',
381     action='store',
382     dest='shared_zlib_libname',
383     default='z',
384     help='alternative lib name to link to [default: %default]')
385
386 shared_optgroup.add_option('--shared-zlib-libpath',
387     action='store',
388     dest='shared_zlib_libpath',
389     help='a directory to search for the shared zlib DLL')
390
391 shared_optgroup.add_option('--shared-brotli',
392     action='store_true',
393     dest='shared_brotli',
394     help='link to a shared brotli DLL instead of static linking')
395
396 shared_optgroup.add_option('--shared-brotli-includes',
397     action='store',
398     dest='shared_brotli_includes',
399     help='directory containing brotli header files')
400
401 shared_optgroup.add_option('--shared-brotli-libname',
402     action='store',
403     dest='shared_brotli_libname',
404     default='brotlidec,brotlienc',
405     help='alternative lib name to link to [default: %default]')
406
407 shared_optgroup.add_option('--shared-brotli-libpath',
408     action='store',
409     dest='shared_brotli_libpath',
410     help='a directory to search for the shared brotli DLL')
411
412 shared_optgroup.add_option('--shared-cares',
413     action='store_true',
414     dest='shared_cares',
415     help='link to a shared cares DLL instead of static linking')
416
417 shared_optgroup.add_option('--shared-cares-includes',
418     action='store',
419     dest='shared_cares_includes',
420     help='directory containing cares header files')
421
422 shared_optgroup.add_option('--shared-cares-libname',
423     action='store',
424     dest='shared_cares_libname',
425     default='cares',
426     help='alternative lib name to link to [default: %default]')
427
428 shared_optgroup.add_option('--shared-cares-libpath',
429     action='store',
430     dest='shared_cares_libpath',
431     help='a directory to search for the shared cares DLL')
432
433 parser.add_option_group(shared_optgroup)
434
435 parser.add_option('--systemtap-includes',
436     action='store',
437     dest='systemtap_includes',
438     help='directory containing systemtap header files')
439
440 parser.add_option('--tag',
441     action='store',
442     dest='tag',
443     help='custom build tag')
444
445 parser.add_option('--release-urlbase',
446     action='store',
447     dest='release_urlbase',
448     help='Provide a custom URL prefix for the `process.release` properties '
449          '`sourceUrl` and `headersUrl`. When compiling a release build, this '
450          'will default to https://nodejs.org/download/release/')
451
452 parser.add_option('--enable-d8',
453     action='store_true',
454     dest='enable_d8',
455     help=optparse.SUPPRESS_HELP)  # Unsupported, undocumented.
456
457 parser.add_option('--enable-trace-maps',
458     action='store_true',
459     dest='trace_maps',
460     help='Enable the --trace-maps flag in V8 (use at your own risk)')
461
462 parser.add_option('--experimental-enable-pointer-compression',
463     action='store_true',
464     dest='enable_pointer_compression',
465     help='[Experimental] Enable V8 pointer compression (limits max heap to 4GB and breaks ABI compatibility)')
466
467 parser.add_option('--v8-options',
468     action='store',
469     dest='v8_options',
470     help='v8 options to pass, see `node --v8-options` for examples.')
471
472 parser.add_option('--with-ossfuzz',
473     action='store_true',
474     dest='ossfuzz',
475     help='Enables building of fuzzers. This command should be run in an OSS-Fuzz Docker image.')
476
477 parser.add_option('--with-arm-float-abi',
478     action='store',
479     dest='arm_float_abi',
480     choices=valid_arm_float_abi,
481     help='specifies which floating-point ABI to use ({0}).'.format(
482         ', '.join(valid_arm_float_abi)))
483
484 parser.add_option('--with-arm-fpu',
485     action='store',
486     dest='arm_fpu',
487     choices=valid_arm_fpu,
488     help='ARM FPU mode ({0}) [default: %default]'.format(
489         ', '.join(valid_arm_fpu)))
490
491 parser.add_option('--with-mips-arch-variant',
492     action='store',
493     dest='mips_arch_variant',
494     default='r2',
495     choices=valid_mips_arch,
496     help='MIPS arch variant ({0}) [default: %default]'.format(
497         ', '.join(valid_mips_arch)))
498
499 parser.add_option('--with-mips-fpu-mode',
500     action='store',
501     dest='mips_fpu_mode',
502     default='fp32',
503     choices=valid_mips_fpu,
504     help='MIPS FPU mode ({0}) [default: %default]'.format(
505         ', '.join(valid_mips_fpu)))
506
507 parser.add_option('--with-mips-float-abi',
508     action='store',
509     dest='mips_float_abi',
510     default='hard',
511     choices=valid_mips_float_abi,
512     help='MIPS floating-point ABI ({0}) [default: %default]'.format(
513         ', '.join(valid_mips_float_abi)))
514
515 parser.add_option('--with-dtrace',
516     action='store_true',
517     dest='with_dtrace',
518     help='build with DTrace (default is true on sunos and darwin)')
519
520 parser.add_option('--with-etw',
521     action='store_true',
522     dest='with_etw',
523     help='build with ETW (default is true on Windows)')
524
525 parser.add_option('--use-largepages',
526     action='store_true',
527     dest='node_use_large_pages',
528     help='This option has no effect. --use-largepages is now a runtime option.')
529
530 parser.add_option('--use-largepages-script-lld',
531     action='store_true',
532     dest='node_use_large_pages_script_lld',
533     help='This option has no effect. --use-largepages is now a runtime option.')
534
535 parser.add_option('--use-section-ordering-file',
536     action='store',
537     dest='node_section_ordering_info',
538     default='',
539     help='Pass a section ordering file to the linker. This requires that ' +
540          'Node.js be linked using the gold linker. The gold linker must have ' +
541          'version 1.2 or greater.')
542
543 intl_optgroup.add_option('--with-intl',
544     action='store',
545     dest='with_intl',
546     default='full-icu',
547     choices=valid_intl_modes,
548     help='Intl mode (valid choices: {0}) [default: %default]'.format(
549         ', '.join(valid_intl_modes)))
550
551 intl_optgroup.add_option('--without-intl',
552     action='store_const',
553     dest='with_intl',
554     const='none',
555     help='Disable Intl, same as --with-intl=none (disables inspector)')
556
557 intl_optgroup.add_option('--with-icu-path',
558     action='store',
559     dest='with_icu_path',
560     help='Path to icu.gyp (ICU i18n, Chromium version only.)')
561
562 icu_default_locales='root,en'
563
564 intl_optgroup.add_option('--with-icu-locales',
565     action='store',
566     dest='with_icu_locales',
567     default=icu_default_locales,
568     help='Comma-separated list of locales for "small-icu". "root" is assumed. '
569         '[default: %default]')
570
571 intl_optgroup.add_option('--with-icu-source',
572     action='store',
573     dest='with_icu_source',
574     help='Intl mode: optional local path to icu/ dir, or path/URL of '
575         'the icu4c source archive. '
576         'v%d.x or later recommended.' % icu_versions['minimum_icu'])
577
578 intl_optgroup.add_option('--with-icu-default-data-dir',
579     action='store',
580     dest='with_icu_default_data_dir',
581     help='Path to the icuXXdt{lb}.dat file. If unspecified, ICU data will '
582          'only be read if the NODE_ICU_DATA environment variable or the '
583          '--icu-data-dir runtime argument is used. This option has effect '
584          'only when Node.js is built with --with-intl=small-icu.')
585
586 parser.add_option('--with-ltcg',
587     action='store_true',
588     dest='with_ltcg',
589     help='Use Link Time Code Generation. This feature is only available on Windows.')
590
591 parser.add_option('--without-node-snapshot',
592     action='store_true',
593     dest='without_node_snapshot',
594     help='Turn off V8 snapshot integration. Currently experimental.')
595
596 parser.add_option('--without-node-code-cache',
597     action='store_true',
598     dest='without_node_code_cache',
599     help='Turn off V8 Code cache integration.')
600
601 intl_optgroup.add_option('--download',
602     action='store',
603     dest='download_list',
604     help=nodedownload.help())
605
606 intl_optgroup.add_option('--download-path',
607     action='store',
608     dest='download_path',
609     default='deps',
610     help='Download directory [default: %default]')
611
612 parser.add_option_group(intl_optgroup)
613
614 parser.add_option('--debug-lib',
615     action='store_true',
616     dest='node_debug_lib',
617     help='build lib with DCHECK macros')
618
619 http2_optgroup.add_option('--debug-nghttp2',
620     action='store_true',
621     dest='debug_nghttp2',
622     help='build nghttp2 with DEBUGBUILD (default is false)')
623
624 parser.add_option_group(http2_optgroup)
625
626 parser.add_option('--without-dtrace',
627     action='store_true',
628     dest='without_dtrace',
629     help='build without DTrace')
630
631 parser.add_option('--without-etw',
632     action='store_true',
633     dest='without_etw',
634     help='build without ETW')
635
636 parser.add_option('--without-npm',
637     action='store_true',
638     dest='without_npm',
639     help='do not install the bundled npm (package manager)')
640
641 # Dummy option for backwards compatibility
642 parser.add_option('--without-report',
643     action='store_true',
644     dest='unused_without_report',
645     help=optparse.SUPPRESS_HELP)
646
647 parser.add_option('--with-snapshot',
648     action='store_true',
649     dest='unused_with_snapshot',
650     help=optparse.SUPPRESS_HELP)
651
652 parser.add_option('--without-snapshot',
653     action='store_true',
654     dest='unused_without_snapshot',
655     help=optparse.SUPPRESS_HELP)
656
657 parser.add_option('--without-siphash',
658     action='store_true',
659     dest='without_siphash',
660     help=optparse.SUPPRESS_HELP)
661
662 # End dummy list.
663
664 parser.add_option('--without-ssl',
665     action='store_true',
666     dest='without_ssl',
667     help='build without SSL (disables crypto, https, inspector, etc.)')
668
669 parser.add_option('--without-node-options',
670     action='store_true',
671     dest='without_node_options',
672     help='build without NODE_OPTIONS support')
673
674 parser.add_option('--ninja',
675     action='store_true',
676     dest='use_ninja',
677     help='generate build files for use with Ninja')
678
679 parser.add_option('--enable-asan',
680     action='store_true',
681     dest='enable_asan',
682     help='compile for Address Sanitizer to find memory bugs')
683
684 parser.add_option('--enable-static',
685     action='store_true',
686     dest='enable_static',
687     help='build as static library')
688
689 parser.add_option('--no-browser-globals',
690     action='store_true',
691     dest='no_browser_globals',
692     help='do not export browser globals like setTimeout, console, etc. ' +
693          '(This mode is not officially supported for regular applications)')
694
695 parser.add_option('--without-inspector',
696     action='store_true',
697     dest='without_inspector',
698     help='disable the V8 inspector protocol')
699
700 parser.add_option('--shared',
701     action='store_true',
702     dest='shared',
703     help='compile shared library for embedding node in another project. ' +
704          '(This mode is not officially supported for regular applications)')
705
706 parser.add_option('--without-v8-platform',
707     action='store_true',
708     dest='without_v8_platform',
709     default=False,
710     help='do not initialize v8 platform during node.js startup. ' +
711          '(This mode is not officially supported for regular applications)')
712
713 parser.add_option('--without-bundled-v8',
714     action='store_true',
715     dest='without_bundled_v8',
716     default=False,
717     help='do not use V8 includes from the bundled deps folder. ' +
718          '(This mode is not officially supported for regular applications)')
719
720 parser.add_option('--build-v8-with-gn',
721     action='store_true',
722     dest='build_v8_with_gn',
723     default=False,
724     help='build V8 using GN instead of gyp')
725
726 parser.add_option('--verbose',
727     action='store_true',
728     dest='verbose',
729     default=False,
730     help='get more output from this script')
731
732 parser.add_option('--v8-non-optimized-debug',
733     action='store_true',
734     dest='v8_non_optimized_debug',
735     default=False,
736     help='compile V8 with minimal optimizations and with runtime checks')
737
738 parser.add_option('--v8-with-dchecks',
739     action='store_true',
740     dest='v8_with_dchecks',
741     default=False,
742     help='compile V8 with debug checks and runtime debugging features enabled')
743
744 parser.add_option('--v8-lite-mode',
745     action='store_true',
746     dest='v8_lite_mode',
747     default=False,
748     help='compile V8 in lite mode for constrained environments (lowers V8 '+
749          'memory footprint, but also implies no just-in-time compilation ' +
750          'support, thus much slower execution)')
751
752 parser.add_option('--v8-enable-object-print',
753     action='store_true',
754     dest='v8_enable_object_print',
755     default=True,
756     help='compile V8 with auxiliar functions for native debuggers')
757
758 parser.add_option('--node-builtin-modules-path',
759     action='store',
760     dest='node_builtin_modules_path',
761     default=False,
762     help='node will load builtin modules from disk instead of from binary')
763
764 # Create compile_commands.json in out/Debug and out/Release.
765 parser.add_option('-C',
766     action='store_true',
767     dest='compile_commands_json',
768     help=optparse.SUPPRESS_HELP)
769
770 (options, args) = parser.parse_args()
771
772 # Expand ~ in the install prefix now, it gets written to multiple files.
773 options.prefix = os.path.expanduser(options.prefix or '')
774
775 # set up auto-download list
776 auto_downloads = nodedownload.parse(options.download_list)
777
778
779 def error(msg):
780   prefix = '\033[1m\033[31mERROR\033[0m' if os.isatty(1) else 'ERROR'
781   print('%s: %s' % (prefix, msg))
782   sys.exit(1)
783
784 def warn(msg):
785   warn.warned = True
786   prefix = '\033[1m\033[93mWARNING\033[0m' if os.isatty(1) else 'WARNING'
787   print('%s: %s' % (prefix, msg))
788
789 # track if warnings occurred
790 warn.warned = False
791
792 def info(msg):
793   prefix = '\033[1m\033[32mINFO\033[0m' if os.isatty(1) else 'INFO'
794   print('%s: %s' % (prefix, msg))
795
796 def print_verbose(x):
797   if not options.verbose:
798     return
799   if type(x) is str:
800     print(x)
801   else:
802     pprint.pprint(x, indent=2)
803
804 def b(value):
805   """Returns the string 'true' if value is truthy, 'false' otherwise."""
806   return 'true' if value else 'false'
807
808 def B(value):
809   """Returns 1 if value is truthy, 0 otherwise."""
810   return 1 if value else 0
811
812 def to_utf8(s):
813   return s if isinstance(s, str) else s.decode("utf-8")
814
815 def pkg_config(pkg):
816   """Run pkg-config on the specified package
817   Returns ("-l flags", "-I flags", "-L flags", "version")
818   otherwise (None, None, None, None)"""
819   pkg_config = os.environ.get('PKG_CONFIG', 'pkg-config')
820   args = []  # Print pkg-config warnings on first round.
821   retval = ()
822   for flag in ['--libs-only-l', '--cflags-only-I',
823                '--libs-only-L', '--modversion']:
824     args += [flag]
825     if isinstance(pkg, list):
826       args += pkg
827     else:
828       args += [pkg]
829     try:
830       proc = subprocess.Popen(shlex.split(pkg_config) + args,
831                               stdout=subprocess.PIPE)
832       val = to_utf8(proc.communicate()[0]).strip()
833     except OSError as e:
834       if e.errno != errno.ENOENT: raise e  # Unexpected error.
835       return (None, None, None, None)  # No pkg-config/pkgconf installed.
836     retval += (val,)
837     args = ['--silence-errors']
838   return retval
839
840
841 def try_check_compiler(cc, lang):
842   try:
843     proc = subprocess.Popen(shlex.split(cc) + ['-E', '-P', '-x', lang, '-'],
844                             stdin=subprocess.PIPE, stdout=subprocess.PIPE)
845   except OSError:
846     return (False, False, '', '')
847
848   proc.stdin.write(b'__clang__ __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ '
849                    b'__clang_major__ __clang_minor__ __clang_patchlevel__')
850
851   values = (to_utf8(proc.communicate()[0]).split() + ['0'] * 7)[0:7]
852   is_clang = values[0] == '1'
853   gcc_version = tuple(map(int, values[1:1+3]))
854   clang_version = tuple(map(int, values[4:4+3])) if is_clang else None
855
856   return (True, is_clang, clang_version, gcc_version)
857
858
859 #
860 # The version of asm compiler is needed for building openssl asm files.
861 # See deps/openssl/openssl.gypi for detail.
862 # Commands and regular expressions to obtain its version number are taken from
863 # https://github.com/openssl/openssl/blob/OpenSSL_1_0_2-stable/crypto/sha/asm/sha512-x86_64.pl#L112-L129
864 #
865 def get_version_helper(cc, regexp):
866   try:
867     proc = subprocess.Popen(shlex.split(cc) + ['-v'], stdin=subprocess.PIPE,
868                             stderr=subprocess.PIPE, stdout=subprocess.PIPE)
869   except OSError:
870     error('''No acceptable C compiler found!
871
872        Please make sure you have a C compiler installed on your system and/or
873        consider adjusting the CC environment variable if you installed
874        it in a non-standard prefix.''')
875
876   match = re.search(regexp, to_utf8(proc.communicate()[1]))
877
878   if match:
879     return match.group(2)
880   else:
881     return '0.0'
882
883 def get_nasm_version(asm):
884   try:
885     proc = subprocess.Popen(shlex.split(asm) + ['-v'],
886                             stdin=subprocess.PIPE, stderr=subprocess.PIPE,
887                             stdout=subprocess.PIPE)
888   except OSError:
889     warn('''No acceptable ASM compiler found!
890          Please make sure you have installed NASM from https://www.nasm.us
891          and refer BUILDING.md.''')
892     return '0.0'
893
894   match = re.match(r"NASM version ([2-9]\.[0-9][0-9]+)",
895                    to_utf8(proc.communicate()[0]))
896
897   if match:
898     return match.group(1)
899   else:
900     return '0.0'
901
902 def get_llvm_version(cc):
903   return get_version_helper(
904     cc, r"(^(?:.+ )?clang version|based on LLVM) ([0-9]+\.[0-9]+)")
905
906 def get_xcode_version(cc):
907   return get_version_helper(
908     cc, r"(^Apple (?:clang|LLVM) version) ([0-9]+\.[0-9]+)")
909
910 def get_gas_version(cc):
911   try:
912     custom_env = os.environ.copy()
913     custom_env["LC_ALL"] = "C"
914     proc = subprocess.Popen(shlex.split(cc) + ['-Wa,-v', '-c', '-o',
915                                                '/dev/null', '-x',
916                                                'assembler',  '/dev/null'],
917                             stdin=subprocess.PIPE, stderr=subprocess.PIPE,
918                             stdout=subprocess.PIPE, env=custom_env)
919   except OSError:
920     error('''No acceptable C compiler found!
921
922        Please make sure you have a C compiler installed on your system and/or
923        consider adjusting the CC environment variable if you installed
924        it in a non-standard prefix.''')
925
926   gas_ret = to_utf8(proc.communicate()[1])
927   match = re.match(r"GNU assembler version ([2-9]\.[0-9]+)", gas_ret)
928
929   if match:
930     return match.group(1)
931   else:
932     warn('Could not recognize `gas`: ' + gas_ret)
933     return '0.0'
934
935 # Note: Apple clang self-reports as clang 4.2.0 and gcc 4.2.1.  It passes
936 # the version check more by accident than anything else but a more rigorous
937 # check involves checking the build number against a whitelist.  I'm not
938 # quite prepared to go that far yet.
939 def check_compiler(o):
940   if sys.platform == 'win32':
941     if not options.openssl_no_asm and options.dest_cpu in ('x86', 'x64'):
942       nasm_version = get_nasm_version('nasm')
943       o['variables']['nasm_version'] = nasm_version
944       if nasm_version == '0.0':
945         o['variables']['openssl_no_asm'] = 1
946     return
947
948   ok, is_clang, clang_version, gcc_version = try_check_compiler(CXX, 'c++')
949   version_str = ".".join(map(str, clang_version if is_clang else gcc_version))
950   print_verbose('Detected %sC++ compiler (CXX=%s) version: %s' %
951                 ('clang ' if is_clang else '', CXX, version_str))
952   if not ok:
953     warn('failed to autodetect C++ compiler version (CXX=%s)' % CXX)
954   elif clang_version < (8, 0, 0) if is_clang else gcc_version < (6, 3, 0):
955     warn('C++ compiler (CXX=%s, %s) too old, need g++ 6.3.0 or clang++ 8.0.0' %
956          (CXX, version_str))
957
958   ok, is_clang, clang_version, gcc_version = try_check_compiler(CC, 'c')
959   version_str = ".".join(map(str, clang_version if is_clang else gcc_version))
960   print_verbose('Detected %sC compiler (CC=%s) version: %s' %
961                 ('clang ' if is_clang else '', CC, version_str))
962   if not ok:
963     warn('failed to autodetect C compiler version (CC=%s)' % CC)
964   elif not is_clang and gcc_version < (4, 2, 0):
965     # clang 3.2 is a little white lie because any clang version will probably
966     # do for the C bits.  However, we might as well encourage people to upgrade
967     # to a version that is not completely ancient.
968     warn('C compiler (CC=%s, %s) too old, need gcc 4.2 or clang 3.2' %
969          (CC, version_str))
970
971   o['variables']['llvm_version'] = get_llvm_version(CC) if is_clang else '0.0'
972
973   # Need xcode_version or gas_version when openssl asm files are compiled.
974   if options.without_ssl or options.openssl_no_asm or options.shared_openssl:
975     return
976
977   if is_clang:
978     if sys.platform == 'darwin':
979       o['variables']['xcode_version'] = get_xcode_version(CC)
980   else:
981     o['variables']['gas_version'] = get_gas_version(CC)
982
983
984 def cc_macros(cc=None):
985   """Checks predefined macros using the C compiler command."""
986
987   try:
988     p = subprocess.Popen(shlex.split(cc or CC) + ['-dM', '-E', '-'],
989                          stdin=subprocess.PIPE,
990                          stdout=subprocess.PIPE,
991                          stderr=subprocess.PIPE)
992   except OSError:
993     error('''No acceptable C compiler found!
994
995        Please make sure you have a C compiler installed on your system and/or
996        consider adjusting the CC environment variable if you installed
997        it in a non-standard prefix.''')
998
999   p.stdin.write(b'\n')
1000   out = to_utf8(p.communicate()[0]).split('\n')
1001
1002   k = {}
1003   for line in out:
1004     lst = shlex.split(line)
1005     if len(lst) > 2:
1006       key = lst[1]
1007       val = lst[2]
1008       k[key] = val
1009   return k
1010
1011
1012 def is_arch_armv7():
1013   """Check for ARMv7 instructions"""
1014   cc_macros_cache = cc_macros()
1015   return cc_macros_cache.get('__ARM_ARCH') == '7'
1016
1017
1018 def is_arch_armv6():
1019   """Check for ARMv6 instructions"""
1020   cc_macros_cache = cc_macros()
1021   return cc_macros_cache.get('__ARM_ARCH') == '6'
1022
1023
1024 def is_arm_hard_float_abi():
1025   """Check for hardfloat or softfloat eabi on ARM"""
1026   # GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
1027   # the Floating Point ABI used (PCS stands for Procedure Call Standard).
1028   # We use these as well as a couple of other defines to statically determine
1029   # what FP ABI used.
1030
1031   return '__ARM_PCS_VFP' in cc_macros()
1032
1033
1034 def host_arch_cc():
1035   """Host architecture check using the CC command."""
1036
1037   if sys.platform.startswith('aix'):
1038     # we only support gcc at this point and the default on AIX
1039     # would be xlc so hard code gcc
1040     k = cc_macros('gcc')
1041   else:
1042     k = cc_macros(os.environ.get('CC_host'))
1043
1044   matchup = {
1045     '__aarch64__' : 'arm64',
1046     '__arm__'     : 'arm',
1047     '__i386__'    : 'ia32',
1048     '__MIPSEL__'  : 'mipsel',
1049     '__mips__'    : 'mips',
1050     '__PPC64__'   : 'ppc64',
1051     '__PPC__'     : 'ppc64',
1052     '__x86_64__'  : 'x64',
1053     '__s390x__'   : 's390x',
1054   }
1055
1056   rtn = 'ia32' # default
1057
1058   for i in matchup:
1059     if i in k and k[i] != '0':
1060       rtn = matchup[i]
1061       break
1062
1063   if rtn == 'mipsel' and '_LP64' in k:
1064     rtn = 'mips64el'
1065
1066   return rtn
1067
1068
1069 def host_arch_win():
1070   """Host architecture check using environ vars (better way to do this?)"""
1071
1072   observed_arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
1073   arch = os.environ.get('PROCESSOR_ARCHITEW6432', observed_arch)
1074
1075   matchup = {
1076     'AMD64'  : 'x64',
1077     'x86'    : 'ia32',
1078     'arm'    : 'arm',
1079     'mips'   : 'mips',
1080   }
1081
1082   return matchup.get(arch, 'ia32')
1083
1084
1085 def configure_arm(o):
1086   if options.arm_float_abi:
1087     arm_float_abi = options.arm_float_abi
1088   elif is_arm_hard_float_abi():
1089     arm_float_abi = 'hard'
1090   else:
1091     arm_float_abi = 'default'
1092
1093   arm_fpu = 'vfp'
1094
1095   if is_arch_armv7():
1096     arm_fpu = 'vfpv3'
1097     o['variables']['arm_version'] = '7'
1098   else:
1099     o['variables']['arm_version'] = '6' if is_arch_armv6() else 'default'
1100
1101   o['variables']['arm_thumb'] = 0      # -marm
1102   o['variables']['arm_float_abi'] = arm_float_abi
1103
1104   if options.dest_os == 'android':
1105     arm_fpu = 'vfpv3'
1106     o['variables']['arm_version'] = '7'
1107
1108   o['variables']['arm_fpu'] = options.arm_fpu or arm_fpu
1109
1110
1111 def configure_mips(o, target_arch):
1112   can_use_fpu_instructions = (options.mips_float_abi != 'soft')
1113   o['variables']['v8_can_use_fpu_instructions'] = b(can_use_fpu_instructions)
1114   o['variables']['v8_use_mips_abi_hardfloat'] = b(can_use_fpu_instructions)
1115   o['variables']['mips_arch_variant'] = options.mips_arch_variant
1116   o['variables']['mips_fpu_mode'] = options.mips_fpu_mode
1117   host_byteorder = 'little' if target_arch in ('mipsel', 'mips64el') else 'big'
1118   o['variables']['v8_host_byteorder'] = host_byteorder
1119
1120
1121 def gcc_version_ge(version_checked):
1122   for compiler in [(CC, 'c'), (CXX, 'c++')]:
1123     ok, is_clang, clang_version, compiler_version = \
1124       try_check_compiler(compiler[0], compiler[1])
1125     if is_clang or compiler_version < version_checked:
1126       return False
1127   return True
1128
1129
1130 def configure_node(o):
1131   if options.dest_os == 'android':
1132     o['variables']['OS'] = 'android'
1133   o['variables']['node_prefix'] = options.prefix
1134   o['variables']['node_install_npm'] = b(not options.without_npm)
1135   o['variables']['debug_node'] = b(options.debug_node)
1136   o['default_configuration'] = 'Debug' if options.debug else 'Release'
1137   o['variables']['error_on_warn'] = b(options.error_on_warn)
1138
1139   host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
1140   target_arch = options.dest_cpu or host_arch
1141   # ia32 is preferred by the build tools (GYP) over x86 even if we prefer the latter
1142   # the Makefile resets this to x86 afterward
1143   if target_arch == 'x86':
1144     target_arch = 'ia32'
1145   # x86_64 is common across linuxes, allow it as an alias for x64
1146   if target_arch == 'x86_64':
1147     target_arch = 'x64'
1148   o['variables']['host_arch'] = host_arch
1149   o['variables']['target_arch'] = target_arch
1150   o['variables']['node_byteorder'] = sys.byteorder
1151
1152   cross_compiling = (options.cross_compiling
1153                      if options.cross_compiling is not None
1154                      else target_arch != host_arch)
1155   if cross_compiling:
1156     os.environ['GYP_CROSSCOMPILE'] = "1"
1157   if options.unused_without_snapshot:
1158     warn('building --without-snapshot is no longer possible')
1159
1160   o['variables']['want_separate_host_toolset'] = int(cross_compiling)
1161
1162   if options.without_node_snapshot or options.node_builtin_modules_path:
1163     o['variables']['node_use_node_snapshot'] = 'false'
1164   else:
1165     o['variables']['node_use_node_snapshot'] = b(
1166       not cross_compiling and not options.shared)
1167
1168   if options.without_node_code_cache or options.node_builtin_modules_path:
1169     o['variables']['node_use_node_code_cache'] = 'false'
1170   else:
1171     # TODO(refack): fix this when implementing embedded code-cache when cross-compiling.
1172     o['variables']['node_use_node_code_cache'] = b(
1173       not cross_compiling and not options.shared)
1174
1175   if target_arch == 'arm':
1176     configure_arm(o)
1177   elif target_arch in ('mips', 'mipsel', 'mips64el'):
1178     configure_mips(o, target_arch)
1179
1180   if flavor == 'aix':
1181     o['variables']['node_target_type'] = 'static_library'
1182
1183   if flavor != 'linux' and (options.enable_pgo_generate or options.enable_pgo_use):
1184     raise Exception(
1185       'The pgo option is supported only on linux.')
1186
1187   if flavor == 'linux':
1188     if options.enable_pgo_generate or options.enable_pgo_use:
1189       version_checked = (5, 4, 1)
1190       if not gcc_version_ge(version_checked):
1191         version_checked_str = ".".join(map(str, version_checked))
1192         raise Exception(
1193           'The options --enable-pgo-generate and --enable-pgo-use '
1194           'are supported for gcc and gxx %s or newer only.' % (version_checked_str))
1195
1196     if options.enable_pgo_generate and options.enable_pgo_use:
1197       raise Exception(
1198         'Only one of the --enable-pgo-generate or --enable-pgo-use options '
1199         'can be specified at a time. You would like to use '
1200         '--enable-pgo-generate first, profile node, and then recompile '
1201         'with --enable-pgo-use')
1202
1203   o['variables']['enable_pgo_generate'] = b(options.enable_pgo_generate)
1204   o['variables']['enable_pgo_use']      = b(options.enable_pgo_use)
1205
1206   if flavor != 'linux' and (options.enable_lto):
1207     raise Exception(
1208       'The lto option is supported only on linux.')
1209
1210   if flavor == 'linux':
1211     if options.enable_lto:
1212       version_checked = (5, 4, 1)
1213       if not gcc_version_ge(version_checked):
1214         version_checked_str = ".".join(map(str, version_checked))
1215         raise Exception(
1216           'The option --enable-lto is supported for gcc and gxx %s'
1217           ' or newer only.' % (version_checked_str))
1218
1219   o['variables']['enable_lto'] = b(options.enable_lto)
1220
1221   if flavor in ('solaris', 'mac', 'linux', 'freebsd'):
1222     use_dtrace = not options.without_dtrace
1223     # Don't enable by default on linux and freebsd
1224     if flavor in ('linux', 'freebsd'):
1225       use_dtrace = options.with_dtrace
1226
1227     if flavor == 'linux':
1228       if options.systemtap_includes:
1229         o['include_dirs'] += [options.systemtap_includes]
1230     o['variables']['node_use_dtrace'] = b(use_dtrace)
1231   elif options.with_dtrace:
1232     raise Exception(
1233        'DTrace is currently only supported on SunOS, MacOS or Linux systems.')
1234   else:
1235     o['variables']['node_use_dtrace'] = 'false'
1236
1237   if options.node_use_large_pages or options.node_use_large_pages_script_lld:
1238     warn('''The `--use-largepages` and `--use-largepages-script-lld` options
1239          have no effect during build time. Support for mapping to large pages is
1240          now a runtime option of Node.js. Run `node --use-largepages` or add
1241          `--use-largepages` to the `NODE_OPTIONS` environment variable once
1242          Node.js is built to enable mapping to large pages.''')
1243
1244   if options.no_ifaddrs:
1245     o['defines'] += ['SUNOS_NO_IFADDRS']
1246
1247   # By default, enable ETW on Windows.
1248   if flavor == 'win':
1249     o['variables']['node_use_etw'] = b(not options.without_etw)
1250   elif options.with_etw:
1251     raise Exception('ETW is only supported on Windows.')
1252   else:
1253     o['variables']['node_use_etw'] = 'false'
1254
1255   o['variables']['node_with_ltcg'] = b(options.with_ltcg)
1256   if flavor != 'win' and options.with_ltcg:
1257     raise Exception('Link Time Code Generation is only supported on Windows.')
1258
1259   if options.tag:
1260     o['variables']['node_tag'] = '-' + options.tag
1261   else:
1262     o['variables']['node_tag'] = ''
1263
1264   o['variables']['node_release_urlbase'] = options.release_urlbase or ''
1265
1266   if options.v8_options:
1267     o['variables']['node_v8_options'] = options.v8_options.replace('"', '\\"')
1268
1269   if options.enable_static:
1270     o['variables']['node_target_type'] = 'static_library'
1271
1272   o['variables']['node_debug_lib'] = b(options.node_debug_lib)
1273
1274   if options.debug_nghttp2:
1275     o['variables']['debug_nghttp2'] = 1
1276   else:
1277     o['variables']['debug_nghttp2'] = 'false'
1278
1279   o['variables']['node_no_browser_globals'] = b(options.no_browser_globals)
1280
1281   o['variables']['node_shared'] = b(options.shared)
1282   node_module_version = getmoduleversion.get_version()
1283
1284   if options.dest_os == 'android':
1285     shlib_suffix = 'so'
1286   elif sys.platform == 'darwin':
1287     shlib_suffix = '%s.dylib'
1288   elif sys.platform.startswith('aix'):
1289     shlib_suffix = '%s.a'
1290   else:
1291     shlib_suffix = 'so.%s'
1292   if '%s' in shlib_suffix:
1293     shlib_suffix %= node_module_version
1294
1295   o['variables']['node_module_version'] = int(node_module_version)
1296   o['variables']['shlib_suffix'] = shlib_suffix
1297
1298   if options.linked_module:
1299     o['variables']['library_files'] = options.linked_module
1300
1301   o['variables']['asan'] = int(options.enable_asan or 0)
1302
1303   if options.coverage:
1304     o['variables']['coverage'] = 'true'
1305   else:
1306     o['variables']['coverage'] = 'false'
1307
1308   if options.shared:
1309     o['variables']['node_target_type'] = 'shared_library'
1310   elif options.enable_static:
1311     o['variables']['node_target_type'] = 'static_library'
1312   else:
1313     o['variables']['node_target_type'] = 'executable'
1314
1315   if options.node_builtin_modules_path:
1316     print('Warning! Loading builtin modules from disk is for development')
1317     o['variables']['node_builtin_modules_path'] = options.node_builtin_modules_path
1318
1319 def configure_napi(output):
1320   version = getnapibuildversion.get_napi_version()
1321   output['variables']['napi_build_version'] = version
1322
1323 def configure_library(lib, output, pkgname=None):
1324   shared_lib = 'shared_' + lib
1325   output['variables']['node_' + shared_lib] = b(getattr(options, shared_lib))
1326
1327   if getattr(options, shared_lib):
1328     (pkg_libs, pkg_cflags, pkg_libpath, pkg_modversion) = (
1329         pkg_config(pkgname or lib))
1330
1331     if options.__dict__[shared_lib + '_includes']:
1332       output['include_dirs'] += [options.__dict__[shared_lib + '_includes']]
1333     elif pkg_cflags:
1334       stripped_flags = [flag.strip() for flag in pkg_cflags.split('-I')]
1335       output['include_dirs'] += [flag for flag in stripped_flags if flag]
1336
1337     # libpath needs to be provided ahead libraries
1338     if options.__dict__[shared_lib + '_libpath']:
1339       if flavor == 'win':
1340         if 'msvs_settings' not in output:
1341           output['msvs_settings'] = { 'VCLinkerTool': { 'AdditionalOptions': [] } }
1342         output['msvs_settings']['VCLinkerTool']['AdditionalOptions'] += [
1343           '/LIBPATH:%s' % options.__dict__[shared_lib + '_libpath']]
1344       else:
1345         output['libraries'] += [
1346             '-L%s' % options.__dict__[shared_lib + '_libpath']]
1347     elif pkg_libpath:
1348       output['libraries'] += [pkg_libpath]
1349
1350     default_libs = getattr(options, shared_lib + '_libname')
1351     default_libs = ['-l{0}'.format(l) for l in default_libs.split(',')]
1352
1353     if default_libs:
1354       output['libraries'] += default_libs
1355     elif pkg_libs:
1356       output['libraries'] += pkg_libs.split()
1357
1358
1359 def configure_v8(o):
1360   o['variables']['v8_enable_lite_mode'] = 1 if options.v8_lite_mode else 0
1361   o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
1362   o['variables']['v8_no_strict_aliasing'] = 1  # Work around compiler bugs.
1363   o['variables']['v8_optimized_debug'] = 0 if options.v8_non_optimized_debug else 1
1364   o['variables']['dcheck_always_on'] = 1 if options.v8_with_dchecks else 0
1365   o['variables']['v8_enable_object_print'] = 1 if options.v8_enable_object_print else 0
1366   o['variables']['v8_random_seed'] = 0  # Use a random seed for hash tables.
1367   o['variables']['v8_promise_internal_field_count'] = 1 # Add internal field to promises for async hooks.
1368   o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1
1369   o['variables']['v8_enable_pointer_compression'] = 1 if options.enable_pointer_compression else 0
1370   o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
1371   o['variables']['v8_trace_maps'] = 1 if options.trace_maps else 0
1372   o['variables']['node_use_v8_platform'] = b(not options.without_v8_platform)
1373   o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
1374   o['variables']['force_dynamic_crt'] = 1 if options.shared else 0
1375   o['variables']['node_enable_d8'] = b(options.enable_d8)
1376   if options.enable_d8:
1377     o['variables']['test_isolation_mode'] = 'noop'  # Needed by d8.gyp.
1378   if options.without_bundled_v8 and options.enable_d8:
1379     raise Exception('--enable-d8 is incompatible with --without-bundled-v8.')
1380   if options.without_bundled_v8 and options.build_v8_with_gn:
1381     raise Exception(
1382         '--build-v8-with-gn is incompatible with --without-bundled-v8.')
1383   if options.build_v8_with_gn:
1384     v8_path = os.path.join('deps', 'v8')
1385     print('Fetching dependencies to build V8 with GN')
1386     options.build_v8_with_gn = FetchDeps(v8_path)
1387   o['variables']['build_v8_with_gn'] = b(options.build_v8_with_gn)
1388
1389
1390 def configure_openssl(o):
1391   variables = o['variables']
1392   variables['node_use_openssl'] = b(not options.without_ssl)
1393   variables['node_shared_openssl'] = b(options.shared_openssl)
1394   variables['openssl_is_fips'] = b(options.openssl_is_fips)
1395   variables['openssl_fips'] = ''
1396
1397   if options.openssl_no_asm:
1398     variables['openssl_no_asm'] = 1
1399
1400   if options.without_ssl:
1401     def without_ssl_error(option):
1402       error('--without-ssl is incompatible with %s' % option)
1403     if options.shared_openssl:
1404       without_ssl_error('--shared-openssl')
1405     if options.openssl_no_asm:
1406       without_ssl_error('--openssl-no-asm')
1407     if options.openssl_fips:
1408       without_ssl_error('--openssl-fips')
1409     if options.openssl_default_cipher_list:
1410       without_ssl_error('--openssl-default-cipher-list')
1411     return
1412
1413   if options.use_openssl_ca_store:
1414     o['defines'] += ['NODE_OPENSSL_CERT_STORE']
1415   if options.openssl_system_ca_path:
1416     variables['openssl_system_ca_path'] = options.openssl_system_ca_path
1417   variables['node_without_node_options'] = b(options.without_node_options)
1418   if options.without_node_options:
1419       o['defines'] += ['NODE_WITHOUT_NODE_OPTIONS']
1420   if options.openssl_default_cipher_list:
1421     variables['openssl_default_cipher_list'] = \
1422             options.openssl_default_cipher_list
1423
1424   if not options.shared_openssl and not options.openssl_no_asm:
1425     is_x86 = 'x64' in variables['target_arch'] or 'ia32' in variables['target_arch']
1426
1427     # supported asm compiler for AVX2. See https://github.com/openssl/openssl/
1428     # blob/OpenSSL_1_1_0-stable/crypto/modes/asm/aesni-gcm-x86_64.pl#L52-L69
1429     openssl110_asm_supported = \
1430       ('gas_version' in variables and StrictVersion(variables['gas_version']) >= StrictVersion('2.23')) or \
1431       ('xcode_version' in variables and StrictVersion(variables['xcode_version']) >= StrictVersion('5.0')) or \
1432       ('llvm_version' in variables and StrictVersion(variables['llvm_version']) >= StrictVersion('3.3')) or \
1433       ('nasm_version' in variables and StrictVersion(variables['nasm_version']) >= StrictVersion('2.10'))
1434
1435     if is_x86 and not openssl110_asm_supported:
1436       error('''Did not find a new enough assembler, install one or build with
1437        --openssl-no-asm.
1438        Please refer to BUILDING.md''')
1439
1440   elif options.openssl_no_asm:
1441     warn('''--openssl-no-asm will result in binaries that do not take advantage
1442          of modern CPU cryptographic instructions and will therefore be slower.
1443          Please refer to BUILDING.md''')
1444
1445   if options.openssl_no_asm and options.shared_openssl:
1446     error('--openssl-no-asm is incompatible with --shared-openssl')
1447
1448   if options.openssl_fips or options.openssl_fips == '':
1449      error('FIPS is not supported in this version of Node.js')
1450
1451   configure_library('openssl', o)
1452
1453
1454 def configure_static(o):
1455   if options.fully_static or options.partly_static:
1456     if flavor == 'mac':
1457       warn("Generation of static executable will not work on OSX "
1458             "when using the default compilation environment")
1459       return
1460
1461     if options.fully_static:
1462       o['libraries'] += ['-static']
1463     elif options.partly_static:
1464       o['libraries'] += ['-static-libgcc', '-static-libstdc++']
1465       if options.enable_asan:
1466         o['libraries'] += ['-static-libasan']
1467
1468
1469 def write(filename, data):
1470   print_verbose('creating %s' % filename)
1471   with open(filename, 'w+') as f:
1472     f.write(data)
1473
1474 do_not_edit = '# Do not edit. Generated by the configure script.\n'
1475
1476 def glob_to_var(dir_base, dir_sub, patch_dir):
1477   list = []
1478   dir_all = '%s/%s' % (dir_base, dir_sub)
1479   files = os.walk(dir_all)
1480   for ent in files:
1481     (path, dirs, files) = ent
1482     for file in files:
1483       if file.endswith('.cpp') or file.endswith('.c') or file.endswith('.h'):
1484         # srcfile uses "slash" as dir separator as its output is consumed by gyp
1485         srcfile = '%s/%s' % (dir_sub, file)
1486         if patch_dir:
1487           patchfile = '%s/%s/%s' % (dir_base, patch_dir, file)
1488           if os.path.isfile(patchfile):
1489             srcfile = '%s/%s' % (patch_dir, file)
1490             info('Using floating patch "%s" from "%s"' % (patchfile, dir_base))
1491         list.append(srcfile)
1492     break
1493   return list
1494
1495 def configure_intl(o):
1496   def icu_download(path):
1497     depFile = 'tools/icu/current_ver.dep'
1498     with open(depFile) as f:
1499       icus = json.load(f)
1500     # download ICU, if needed
1501     if not os.access(options.download_path, os.W_OK):
1502       error('''Cannot write to desired download path.
1503         Either create it or verify permissions.''')
1504     attemptdownload = nodedownload.candownload(auto_downloads, "icu")
1505     for icu in icus:
1506       url = icu['url']
1507       (expectHash, hashAlgo, allAlgos) = nodedownload.findHash(icu)
1508       if not expectHash:
1509         error('''Could not find a hash to verify ICU download.
1510           %s may be incorrect.
1511           For the entry %s,
1512           Expected one of these keys: %s''' % (depFile, url, ' '.join(allAlgos)))
1513       local = url.split('/')[-1]
1514       targetfile = os.path.join(options.download_path, local)
1515       if not os.path.isfile(targetfile):
1516         if attemptdownload:
1517           nodedownload.retrievefile(url, targetfile)
1518       else:
1519         print('Re-using existing %s' % targetfile)
1520       if os.path.isfile(targetfile):
1521         print('Checking file integrity with %s:\r' % hashAlgo)
1522         gotHash = nodedownload.checkHash(targetfile, hashAlgo)
1523         print('%s:      %s  %s' % (hashAlgo, gotHash, targetfile))
1524         if (expectHash == gotHash):
1525           return targetfile
1526         else:
1527           warn('Expected: %s      *MISMATCH*' % expectHash)
1528           warn('\n ** Corrupted ZIP? Delete %s to retry download.\n' % targetfile)
1529     return None
1530   icu_config = {
1531     'variables': {}
1532   }
1533   icu_config_name = 'icu_config.gypi'
1534   def write_config(data, name):
1535     return
1536
1537   # write an empty file to start with
1538   write(icu_config_name, do_not_edit +
1539         pprint.pformat(icu_config, indent=2) + '\n')
1540
1541   # always set icu_small, node.gyp depends on it being defined.
1542   o['variables']['icu_small'] = b(False)
1543
1544   with_intl = options.with_intl
1545   with_icu_source = options.with_icu_source
1546   have_icu_path = bool(options.with_icu_path)
1547   if have_icu_path and with_intl != 'none':
1548     error('Cannot specify both --with-icu-path and --with-intl')
1549   elif have_icu_path:
1550     # Chromium .gyp mode: --with-icu-path
1551     o['variables']['v8_enable_i18n_support'] = 1
1552     # use the .gyp given
1553     o['variables']['icu_gyp_path'] = options.with_icu_path
1554     return
1555   # --with-intl=<with_intl>
1556   # set the default
1557   if with_intl in (None, 'none'):
1558     o['variables']['v8_enable_i18n_support'] = 0
1559     return  # no Intl
1560   elif with_intl == 'small-icu':
1561     # small ICU (English only)
1562     o['variables']['v8_enable_i18n_support'] = 1
1563     o['variables']['icu_small'] = b(True)
1564     locs = set(options.with_icu_locales.split(','))
1565     locs.add('root')  # must have root
1566     o['variables']['icu_locales'] = ','.join(str(loc) for loc in locs)
1567     # We will check a bit later if we can use the canned deps/icu-small
1568     o['variables']['icu_default_data'] = options.with_icu_default_data_dir or ''
1569   elif with_intl == 'full-icu':
1570     # full ICU
1571     o['variables']['v8_enable_i18n_support'] = 1
1572   elif with_intl == 'system-icu':
1573     # ICU from pkg-config.
1574     o['variables']['v8_enable_i18n_support'] = 1
1575     pkgicu = pkg_config('icu-i18n')
1576     if not pkgicu[0]:
1577       error('''Could not load pkg-config data for "icu-i18n".
1578        See above errors or the README.md.''')
1579     (libs, cflags, libpath, icuversion) = pkgicu
1580     icu_ver_major = icuversion.split('.')[0]
1581     o['variables']['icu_ver_major'] = icu_ver_major
1582     if int(icu_ver_major) < icu_versions['minimum_icu']:
1583       error('icu4c v%s is too old, v%d.x or later is required.' %
1584             (icuversion, icu_versions['minimum_icu']))
1585     # libpath provides linker path which may contain spaces
1586     if libpath:
1587       o['libraries'] += [libpath]
1588     # safe to split, cannot contain spaces
1589     o['libraries'] += libs.split()
1590     if cflags:
1591       stripped_flags = [flag.strip() for flag in cflags.split('-I')]
1592       o['include_dirs'] += [flag for flag in stripped_flags if flag]
1593     # use the "system" .gyp
1594     o['variables']['icu_gyp_path'] = 'tools/icu/icu-system.gyp'
1595     return
1596
1597   # this is just the 'deps' dir. Used for unpacking.
1598   icu_parent_path = 'deps'
1599
1600   # The full path to the ICU source directory. Should not include './'.
1601   icu_deps_path = 'deps/icu'
1602   icu_full_path = icu_deps_path
1603
1604   # icu-tmp is used to download and unpack the ICU tarball.
1605   icu_tmp_path = os.path.join(icu_parent_path, 'icu-tmp')
1606
1607   # canned ICU. see tools/icu/README.md to update.
1608   canned_icu_dir = 'deps/icu-small'
1609
1610   # use the README to verify what the canned ICU is
1611   canned_is_full = os.path.isfile(os.path.join(canned_icu_dir, 'README-FULL-ICU.txt'))
1612   canned_is_small = os.path.isfile(os.path.join(canned_icu_dir, 'README-SMALL-ICU.txt'))
1613   if canned_is_small:
1614     warn('Ignoring %s - in-repo small icu is no longer supported.' % canned_icu_dir)
1615
1616   # We can use 'deps/icu-small' - pre-canned ICU *iff*
1617   # - canned_is_full AND
1618   # - with_icu_source is unset (i.e. no other ICU was specified)
1619   #
1620   # This is *roughly* equivalent to
1621   # $ configure --with-intl=full-icu --with-icu-source=deps/icu-small
1622   # .. Except that we avoid copying icu-small over to deps/icu.
1623   # In this default case, deps/icu is ignored, although make clean will
1624   # still harmlessly remove deps/icu.
1625
1626   if (not with_icu_source) and canned_is_full:
1627     # OK- we can use the canned ICU.
1628     icu_full_path = canned_icu_dir
1629     icu_config['variables']['icu_full_canned'] = 1
1630   # --with-icu-source processing
1631   # now, check that they didn't pass --with-icu-source=deps/icu
1632   elif with_icu_source and os.path.abspath(icu_full_path) == os.path.abspath(with_icu_source):
1633     warn('Ignoring redundant --with-icu-source=%s' % with_icu_source)
1634     with_icu_source = None
1635   # if with_icu_source is still set, try to use it.
1636   if with_icu_source:
1637     if os.path.isdir(icu_full_path):
1638       print('Deleting old ICU source: %s' % icu_full_path)
1639       shutil.rmtree(icu_full_path)
1640     # now, what path was given?
1641     if os.path.isdir(with_icu_source):
1642       # it's a path. Copy it.
1643       print('%s -> %s' % (with_icu_source, icu_full_path))
1644       shutil.copytree(with_icu_source, icu_full_path)
1645     else:
1646       # could be file or URL.
1647       # Set up temporary area
1648       if os.path.isdir(icu_tmp_path):
1649         shutil.rmtree(icu_tmp_path)
1650       os.mkdir(icu_tmp_path)
1651       icu_tarball = None
1652       if os.path.isfile(with_icu_source):
1653         # it's a file. Try to unpack it.
1654         icu_tarball = with_icu_source
1655       else:
1656         # Can we download it?
1657         local = os.path.join(icu_tmp_path, with_icu_source.split('/')[-1])  # local part
1658         icu_tarball = nodedownload.retrievefile(with_icu_source, local)
1659       # continue with "icu_tarball"
1660       nodedownload.unpack(icu_tarball, icu_tmp_path)
1661       # Did it unpack correctly? Should contain 'icu'
1662       tmp_icu = os.path.join(icu_tmp_path, 'icu')
1663       if os.path.isdir(tmp_icu):
1664         os.rename(tmp_icu, icu_full_path)
1665         shutil.rmtree(icu_tmp_path)
1666       else:
1667         shutil.rmtree(icu_tmp_path)
1668         error('--with-icu-source=%s did not result in an "icu" dir.' % \
1669                with_icu_source)
1670
1671   # ICU mode. (icu-generic.gyp)
1672   o['variables']['icu_gyp_path'] = 'tools/icu/icu-generic.gyp'
1673   # ICU source dir relative to tools/icu (for .gyp file)
1674   o['variables']['icu_path'] = icu_full_path
1675   if not os.path.isdir(icu_full_path):
1676     # can we download (or find) a zipfile?
1677     localzip = icu_download(icu_full_path)
1678     if localzip:
1679       nodedownload.unpack(localzip, icu_parent_path)
1680     else:
1681       warn('* ECMA-402 (Intl) support didn\'t find ICU in %s..' % icu_full_path)
1682   if not os.path.isdir(icu_full_path):
1683     error('''Cannot build Intl without ICU in %s.
1684        Fix, or disable with "--with-intl=none"''' % icu_full_path)
1685   else:
1686     print_verbose('* Using ICU in %s' % icu_full_path)
1687   # Now, what version of ICU is it? We just need the "major", such as 54.
1688   # uvernum.h contains it as a #define.
1689   uvernum_h = os.path.join(icu_full_path, 'source/common/unicode/uvernum.h')
1690   if not os.path.isfile(uvernum_h):
1691     error('Could not load %s - is ICU installed?' % uvernum_h)
1692   icu_ver_major = None
1693   matchVerExp = r'^\s*#define\s+U_ICU_VERSION_SHORT\s+"([^"]*)".*'
1694   match_version = re.compile(matchVerExp)
1695   with io.open(uvernum_h, encoding='utf8') as in_file:
1696     for line in in_file:
1697       m = match_version.match(line)
1698       if m:
1699         icu_ver_major = str(m.group(1))
1700   if not icu_ver_major:
1701     error('Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h)
1702   elif int(icu_ver_major) < icu_versions['minimum_icu']:
1703     error('icu4c v%s.x is too old, v%d.x or later is required.' %
1704           (icu_ver_major, icu_versions['minimum_icu']))
1705   icu_endianness = sys.byteorder[0]
1706   o['variables']['icu_ver_major'] = icu_ver_major
1707   o['variables']['icu_endianness'] = icu_endianness
1708   icu_data_file_l = 'icudt%s%s.dat' % (icu_ver_major, 'l') # LE filename
1709   icu_data_file = 'icudt%s%s.dat' % (icu_ver_major, icu_endianness)
1710   # relative to configure
1711   icu_data_path = os.path.join(icu_full_path,
1712                                'source/data/in',
1713                                icu_data_file_l) # LE
1714   compressed_data = '%s.bz2' % (icu_data_path)
1715   if not os.path.isfile(icu_data_path) and os.path.isfile(compressed_data):
1716     # unpack. deps/icu is a temporary path
1717     if os.path.isdir(icu_tmp_path):
1718       shutil.rmtree(icu_tmp_path)
1719     os.mkdir(icu_tmp_path)
1720     icu_data_path = os.path.join(icu_tmp_path, icu_data_file_l)
1721     with open(icu_data_path, 'wb') as outf:
1722         inf = bz2.BZ2File(compressed_data, 'rb')
1723         try:
1724           shutil.copyfileobj(inf, outf)
1725         finally:
1726           inf.close()
1727     # Now, proceed..
1728
1729   # relative to dep..
1730   icu_data_in = os.path.join('..','..', icu_data_path)
1731   if not os.path.isfile(icu_data_path) and icu_endianness != 'l':
1732     # use host endianness
1733     icu_data_path = os.path.join(icu_full_path,
1734                                  'source/data/in',
1735                                  icu_data_file) # will be generated
1736   if not os.path.isfile(icu_data_path):
1737     # .. and we're not about to build it from .gyp!
1738     error('''ICU prebuilt data file %s does not exist.
1739        See the README.md.''' % icu_data_path)
1740
1741   # this is the input '.dat' file to use .. icudt*.dat
1742   # may be little-endian if from a icu-project.org tarball
1743   o['variables']['icu_data_in'] = icu_data_in
1744
1745   # map from variable name to subdirs
1746   icu_src = {
1747     'stubdata': 'stubdata',
1748     'common': 'common',
1749     'i18n': 'i18n',
1750     'tools': 'tools/toolutil',
1751     'genccode': 'tools/genccode',
1752     'genrb': 'tools/genrb',
1753     'icupkg': 'tools/icupkg',
1754   }
1755   # this creates a variable icu_src_XXX for each of the subdirs
1756   # with a list of the src files to use
1757   for i in icu_src:
1758     var  = 'icu_src_%s' % i
1759     path = '../../%s/source/%s' % (icu_full_path, icu_src[i])
1760     icu_config['variables'][var] = glob_to_var('tools/icu', path, 'patches/%s/source/%s' % (icu_ver_major, icu_src[i]) )
1761   # calculate platform-specific genccode args
1762   # print("platform %s, flavor %s" % (sys.platform, flavor))
1763   # if sys.platform == 'darwin':
1764   #   shlib_suffix = '%s.dylib'
1765   # elif sys.platform.startswith('aix'):
1766   #   shlib_suffix = '%s.a'
1767   # else:
1768   #   shlib_suffix = 'so.%s'
1769   if flavor == 'win':
1770     icu_config['variables']['icu_asm_ext'] = 'obj'
1771     icu_config['variables']['icu_asm_opts'] = [ '-o ' ]
1772   elif with_intl == 'small-icu' or options.cross_compiling:
1773     icu_config['variables']['icu_asm_ext'] = 'c'
1774     icu_config['variables']['icu_asm_opts'] = []
1775   elif flavor == 'mac':
1776     icu_config['variables']['icu_asm_ext'] = 'S'
1777     icu_config['variables']['icu_asm_opts'] = [ '-a', 'gcc-darwin' ]
1778   elif sys.platform.startswith('aix'):
1779     icu_config['variables']['icu_asm_ext'] = 'S'
1780     icu_config['variables']['icu_asm_opts'] = [ '-a', 'xlc' ]
1781   else:
1782     # assume GCC-compatible asm is OK
1783     icu_config['variables']['icu_asm_ext'] = 'S'
1784     icu_config['variables']['icu_asm_opts'] = [ '-a', 'gcc' ]
1785
1786   # write updated icu_config.gypi with a bunch of paths
1787   write(icu_config_name, do_not_edit +
1788         pprint.pformat(icu_config, indent=2) + '\n')
1789   return  # end of configure_intl
1790
1791 def configure_inspector(o):
1792   disable_inspector = (options.without_inspector or
1793                        options.with_intl in (None, 'none') or
1794                        options.without_ssl)
1795   o['variables']['v8_enable_inspector'] = 0 if disable_inspector else 1
1796
1797 def configure_section_file(o):
1798   try:
1799     proc = subprocess.Popen(['ld.gold'] + ['-v'], stdin = subprocess.PIPE,
1800                             stdout = subprocess.PIPE, stderr = subprocess.PIPE)
1801   except OSError:
1802     warn('''No acceptable ld.gold linker found!''')
1803     return 0
1804
1805   match = re.match(r"^GNU gold.*([0-9]+)\.([0-9]+)$",
1806                    proc.communicate()[0].decode("utf-8"))
1807
1808   if match:
1809     gold_major_version = match.group(1)
1810     gold_minor_version = match.group(2)
1811     if int(gold_major_version) == 1 and int(gold_minor_version) <= 1:
1812       error('''GNU gold version must be greater than 1.2 in order to use section
1813             reordering''')
1814
1815   if options.node_section_ordering_info != "":
1816     o['variables']['node_section_ordering_info'] = os.path.realpath(
1817       str(options.node_section_ordering_info))
1818   else:
1819     o['variables']['node_section_ordering_info'] = ""
1820
1821 def make_bin_override():
1822   if sys.platform == 'win32':
1823     raise Exception('make_bin_override should not be called on win32.')
1824   # If the system python is not the python we are running (which should be
1825   # python 2), then create a directory with a symlink called `python` to our
1826   # sys.executable. This directory will be prefixed to the PATH, so that
1827   # other tools that shell out to `python` will use the appropriate python
1828
1829   which_python = which('python')
1830   if (which_python and
1831       os.path.realpath(which_python) == os.path.realpath(sys.executable)):
1832     return
1833
1834   bin_override = os.path.abspath('out/tools/bin')
1835   try:
1836     os.makedirs(bin_override)
1837   except OSError as e:
1838     if e.errno != errno.EEXIST: raise e
1839
1840   python_link = os.path.join(bin_override, 'python')
1841   try:
1842     os.unlink(python_link)
1843   except OSError as e:
1844     if e.errno != errno.ENOENT: raise e
1845   os.symlink(sys.executable, python_link)
1846
1847   # We need to set the environment right now so that when gyp (in run_gyp)
1848   # shells out, it finds the right python (specifically at
1849   # https://github.com/nodejs/node/blob/d82e107/deps/v8/gypfiles/toolchain.gypi#L43)
1850   os.environ['PATH'] = bin_override + ':' + os.environ['PATH']
1851
1852   return bin_override
1853
1854 output = {
1855   'variables': {},
1856   'include_dirs': [],
1857   'libraries': [],
1858   'defines': [],
1859   'cflags': [],
1860 }
1861
1862 # Print a warning when the compiler is too old.
1863 check_compiler(output)
1864
1865 # determine the "flavor" (operating system) we're building for,
1866 # leveraging gyp's GetFlavor function
1867 flavor_params = {}
1868 if (options.dest_os):
1869   flavor_params['flavor'] = options.dest_os
1870 flavor = GetFlavor(flavor_params)
1871
1872 configure_node(output)
1873 configure_napi(output)
1874 configure_library('zlib', output)
1875 configure_library('http_parser', output)
1876 configure_library('libuv', output)
1877 configure_library('brotli', output, pkgname=['libbrotlidec', 'libbrotlienc'])
1878 configure_library('cares', output, pkgname='libcares')
1879 configure_library('nghttp2', output, pkgname='libnghttp2')
1880 configure_v8(output)
1881 configure_openssl(output)
1882 configure_intl(output)
1883 configure_static(output)
1884 configure_inspector(output)
1885 configure_section_file(output)
1886
1887 # Forward OSS-Fuzz settings
1888 output['variables']['ossfuzz'] = b(options.ossfuzz)
1889
1890 # variables should be a root level element,
1891 # move everything else to target_defaults
1892 variables = output['variables']
1893 del output['variables']
1894 variables['is_debug'] = B(options.debug)
1895
1896 # make_global_settings for special FIPS linking
1897 # should not be used to compile modules in node-gyp
1898 config_fips = { 'make_global_settings' : [] }
1899 if 'make_fips_settings' in output:
1900   config_fips['make_global_settings'] = output['make_fips_settings']
1901   del output['make_fips_settings']
1902   write('config_fips.gypi', do_not_edit +
1903         pprint.pformat(config_fips, indent=2) + '\n')
1904
1905 # make_global_settings should be a root level element too
1906 if 'make_global_settings' in output:
1907   make_global_settings = output['make_global_settings']
1908   del output['make_global_settings']
1909 else:
1910   make_global_settings = False
1911
1912 output = {
1913   'variables': variables,
1914   'target_defaults': output,
1915 }
1916 if make_global_settings:
1917   output['make_global_settings'] = make_global_settings
1918
1919 print_verbose(output)
1920
1921 write('config.gypi', do_not_edit +
1922       pprint.pformat(output, indent=2) + '\n')
1923
1924 write('config.status', '#!/bin/sh\nset -x\nexec ./configure ' +
1925       ' '.join([pipes.quote(arg) for arg in original_argv]) + '\n')
1926 os.chmod('config.status', 0o775)
1927
1928
1929 config = {
1930   'BUILDTYPE': 'Debug' if options.debug else 'Release',
1931   'NODE_TARGET_TYPE': variables['node_target_type'],
1932 }
1933
1934 # Not needed for trivial case. Useless when it's a win32 path.
1935 if sys.executable != 'python' and ':\\' not in sys.executable:
1936   config['PYTHON'] = sys.executable
1937
1938 if options.prefix:
1939   config['PREFIX'] = options.prefix
1940
1941 if options.use_ninja:
1942   config['BUILD_WITH'] = 'ninja'
1943
1944 # On Windows there is another find.exe in C:\Windows\System32
1945 if sys.platform == 'win32':
1946   config['FIND'] = '/usr/bin/find'
1947
1948 config_lines = ['='.join((k,v)) for k,v in config.items()]
1949 # Add a blank string to get a blank line at the end.
1950 config_lines += ['']
1951 config_str = '\n'.join(config_lines)
1952
1953 # On Windows there's no reason to search for a different python binary.
1954 bin_override = None if sys.platform == 'win32' else make_bin_override()
1955 if bin_override:
1956   config_str = 'export PATH:=' + bin_override + ':$(PATH)\n' + config_str
1957
1958 write('config.mk', do_not_edit + config_str)
1959
1960
1961
1962 gyp_args = ['--no-parallel', '-Dconfiguring_node=1']
1963
1964 if options.use_ninja:
1965   gyp_args += ['-f', 'ninja']
1966 elif flavor == 'win' and sys.platform != 'msys':
1967   gyp_args += ['-f', 'msvs', '-G', 'msvs_version=auto']
1968 else:
1969   gyp_args += ['-f', 'make-' + flavor]
1970
1971 if options.compile_commands_json:
1972   gyp_args += ['-f', 'compile_commands_json']
1973
1974 # pass the leftover positional arguments to GYP
1975 gyp_args += args
1976 # @lwnode
1977 gyp_args += get_lwnode_gyp_options()
1978 # @end of lwnode
1979
1980 if warn.warned and not options.verbose:
1981   warn('warnings were emitted in the configure phase')
1982
1983 print_verbose("running: \n    " + " ".join(['python', 'tools/gyp_node.py'] + gyp_args))
1984 run_gyp(gyp_args)
1985 info('configure completed successfully')