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 @ 73ff653a

History | View | Annotate | Download (16.9 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("--with-dtrace",
175
    action="store_true",
176
    dest="with_dtrace",
177
    help="Build with DTrace (default is true on sunos)")
178

    
179
parser.add_option("--without-dtrace",
180
    action="store_true",
181
    dest="without_dtrace",
182
    help="Build without DTrace")
183

    
184
parser.add_option("--with-etw",
185
    action="store_true",
186
    dest="with_etw",
187
    help="Build with ETW (default is true on Windows)")
188

    
189
parser.add_option("--without-etw",
190
    action="store_true",
191
    dest="without_etw",
192
    help="Build without ETW")
193

    
194
# CHECKME does this still work with recent releases of V8?
195
parser.add_option("--gdb",
196
    action="store_true",
197
    dest="gdb",
198
    help="add gdb support")
199

    
200
parser.add_option("--dest-cpu",
201
    action="store",
202
    dest="dest_cpu",
203
    help="CPU architecture to build for. Valid values are: arm, ia32, x64")
204

    
205
parser.add_option("--dest-os",
206
    action="store",
207
    dest="dest_os",
208
    help="Operating system to build for. Valid values are: "
209
         "win, mac, solaris, freebsd, linux")
210

    
211
parser.add_option("--no-ifaddrs",
212
    action="store_true",
213
    dest="no_ifaddrs",
214
    help="Use on deprecated SunOS systems that do not support ifaddrs.h")
215

    
216
parser.add_option("--with-arm-float-abi",
217
    action="store",
218
    dest="arm_float_abi",
219
    help="Specifies which floating-point ABI to use. Valid values are: "
220
         "soft, softfp, hard")
221

    
222
parser.add_option("--ninja",
223
    action="store_true",
224
    dest="use_ninja",
225
    help="Generate files for the ninja build system")
226

    
227
# Using --unsafe-optimizations voids your warranty.
228
parser.add_option("--unsafe-optimizations",
229
    action="store_true",
230
    dest="unsafe_optimizations",
231
    help=optparse.SUPPRESS_HELP)
232

    
233
(options, args) = parser.parse_args()
234

    
235

    
236
def b(value):
237
  """Returns the string 'true' if value is truthy, 'false' otherwise."""
238
  if value:
239
    return 'true'
240
  else:
241
    return 'false'
242

    
243

    
244
def pkg_config(pkg):
245
  cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
246
  libs = cmd.readline().strip()
247
  ret = cmd.close()
248
  if (ret): return None
249

    
250
  cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
251
  cflags = cmd.readline().strip()
252
  ret = cmd.close()
253
  if (ret): return None
254

    
255
  return (libs, cflags)
256

    
257

    
258
def cc_macros():
259
  """Checks predefined macros using the CC command."""
260

    
261
  try:
262
    p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
263
                         stdin=subprocess.PIPE,
264
                         stdout=subprocess.PIPE,
265
                         stderr=subprocess.PIPE)
266
  except OSError:
267
    print '''Node.js configure error: No acceptable C compiler found!
268

    
269
        Please make sure you have a C compiler installed on your system and/or
270
        consider adjusting the CC environment variable if you installed
271
        it in a non-standard prefix.
272
        '''
273
    sys.exit()
274

    
275
  p.stdin.write('\n')
276
  out = p.communicate()[0]
277

    
278
  out = str(out).split('\n')
279

    
280
  k = {}
281
  for line in out:
282
    lst = shlex.split(line)
283
    if len(lst) > 2:
284
      key = lst[1]
285
      val = lst[2]
286
      k[key] = val
287
  return k
288

    
289

    
290
def is_arch_armv7():
291
  """Check for ARMv7 instructions"""
292
  cc_macros_cache = cc_macros()
293
  return ('__ARM_ARCH_7__' in cc_macros_cache or
294
          '__ARM_ARCH_7A__' in cc_macros_cache or
295
          '__ARM_ARCH_7R__' in cc_macros_cache or
296
          '__ARM_ARCH_7M__' in cc_macros_cache)
297

    
298

    
299
def arm_hard_float_abi():
300
  """Check for hardfloat or softfloat eabi on ARM"""
301
  # GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
302
  # the Floating Point ABI used (PCS stands for Procedure Call Standard).
303
  # We use these as well as a couple of other defines to statically determine
304
  # what FP ABI used.
305
  # GCC versions 4.4 and below don't support hard-fp.
306
  # GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
307
  # __ARM_PCS_VFP.
308

    
309
  if compiler_version() >= (4, 6, 0):
310
    return '__ARM_PCS_VFP' in cc_macros()
311
  elif compiler_version() < (4, 5, 0):
312
    return False
313
  elif '__ARM_PCS_VFP' in cc_macros():
314
    return True
315
  elif ('__ARM_PCS' in cc_macros() or
316
        '__SOFTFP' in cc_macros() or
317
        not '__VFP_FP__' in cc_macros()):
318
    return False
319
  else:
320
    print '''Node.js configure error: Your version of GCC does not report
321
      the Floating-Point ABI to compile for your hardware
322

    
323
      Please manually specify which floating-point ABI to use with the
324
      --with-arm-float-abi option.
325
      '''
326
    sys.exit()
327

    
328

    
329
def host_arch_cc():
330
  """Host architecture check using the CC command."""
331

    
332
  k = cc_macros()
333

    
334
  matchup = {
335
    '__x86_64__'  : 'x64',
336
    '__i386__'    : 'ia32',
337
    '__arm__'     : 'arm',
338
  }
339

    
340
  rtn = 'ia32' # default
341

    
342
  for i in matchup:
343
    if i in k and k[i] != '0':
344
      rtn = matchup[i]
345
      break
346

    
347
  return rtn
348

    
349

    
350
def host_arch_win():
351
  """Host architecture check using environ vars (better way to do this?)"""
352

    
353
  arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
354

    
355
  matchup = {
356
    'AMD64'  : 'x64',
357
    'x86'    : 'ia32',
358
    'arm'    : 'arm',
359
  }
360

    
361
  return matchup.get(arch, 'ia32')
362

    
363

    
364
def compiler_version():
365
  try:
366
    proc = subprocess.Popen(shlex.split(CC) + ['--version'], stdout=subprocess.PIPE)
367
  except WindowsError:
368
    return (0, False)
369

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

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

    
375
  return (version, is_clang)
376

    
377

    
378
def configure_arm(o):
379
  # V8 on ARM requires that armv7 is set. CPU Model detected by
380
  # the presence of __ARM_ARCH_7__ and the like defines in compiler
381
  if options.arm_float_abi:
382
    hard_float = options.arm_float_abi == 'hard'
383
  else:
384
    hard_float = arm_hard_float_abi()
385
  o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
386

    
387
  armv7 = is_arch_armv7()
388
  if armv7:
389
    # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
390
    o['variables']['arm_fpu'] = 'vfpv3'
391
    o['variables']['arm_neon'] = 0
392
  o['variables']['armv7'] = int(armv7)
393

    
394

    
395
def configure_node(o):
396
  o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
397
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
398
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
399
  o['variables']['node_install_npm'] = b(not options.without_npm)
400
  o['variables']['node_unsafe_optimizations'] = (
401
    1 if options.unsafe_optimizations else 0)
402
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
403

    
404
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
405
  target_arch = options.dest_cpu or host_arch
406
  o['variables']['host_arch'] = host_arch
407
  o['variables']['target_arch'] = target_arch
408

    
409
  if target_arch == 'arm':
410
    configure_arm(o)
411

    
412
  cc_version, is_clang = compiler_version()
413
  o['variables']['clang'] = 1 if is_clang else 0
414

    
415
  if not is_clang and cc_version != 0:
416
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
417

    
418
  # clang has always supported -fvisibility=hidden, right?
419
  if not is_clang and cc_version < (4,0,0):
420
    o['variables']['visibility'] = ''
421

    
422
  # By default, enable DTrace on SunOS systems. Don't allow it on other
423
  # systems, since it won't work.  (The MacOS build process is different than
424
  # SunOS, and we haven't implemented it.)
425
  if sys.platform.startswith('sunos'):
426
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
427
  elif sys.platform.startswith('linux'):
428
    o['variables']['node_use_dtrace'] = 'false'
429
    o['variables']['node_use_systemtap'] = b(options.with_dtrace)
430
    if options.systemtap_includes:
431
      o['include_dirs'] += [options.systemtap_includes]
432
  elif b(options.with_dtrace) == 'true':
433
    raise Exception(
434
       'DTrace is currently only supported on SunOS or Linux systems.')
435
  else:
436
    o['variables']['node_use_dtrace'] = 'false'
437
    o['variables']['node_use_systemtap'] = 'false'
438

    
439
  if options.no_ifaddrs:
440
    o['defines'] += ['SUNOS_NO_IFADDRS']
441

    
442
  # By default, enable ETW on Windows.
443
  if sys.platform.startswith('win32'):
444
    o['variables']['node_use_etw'] = b(not options.without_etw);
445
  elif b(options.with_etw) == 'true':
446
    raise Exception('ETW is only supported on Windows.')
447
  else:
448
    o['variables']['node_use_etw'] = 'false'
449

    
450

    
451
def configure_libz(o):
452
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
453

    
454
  # assume shared_zlib if one of these is set?
455
  if options.shared_zlib_libpath:
456
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
457
  if options.shared_zlib_libname:
458
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
459
  elif options.shared_zlib:
460
    o['libraries'] += ['-lz']
461
  if options.shared_zlib_includes:
462
    o['include_dirs'] += [options.shared_zlib_includes]
463

    
464

    
465
def configure_http_parser(o):
466
    o['variables']['node_shared_http_parser'] = b(options.shared_http_parser)
467

    
468
    # assume shared http_parser if one of these is set?
469
    if options.shared_http_parser_libpath:
470
        o['libraries'] += ['-L%s' % options.shared_http_parser_libpath]
471
    if options.shared_http_parser_libname:
472
        o['libraries'] += ['-l%s' % options.shared_http_parser_libname]
473
    elif options.shared_http_parser:
474
        o['libraries'] += ['-lhttp_parser']
475
    if options.shared_http_parser_includes:
476
        o['include_dirs'] += [options.shared_http_parser_includes]
477

    
478

    
479
def configure_cares(o):
480
    o['variables']['node_shared_cares'] = b(options.shared_cares)
481

    
482
    # assume shared cares if one of these is set?
483
    if options.shared_cares_libpath:
484
        o['libraries'] += ['-L%s' % options.shared_cares_libpath]
485
    if options.shared_cares_libname:
486
        o['libraries'] += ['-l%s' % options.shared_cares_libname]
487
    elif options.shared_cares:
488
        o['libraries'] += ['-lcares']
489
    if options.shared_cares_includes:
490
        o['include_dirs'] += [options.shared_cares_includes]
491

    
492

    
493
def configure_v8(o):
494
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
495
  o['variables']['node_shared_v8'] = b(options.shared_v8)
496

    
497
  # assume shared_v8 if one of these is set?
498
  if options.shared_v8_libpath:
499
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
500
  if options.shared_v8_libname:
501
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
502
  elif options.shared_v8:
503
    o['libraries'] += ['-lv8']
504
  if options.shared_v8_includes:
505
    o['include_dirs'] += [options.shared_v8_includes]
506

    
507

    
508
def configure_openssl(o):
509
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
510
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
511

    
512
  if options.without_ssl:
513
    return
514

    
515
  if options.no_ssl2:
516
    o['defines'] += ['OPENSSL_NO_SSL2=1']
517

    
518
  if options.shared_openssl:
519
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
520

    
521
    if options.shared_openssl_libpath:
522
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
523

    
524
    if options.shared_openssl_libname:
525
      libnames = options.shared_openssl_libname.split(',')
526
      o['libraries'] += ['-l%s' % s for s in libnames]
527
    else:
528
      o['libraries'] += libs.split()
529

    
530
    if options.shared_openssl_includes:
531
      o['include_dirs'] += [options.shared_openssl_includes]
532
    else:
533
      o['cflags'] += cflags.split()
534

    
535

    
536
output = {
537
  'variables': {},
538
  'include_dirs': [],
539
  'libraries': [],
540
  'defines': [],
541
  'cflags': [],
542
}
543

    
544
configure_node(output)
545
configure_libz(output)
546
configure_http_parser(output)
547
configure_cares(output)
548
configure_v8(output)
549
configure_openssl(output)
550

    
551
# variables should be a root level element,
552
# move everything else to target_defaults
553
variables = output['variables']
554
del output['variables']
555
output = {
556
  'variables': variables,
557
  'target_defaults': output
558
}
559
pprint.pprint(output, indent=2)
560

    
561
def write(filename, data):
562
  filename = os.path.join(root_dir, filename)
563
  print "creating ", filename
564
  f = open(filename, 'w+')
565
  f.write(data)
566

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

    
570
config = {
571
  'BUILDTYPE': 'Debug' if options.debug else 'Release',
572
  'USE_NINJA': str(int(options.use_ninja or 0)),
573
}
574
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
575

    
576
write('config.mk',
577
      '# Do not edit. Generated by the configure script.\n' + config)
578

    
579
if options.use_ninja:
580
  gyp_args = ['-f', 'ninja']
581
elif os.name == 'nt':
582
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto']
583
elif options.dest_os:
584
  gyp_args = ['-f', 'make-' + options.dest_os]
585
else:
586
  gyp_args = ['-f', 'make']
587

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