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 @ bfd78b69

History | View | Annotate | Download (15.8 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("--with-dtrace",
155
    action="store_true",
156
    dest="with_dtrace",
157
    help="Build with DTrace (default is true on sunos)")
158

    
159
parser.add_option("--without-dtrace",
160
    action="store_true",
161
    dest="without_dtrace",
162
    help="Build without DTrace")
163

    
164
parser.add_option("--with-etw",
165
    action="store_true",
166
    dest="with_etw",
167
    help="Build with ETW (default is true on Windows)")
168

    
169
parser.add_option("--without-etw",
170
    action="store_true",
171
    dest="without_etw",
172
    help="Build without ETW")
173

    
174
# CHECKME does this still work with recent releases of V8?
175
parser.add_option("--gdb",
176
    action="store_true",
177
    dest="gdb",
178
    help="add gdb support")
179

    
180
parser.add_option("--dest-cpu",
181
    action="store",
182
    dest="dest_cpu",
183
    help="CPU architecture to build for. Valid values are: arm, ia32, x64")
184

    
185
parser.add_option("--dest-os",
186
    action="store",
187
    dest="dest_os",
188
    help="Operating system to build for. Valid values are: "
189
         "win, mac, solaris, freebsd, linux")
190

    
191
parser.add_option("--no-ifaddrs",
192
    action="store_true",
193
    dest="no_ifaddrs",
194
    help="Use on deprecated SunOS systems that do not support ifaddrs.h")
195

    
196
parser.add_option("--with-arm-float-abi",
197
    action="store",
198
    dest="arm_float_abi",
199
    help="Specifies which floating-point ABI to use. Valid values are: "
200
         "soft, softfp, hard")
201

    
202
parser.add_option("--ninja",
203
    action="store_true",
204
    dest="use_ninja",
205
    help="Generate files for the ninja build system")
206

    
207
# Using --unsafe-optimizations voids your warranty.
208
parser.add_option("--unsafe-optimizations",
209
    action="store_true",
210
    dest="unsafe_optimizations",
211
    help=optparse.SUPPRESS_HELP)
212

    
213
(options, args) = parser.parse_args()
214

    
215

    
216
def b(value):
217
  """Returns the string 'true' if value is truthy, 'false' otherwise."""
218
  if value:
219
    return 'true'
220
  else:
221
    return 'false'
222

    
223

    
224
def pkg_config(pkg):
225
  cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
226
  libs = cmd.readline().strip()
227
  ret = cmd.close()
228
  if (ret): return None
229

    
230
  cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
231
  cflags = cmd.readline().strip()
232
  ret = cmd.close()
233
  if (ret): return None
234

    
235
  return (libs, cflags)
236

    
237

    
238
def cc_macros():
239
  """Checks predefined macros using the CC command."""
240

    
241
  try:
242
    p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
243
                         stdin=subprocess.PIPE,
244
                         stdout=subprocess.PIPE,
245
                         stderr=subprocess.PIPE)
246
  except OSError:
247
    print '''Node.js configure error: No acceptable C compiler found!
248

    
249
        Please make sure you have a C compiler installed on your system and/or
250
        consider adjusting the CC environment variable if you installed
251
        it in a non-standard prefix.
252
        '''
253
    sys.exit()
254

    
255
  p.stdin.write('\n')
256
  out = p.communicate()[0]
257

    
258
  out = str(out).split('\n')
259

    
260
  k = {}
261
  for line in out:
262
    lst = shlex.split(line)
263
    if len(lst) > 2:
264
      key = lst[1]
265
      val = lst[2]
266
      k[key] = val
267
  return k
268

    
269

    
270
def is_arch_armv7():
271
  """Check for ARMv7 instructions"""
272
  cc_macros_cache = cc_macros()
273
  return ('__ARM_ARCH_7__' in cc_macros_cache or
274
          '__ARM_ARCH_7A__' in cc_macros_cache or
275
          '__ARM_ARCH_7R__' in cc_macros_cache or
276
          '__ARM_ARCH_7M__' in cc_macros_cache)
277

    
278

    
279
def arm_hard_float_abi():
280
  """Check for hardfloat or softfloat eabi on ARM"""
281
  # GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
282
  # the Floating Point ABI used (PCS stands for Procedure Call Standard).
283
  # We use these as well as a couple of other defines to statically determine
284
  # what FP ABI used.
285
  # GCC versions 4.4 and below don't support hard-fp.
286
  # GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
287
  # __ARM_PCS_VFP.
288

    
289
  if compiler_version() >= (4, 6, 0):
290
    return '__ARM_PCS_VFP' in cc_macros()
291
  elif compiler_version() < (4, 5, 0):
292
    return False
293
  elif '__ARM_PCS_VFP' in cc_macros():
294
    return True
295
  elif ('__ARM_PCS' in cc_macros() or
296
        '__SOFTFP' in cc_macros() or
297
        not '__VFP_FP__' in cc_macros()):
298
    return False
299
  else:
300
    print '''Node.js configure error: Your version of GCC does not report
301
      the Floating-Point ABI to compile for your hardware
302

    
303
      Please manually specify which floating-point ABI to use with the
304
      --with-arm-float-abi option.
305
      '''
306
    sys.exit()
307

    
308

    
309
def host_arch_cc():
310
  """Host architecture check using the CC command."""
311

    
312
  k = cc_macros()
313

    
314
  matchup = {
315
    '__x86_64__'  : 'x64',
316
    '__i386__'    : 'ia32',
317
    '__arm__'     : 'arm',
318
  }
319

    
320
  rtn = 'ia32' # default
321

    
322
  for i in matchup:
323
    if i in k and k[i] != '0':
324
      rtn = matchup[i]
325
      break
326

    
327
  return rtn
328

    
329

    
330
def host_arch_win():
331
  """Host architecture check using environ vars (better way to do this?)"""
332

    
333
  arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
334

    
335
  matchup = {
336
    'AMD64'  : 'x64',
337
    'x86'    : 'ia32',
338
    'arm'    : 'arm',
339
  }
340

    
341
  return matchup.get(arch, 'ia32')
342

    
343

    
344
def compiler_version():
345
  try:
346
    proc = subprocess.Popen(shlex.split(CC) + ['--version'], stdout=subprocess.PIPE)
347
  except WindowsError:
348
    return (0, False)
349

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

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

    
355
  return (version, is_clang)
356

    
357

    
358
def configure_arm(o):
359
  # V8 on ARM requires that armv7 is set. CPU Model detected by
360
  # the presence of __ARM_ARCH_7__ and the like defines in compiler
361
  if options.arm_float_abi:
362
    hard_float = options.arm_float_abi == 'hard'
363
  else:
364
    hard_float = arm_hard_float_abi()
365
  o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
366

    
367
  armv7 = is_arch_armv7()
368
  if armv7:
369
    # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
370
    o['variables']['arm_fpu'] = 'vfpv3'
371
    o['variables']['arm_neon'] = 0
372
  o['variables']['armv7'] = int(armv7)
373

    
374

    
375
def configure_node(o):
376
  o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
377
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
378
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
379
  o['variables']['node_install_npm'] = b(not options.without_npm)
380
  o['variables']['node_unsafe_optimizations'] = (
381
    1 if options.unsafe_optimizations else 0)
382
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
383

    
384
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
385
  target_arch = options.dest_cpu or host_arch
386
  o['variables']['host_arch'] = host_arch
387
  o['variables']['target_arch'] = target_arch
388

    
389
  if target_arch == 'arm':
390
    configure_arm(o)
391

    
392
  cc_version, is_clang = compiler_version()
393
  o['variables']['clang'] = 1 if is_clang else 0
394

    
395
  if not is_clang and cc_version != 0:
396
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
397

    
398
  # clang has always supported -fvisibility=hidden, right?
399
  if not is_clang and cc_version < (4,0,0):
400
    o['variables']['visibility'] = ''
401

    
402
  # By default, enable DTrace on SunOS systems. Don't allow it on other
403
  # systems, since it won't work.  (The MacOS build process is different than
404
  # SunOS, and we haven't implemented it.)
405
  if sys.platform.startswith('sunos'):
406
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
407
  elif sys.platform.startswith('linux'):
408
    o['variables']['node_use_dtrace'] = 'false'
409
    o['variables']['node_use_systemtap'] = b(options.with_dtrace)
410
    if options.systemtap_includes:
411
      o['include_dirs'] += [options.systemtap_includes]
412
  elif b(options.with_dtrace) == 'true':
413
    raise Exception(
414
       'DTrace is currently only supported on SunOS or Linux systems.')
415
  else:
416
    o['variables']['node_use_dtrace'] = 'false'
417
    o['variables']['node_use_systemtap'] = 'false'
418

    
419
  if options.no_ifaddrs:
420
    o['defines'] += ['SUNOS_NO_IFADDRS']
421

    
422
  # By default, enable ETW on Windows.
423
  if sys.platform.startswith('win32'):
424
    o['variables']['node_use_etw'] = b(not options.without_etw);
425
  elif b(options.with_etw) == 'true':
426
    raise Exception('ETW is only supported on Windows.')
427
  else:
428
    o['variables']['node_use_etw'] = 'false'
429

    
430

    
431
def configure_libz(o):
432
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
433

    
434
  # assume shared_zlib if one of these is set?
435
  if options.shared_zlib_libpath:
436
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
437
  if options.shared_zlib_libname:
438
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
439
  elif options.shared_zlib:
440
    o['libraries'] += ['-lz']
441
  if options.shared_zlib_includes:
442
    o['include_dirs'] += [options.shared_zlib_includes]
443

    
444

    
445
def configure_http_parser(o):
446
    o['variables']['node_shared_http_parser'] = b(options.shared_http_parser)
447

    
448
    # assume shared http_parser if one of these is set?
449
    if options.shared_http_parser_libpath:
450
        o['libraries'] += ['-L%s' % options.shared_http_parser_libpath]
451
    if options.shared_http_parser_libname:
452
        o['libraries'] += ['-l%s' % options.shared_http_parser_libname]
453
    elif options.shared_http_parser:
454
        o['libraries'] += ['-lhttp_parser']
455
    if options.shared_http_parser_includes:
456
        o['include_dirs'] += [options.shared_http_parser_includes]
457

    
458

    
459
def configure_v8(o):
460
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
461
  o['variables']['node_shared_v8'] = b(options.shared_v8)
462

    
463
  # assume shared_v8 if one of these is set?
464
  if options.shared_v8_libpath:
465
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
466
  if options.shared_v8_libname:
467
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
468
  elif options.shared_v8:
469
    o['libraries'] += ['-lv8']
470
  if options.shared_v8_includes:
471
    o['include_dirs'] += [options.shared_v8_includes]
472

    
473

    
474
def configure_openssl(o):
475
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
476
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
477

    
478
  if options.without_ssl:
479
    return
480

    
481
  if options.no_ssl2:
482
    o['defines'] += ['OPENSSL_NO_SSL2=1']
483

    
484
  if options.shared_openssl:
485
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
486

    
487
    if options.shared_openssl_libpath:
488
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
489

    
490
    if options.shared_openssl_libname:
491
      libnames = options.shared_openssl_libname.split(',')
492
      o['libraries'] += ['-l%s' % s for s in libnames]
493
    else:
494
      o['libraries'] += libs.split()
495

    
496
    if options.shared_openssl_includes:
497
      o['include_dirs'] += [options.shared_openssl_includes]
498
    else:
499
      o['cflags'] += cflags.split()
500

    
501

    
502
output = {
503
  'variables': {},
504
  'include_dirs': [],
505
  'libraries': [],
506
  'defines': [],
507
  'cflags': [],
508
}
509

    
510
configure_node(output)
511
configure_libz(output)
512
configure_http_parser(output)
513
configure_v8(output)
514
configure_openssl(output)
515

    
516
# variables should be a root level element,
517
# move everything else to target_defaults
518
variables = output['variables']
519
del output['variables']
520
output = {
521
  'variables': variables,
522
  'target_defaults': output
523
}
524
pprint.pprint(output, indent=2)
525

    
526
def write(filename, data):
527
  filename = os.path.join(root_dir, filename)
528
  print "creating ", filename
529
  f = open(filename, 'w+')
530
  f.write(data)
531

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

    
535
config = {
536
  'BUILDTYPE': 'Debug' if options.debug else 'Release',
537
  'USE_NINJA': str(int(options.use_ninja or 0)),
538
}
539
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
540

    
541
write('config.mk',
542
      '# Do not edit. Generated by the configure script.\n' + config)
543

    
544
if options.use_ninja:
545
  gyp_args = ['-f', 'ninja']
546
elif os.name == 'nt':
547
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto']
548
elif options.dest_os:
549
  gyp_args = ['-f', 'make-' + options.dest_os]
550
else:
551
  gyp_args = ['-f', 'make']
552

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