The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / configure @ 38809e39

History | View | Annotate | Download (18.2 KB)

1
#!/usr/bin/env python
2
import optparse
3
import os
4
import pprint
5
import re
6
import shlex
7
import subprocess
8
import sys
9

    
10
CC = os.environ.get('CC', 'cc')
11

    
12
root_dir = os.path.dirname(__file__)
13
sys.path.insert(0, os.path.join(root_dir, 'deps', 'v8', 'tools'))
14

    
15
# parse our options
16
parser = optparse.OptionParser()
17

    
18
parser.add_option("--debug",
19
    action="store_true",
20
    dest="debug",
21
    help="Also build debug build")
22

    
23
parser.add_option("--prefix",
24
    action="store",
25
    dest="prefix",
26
    help="Select the install prefix (defaults to /usr/local)")
27

    
28
parser.add_option("--without-npm",
29
    action="store_true",
30
    dest="without_npm",
31
    help="Don\'t install the bundled npm package manager")
32

    
33
parser.add_option("--without-ssl",
34
    action="store_true",
35
    dest="without_ssl",
36
    help="Build without SSL")
37

    
38
parser.add_option("--without-snapshot",
39
    action="store_true",
40
    dest="without_snapshot",
41
    help="Build without snapshotting V8 libraries. You might want to set"
42
         " this for cross-compiling. [Default: False]")
43

    
44
parser.add_option("--shared-v8",
45
    action="store_true",
46
    dest="shared_v8",
47
    help="Link to a shared V8 DLL instead of static linking")
48

    
49
parser.add_option("--shared-v8-includes",
50
    action="store",
51
    dest="shared_v8_includes",
52
    help="Directory containing V8 header files")
53

    
54
parser.add_option("--shared-v8-libpath",
55
    action="store",
56
    dest="shared_v8_libpath",
57
    help="A directory to search for the shared V8 DLL")
58

    
59
parser.add_option("--shared-v8-libname",
60
    action="store",
61
    dest="shared_v8_libname",
62
    help="Alternative lib name to link to (default: 'v8')")
63

    
64
parser.add_option("--shared-openssl",
65
    action="store_true",
66
    dest="shared_openssl",
67
    help="Link to a shared OpenSSl DLL instead of static linking")
68

    
69
parser.add_option("--shared-openssl-includes",
70
    action="store",
71
    dest="shared_openssl_includes",
72
    help="Directory containing OpenSSL header files")
73

    
74
parser.add_option("--shared-openssl-libpath",
75
    action="store",
76
    dest="shared_openssl_libpath",
77
    help="A directory to search for the shared OpenSSL DLLs")
78

    
79
parser.add_option("--shared-openssl-libname",
80
    action="store",
81
    dest="shared_openssl_libname",
82
    help="Alternative lib name to link to (default: 'crypto,ssl')")
83

    
84
# deprecated
85
parser.add_option("--openssl-use-sys",
86
    action="store_true",
87
    dest="shared_openssl",
88
    help=optparse.SUPPRESS_HELP)
89

    
90
# deprecated
91
parser.add_option("--openssl-includes",
92
    action="store",
93
    dest="shared_openssl_includes",
94
    help=optparse.SUPPRESS_HELP)
95

    
96
# deprecated
97
parser.add_option("--openssl-libpath",
98
    action="store",
99
    dest="shared_openssl_libpath",
100
    help=optparse.SUPPRESS_HELP)
101

    
102
# TODO document when we've decided on what the tracing API and its options will
103
# look like
104
parser.add_option("--systemtap-includes",
105
    action="store",
106
    dest="systemtap_includes",
107
    help=optparse.SUPPRESS_HELP)
108

    
109
parser.add_option("--no-ssl2",
110
    action="store_true",
111
    dest="no_ssl2",
112
    help="Disable OpenSSL v2")
113

    
114
parser.add_option("--shared-zlib",
115
    action="store_true",
116
    dest="shared_zlib",
117
    help="Link to a shared zlib DLL instead of static linking")
118

    
119
parser.add_option("--shared-zlib-includes",
120
    action="store",
121
    dest="shared_zlib_includes",
122
    help="Directory containing zlib header files")
123

    
124
parser.add_option("--shared-zlib-libpath",
125
    action="store",
126
    dest="shared_zlib_libpath",
127
    help="A directory to search for the shared zlib DLL")
128

    
129
parser.add_option("--shared-zlib-libname",
130
    action="store",
131
    dest="shared_zlib_libname",
132
    help="Alternative lib name to link to (default: 'z')")
133

    
134
parser.add_option("--shared-http-parser",
135
    action="store_true",
136
    dest="shared_http_parser",
137
    help="Link to a shared http_parser DLL instead of static linking")
138

    
139
parser.add_option("--shared-http-parser-includes",
140
    action="store",
141
    dest="shared_http_parser_includes",
142
    help="Directory containing http_parser header files")
143

    
144
parser.add_option("--shared-http-parser-libpath",
145
    action="store",
146
    dest="shared_http_parser_libpath",
147
    help="A directory to search for the shared http_parser DLL")
148

    
149
parser.add_option("--shared-http-parser-libname",
150
    action="store",
151
    dest="shared_http_parser_libname",
152
    help="Alternative lib name to link to (default: 'http_parser')")
153

    
154
parser.add_option("--shared-cares",
155
    action="store_true",
156
    dest="shared_cares",
157
    help="Link to a shared cares DLL instead of static linking")
158

    
159
parser.add_option("--shared-cares-includes",
160
    action="store",
161
    dest="shared_cares_includes",
162
    help="Directory containing cares header files")
163

    
164
parser.add_option("--shared-cares-libpath",
165
    action="store",
166
    dest="shared_cares_libpath",
167
    help="A directory to search for the shared cares DLL")
168

    
169
parser.add_option("--shared-cares-libname",
170
    action="store",
171
    dest="shared_cares_libname",
172
    help="Alternative lib name to link to (default: 'cares')")
173

    
174
parser.add_option("--shared-libuv",
175
    action="store_true",
176
    dest="shared_libuv",
177
    help="Link to a shared libuv DLL instead of static linking")
178

    
179
parser.add_option("--shared-libuv-includes",
180
    action="store",
181
    dest="shared_libuv_includes",
182
    help="Directory containing libuv header files")
183

    
184
parser.add_option("--shared-libuv-libpath",
185
    action="store",
186
    dest="shared_libuv_libpath",
187
    help="A directory to search for the shared libuv DLL")
188

    
189
parser.add_option("--shared-libuv-libname",
190
    action="store",
191
    dest="shared_libuv_libname",
192
    help="Alternative lib name to link to (default: 'uv')")
193

    
194
parser.add_option("--with-dtrace",
195
    action="store_true",
196
    dest="with_dtrace",
197
    help="Build with DTrace (default is true on sunos)")
198

    
199
parser.add_option("--without-dtrace",
200
    action="store_true",
201
    dest="without_dtrace",
202
    help="Build without DTrace")
203

    
204
parser.add_option("--with-etw",
205
    action="store_true",
206
    dest="with_etw",
207
    help="Build with ETW (default is true on Windows)")
208

    
209
parser.add_option("--without-etw",
210
    action="store_true",
211
    dest="without_etw",
212
    help="Build without ETW")
213

    
214
# CHECKME does this still work with recent releases of V8?
215
parser.add_option("--gdb",
216
    action="store_true",
217
    dest="gdb",
218
    help="add gdb support")
219

    
220
parser.add_option("--dest-cpu",
221
    action="store",
222
    dest="dest_cpu",
223
    help="CPU architecture to build for. Valid values are: arm, ia32, x64")
224

    
225
parser.add_option("--dest-os",
226
    action="store",
227
    dest="dest_os",
228
    help="Operating system to build for. Valid values are: "
229
         "win, mac, solaris, freebsd, linux")
230

    
231
parser.add_option("--no-ifaddrs",
232
    action="store_true",
233
    dest="no_ifaddrs",
234
    help="Use on deprecated SunOS systems that do not support ifaddrs.h")
235

    
236
parser.add_option("--with-arm-float-abi",
237
    action="store",
238
    dest="arm_float_abi",
239
    help="Specifies which floating-point ABI to use. Valid values are: "
240
         "soft, softfp, hard")
241

    
242
parser.add_option("--ninja",
243
    action="store_true",
244
    dest="use_ninja",
245
    help="Generate files for the ninja build system")
246

    
247
# Using --unsafe-optimizations voids your warranty.
248
parser.add_option("--unsafe-optimizations",
249
    action="store_true",
250
    dest="unsafe_optimizations",
251
    help=optparse.SUPPRESS_HELP)
252

    
253
parser.add_option("--xcode",
254
    action="store_true",
255
    dest="use_xcode",
256
    help="Generate build files for use with xcode")
257

    
258
(options, args) = parser.parse_args()
259

    
260

    
261
def b(value):
262
  """Returns the string 'true' if value is truthy, 'false' otherwise."""
263
  if value:
264
    return 'true'
265
  else:
266
    return 'false'
267

    
268

    
269
def pkg_config(pkg):
270
  cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
271
  libs = cmd.readline().strip()
272
  ret = cmd.close()
273
  if (ret): return None
274

    
275
  cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
276
  cflags = cmd.readline().strip()
277
  ret = cmd.close()
278
  if (ret): return None
279

    
280
  return (libs, cflags)
281

    
282

    
283
def cc_macros():
284
  """Checks predefined macros using the CC command."""
285

    
286
  try:
287
    p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
288
                         stdin=subprocess.PIPE,
289
                         stdout=subprocess.PIPE,
290
                         stderr=subprocess.PIPE)
291
  except OSError:
292
    print '''Node.js configure error: No acceptable C compiler found!
293

    
294
        Please make sure you have a C compiler installed on your system and/or
295
        consider adjusting the CC environment variable if you installed
296
        it in a non-standard prefix.
297
        '''
298
    sys.exit()
299

    
300
  p.stdin.write('\n')
301
  out = p.communicate()[0]
302

    
303
  out = str(out).split('\n')
304

    
305
  k = {}
306
  for line in out:
307
    lst = shlex.split(line)
308
    if len(lst) > 2:
309
      key = lst[1]
310
      val = lst[2]
311
      k[key] = val
312
  return k
313

    
314

    
315
def is_arch_armv7():
316
  """Check for ARMv7 instructions"""
317
  cc_macros_cache = cc_macros()
318
  return ('__ARM_ARCH_7__' in cc_macros_cache or
319
          '__ARM_ARCH_7A__' in cc_macros_cache or
320
          '__ARM_ARCH_7R__' in cc_macros_cache or
321
          '__ARM_ARCH_7M__' in cc_macros_cache)
322

    
323

    
324
def arm_hard_float_abi():
325
  """Check for hardfloat or softfloat eabi on ARM"""
326
  # GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
327
  # the Floating Point ABI used (PCS stands for Procedure Call Standard).
328
  # We use these as well as a couple of other defines to statically determine
329
  # what FP ABI used.
330
  # GCC versions 4.4 and below don't support hard-fp.
331
  # GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
332
  # __ARM_PCS_VFP.
333

    
334
  if compiler_version() >= (4, 6, 0):
335
    return '__ARM_PCS_VFP' in cc_macros()
336
  elif compiler_version() < (4, 5, 0):
337
    return False
338
  elif '__ARM_PCS_VFP' in cc_macros():
339
    return True
340
  elif ('__ARM_PCS' in cc_macros() or
341
        '__SOFTFP' in cc_macros() or
342
        not '__VFP_FP__' in cc_macros()):
343
    return False
344
  else:
345
    print '''Node.js configure error: Your version of GCC does not report
346
      the Floating-Point ABI to compile for your hardware
347

    
348
      Please manually specify which floating-point ABI to use with the
349
      --with-arm-float-abi option.
350
      '''
351
    sys.exit()
352

    
353

    
354
def host_arch_cc():
355
  """Host architecture check using the CC command."""
356

    
357
  k = cc_macros()
358

    
359
  matchup = {
360
    '__x86_64__'  : 'x64',
361
    '__i386__'    : 'ia32',
362
    '__arm__'     : 'arm',
363
  }
364

    
365
  rtn = 'ia32' # default
366

    
367
  for i in matchup:
368
    if i in k and k[i] != '0':
369
      rtn = matchup[i]
370
      break
371

    
372
  return rtn
373

    
374

    
375
def host_arch_win():
376
  """Host architecture check using environ vars (better way to do this?)"""
377

    
378
  arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
379

    
380
  matchup = {
381
    'AMD64'  : 'x64',
382
    'x86'    : 'ia32',
383
    'arm'    : 'arm',
384
  }
385

    
386
  return matchup.get(arch, 'ia32')
387

    
388

    
389
def compiler_version():
390
  try:
391
    proc = subprocess.Popen(shlex.split(CC) + ['--version'], stdout=subprocess.PIPE)
392
  except WindowsError:
393
    return (0, False)
394

    
395
  is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
396

    
397
  proc = subprocess.Popen(shlex.split(CC) + ['-dumpversion'], stdout=subprocess.PIPE)
398
  version = tuple(map(int, proc.communicate()[0].split('.')))
399

    
400
  return (version, is_clang)
401

    
402

    
403
def configure_arm(o):
404
  # V8 on ARM requires that armv7 is set. CPU Model detected by
405
  # the presence of __ARM_ARCH_7__ and the like defines in compiler
406
  if options.arm_float_abi:
407
    hard_float = options.arm_float_abi == 'hard'
408
  else:
409
    hard_float = arm_hard_float_abi()
410
  o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
411

    
412
  armv7 = is_arch_armv7()
413
  if armv7:
414
    # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
415
    o['variables']['arm_fpu'] = 'vfpv3'
416
    o['variables']['arm_neon'] = 0
417
  o['variables']['armv7'] = int(armv7)
418

    
419

    
420
def configure_node(o):
421
  o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
422
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
423
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
424
  o['variables']['node_install_npm'] = b(not options.without_npm)
425
  o['variables']['node_unsafe_optimizations'] = (
426
    1 if options.unsafe_optimizations else 0)
427
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
428

    
429
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
430
  target_arch = options.dest_cpu or host_arch
431
  o['variables']['host_arch'] = host_arch
432
  o['variables']['target_arch'] = target_arch
433

    
434
  if target_arch == 'arm':
435
    configure_arm(o)
436

    
437
  cc_version, is_clang = compiler_version()
438
  o['variables']['clang'] = 1 if is_clang else 0
439

    
440
  if not is_clang and cc_version != 0:
441
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
442

    
443
  # clang has always supported -fvisibility=hidden, right?
444
  if not is_clang and cc_version < (4,0,0):
445
    o['variables']['visibility'] = ''
446

    
447
  # By default, enable DTrace on SunOS systems. Don't allow it on other
448
  # systems, since it won't work.  (The MacOS build process is different than
449
  # SunOS, and we haven't implemented it.)
450
  if sys.platform.startswith('sunos'):
451
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
452
  elif sys.platform.startswith('linux'):
453
    o['variables']['node_use_dtrace'] = 'false'
454
    o['variables']['node_use_systemtap'] = b(options.with_dtrace)
455
    if options.systemtap_includes:
456
      o['include_dirs'] += [options.systemtap_includes]
457
  elif b(options.with_dtrace) == 'true':
458
    raise Exception(
459
       'DTrace is currently only supported on SunOS or Linux systems.')
460
  else:
461
    o['variables']['node_use_dtrace'] = 'false'
462
    o['variables']['node_use_systemtap'] = 'false'
463

    
464
  if options.no_ifaddrs:
465
    o['defines'] += ['SUNOS_NO_IFADDRS']
466

    
467
  # By default, enable ETW on Windows.
468
  if sys.platform.startswith('win32'):
469
    o['variables']['node_use_etw'] = b(not options.without_etw);
470
  elif b(options.with_etw) == 'true':
471
    raise Exception('ETW is only supported on Windows.')
472
  else:
473
    o['variables']['node_use_etw'] = 'false'
474

    
475

    
476
def configure_libz(o):
477
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
478

    
479
  # assume shared_zlib if one of these is set?
480
  if options.shared_zlib_libpath:
481
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
482
  if options.shared_zlib_libname:
483
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
484
  elif options.shared_zlib:
485
    o['libraries'] += ['-lz']
486
  if options.shared_zlib_includes:
487
    o['include_dirs'] += [options.shared_zlib_includes]
488

    
489

    
490
def configure_http_parser(o):
491
    o['variables']['node_shared_http_parser'] = b(options.shared_http_parser)
492

    
493
    # assume shared http_parser if one of these is set?
494
    if options.shared_http_parser_libpath:
495
        o['libraries'] += ['-L%s' % options.shared_http_parser_libpath]
496
    if options.shared_http_parser_libname:
497
        o['libraries'] += ['-l%s' % options.shared_http_parser_libname]
498
    elif options.shared_http_parser:
499
        o['libraries'] += ['-lhttp_parser']
500
    if options.shared_http_parser_includes:
501
        o['include_dirs'] += [options.shared_http_parser_includes]
502

    
503

    
504
def configure_cares(o):
505
    o['variables']['node_shared_cares'] = b(options.shared_cares)
506

    
507
    # assume shared cares if one of these is set?
508
    if options.shared_cares_libpath:
509
        o['libraries'] += ['-L%s' % options.shared_cares_libpath]
510
    if options.shared_cares_libname:
511
        o['libraries'] += ['-l%s' % options.shared_cares_libname]
512
    elif options.shared_cares:
513
        o['libraries'] += ['-lcares']
514
    if options.shared_cares_includes:
515
        o['include_dirs'] += [options.shared_cares_includes]
516

    
517

    
518
def configure_libuv(o):
519
  o['variables']['node_shared_libuv'] = b(options.shared_libuv)
520

    
521
  # assume shared libuv if one of these is set?
522
  if options.shared_libuv_libpath:
523
    o['libraries'] += ['-L%s' % options.shared_libuv_libpath]
524
  if options.shared_libuv_libname:
525
    o['libraries'] += ['-l%s' % options.shared_libuv_libname]
526
  elif options.shared_libuv:
527
    o['libraries'] += ['-luv']
528
  if options.shared_libuv_includes:
529
    o['include_dirs'] += [options.shared_libuv_includes]
530

    
531

    
532
def configure_v8(o):
533
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
534
  o['variables']['node_shared_v8'] = b(options.shared_v8)
535

    
536
  # assume shared_v8 if one of these is set?
537
  if options.shared_v8_libpath:
538
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
539
  if options.shared_v8_libname:
540
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
541
  elif options.shared_v8:
542
    o['libraries'] += ['-lv8']
543
  if options.shared_v8_includes:
544
    o['include_dirs'] += [options.shared_v8_includes]
545

    
546

    
547
def configure_openssl(o):
548
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
549
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
550

    
551
  if options.without_ssl:
552
    return
553

    
554
  if options.no_ssl2:
555
    o['defines'] += ['OPENSSL_NO_SSL2=1']
556

    
557
  if options.shared_openssl:
558
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
559

    
560
    if options.shared_openssl_libpath:
561
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
562

    
563
    if options.shared_openssl_libname:
564
      libnames = options.shared_openssl_libname.split(',')
565
      o['libraries'] += ['-l%s' % s for s in libnames]
566
    else:
567
      o['libraries'] += libs.split()
568

    
569
    if options.shared_openssl_includes:
570
      o['include_dirs'] += [options.shared_openssl_includes]
571
    else:
572
      o['cflags'] += cflags.split()
573

    
574

    
575
output = {
576
  'variables': {},
577
  'include_dirs': [],
578
  'libraries': [],
579
  'defines': [],
580
  'cflags': [],
581
}
582

    
583
configure_node(output)
584
configure_libz(output)
585
configure_http_parser(output)
586
configure_cares(output)
587
configure_libuv(output)
588
configure_v8(output)
589
configure_openssl(output)
590

    
591
# variables should be a root level element,
592
# move everything else to target_defaults
593
variables = output['variables']
594
del output['variables']
595
output = {
596
  'variables': variables,
597
  'target_defaults': output
598
}
599
pprint.pprint(output, indent=2)
600

    
601
def write(filename, data):
602
  filename = os.path.join(root_dir, filename)
603
  print "creating ", filename
604
  f = open(filename, 'w+')
605
  f.write(data)
606

    
607
write('config.gypi', "# Do not edit. Generated by the configure script.\n" +
608
  pprint.pformat(output, indent=2) + "\n")
609

    
610
config = {
611
  'BUILDTYPE': 'Debug' if options.debug else 'Release',
612
  'USE_NINJA': str(int(options.use_ninja or 0)),
613
  'USE_XCODE': str(int(options.use_xcode or 0)),
614
}
615
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
616

    
617
write('config.mk',
618
      '# Do not edit. Generated by the configure script.\n' + config)
619

    
620
if options.use_ninja:
621
  gyp_args = ['-f', 'ninja']
622
elif options.use_xcode:
623
  gyp_args = ['-f', 'xcode']
624
elif os.name == 'nt':
625
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto']
626
elif options.dest_os:
627
  gyp_args = ['-f', 'make-' + options.dest_os]
628
else:
629
  gyp_args = ['-f', 'make']
630

    
631
subprocess.call([sys.executable, 'tools/gyp_node'] + gyp_args)