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 @ 148f5e65

History | View | Annotate | Download (14.5 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("--with-dtrace",
135
    action="store_true",
136
    dest="with_dtrace",
137
    help="Build with DTrace (default is true on sunos)")
138

    
139
parser.add_option("--without-dtrace",
140
    action="store_true",
141
    dest="without_dtrace",
142
    help="Build without DTrace")
143

    
144
parser.add_option("--with-etw",
145
    action="store_true",
146
    dest="with_etw",
147
    help="Build with ETW (default is true on Windows)")
148

    
149
parser.add_option("--without-etw",
150
    action="store_true",
151
    dest="without_etw",
152
    help="Build without ETW")
153

    
154
# CHECKME does this still work with recent releases of V8?
155
parser.add_option("--gdb",
156
    action="store_true",
157
    dest="gdb",
158
    help="add gdb support")
159

    
160
parser.add_option("--dest-cpu",
161
    action="store",
162
    dest="dest_cpu",
163
    help="CPU architecture to build for. Valid values are: arm, ia32, x64")
164

    
165
parser.add_option("--dest-os",
166
    action="store",
167
    dest="dest_os",
168
    help="Operating system to build for. Valid values are: "
169
         "win, mac, solaris, freebsd, linux")
170

    
171
parser.add_option("--no-ifaddrs",
172
    action="store_true",
173
    dest="no_ifaddrs",
174
    help="Use on deprecated SunOS systems that do not support ifaddrs.h")
175

    
176
parser.add_option("--with-arm-float-abi",
177
    action="store",
178
    dest="arm_float_abi",
179
    help="Specifies which floating-point ABI to use. Valid values are: "
180
         "soft, softfp, hard")
181

    
182
parser.add_option("--ninja",
183
    action="store_true",
184
    dest="use_ninja",
185
    help="Generate files for the ninja build system")
186

    
187
# Using --unsafe-optimizations voids your warranty.
188
parser.add_option("--unsafe-optimizations",
189
    action="store_true",
190
    dest="unsafe_optimizations",
191
    help=optparse.SUPPRESS_HELP)
192

    
193
(options, args) = parser.parse_args()
194

    
195

    
196
def b(value):
197
  """Returns the string 'true' if value is truthy, 'false' otherwise."""
198
  if value:
199
    return 'true'
200
  else:
201
    return 'false'
202

    
203

    
204
def pkg_config(pkg):
205
  cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
206
  libs = cmd.readline().strip()
207
  ret = cmd.close()
208
  if (ret): return None
209

    
210
  cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
211
  cflags = cmd.readline().strip()
212
  ret = cmd.close()
213
  if (ret): return None
214

    
215
  return (libs, cflags)
216

    
217

    
218
def cc_macros():
219
  """Checks predefined macros using the CC command."""
220

    
221
  try:
222
    p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
223
                         stdin=subprocess.PIPE,
224
                         stdout=subprocess.PIPE,
225
                         stderr=subprocess.PIPE)
226
  except OSError:
227
    print '''Node.js configure error: No acceptable C compiler found!
228

    
229
        Please make sure you have a C compiler installed on your system and/or
230
        consider adjusting the CC environment variable if you installed
231
        it in a non-standard prefix.
232
        '''
233
    sys.exit()
234

    
235
  p.stdin.write('\n')
236
  out = p.communicate()[0]
237

    
238
  out = str(out).split('\n')
239

    
240
  k = {}
241
  for line in out:
242
    lst = shlex.split(line)
243
    if len(lst) > 2:
244
      key = lst[1]
245
      val = lst[2]
246
      k[key] = val
247
  return k
248

    
249

    
250
def is_arch_armv7():
251
  """Check for ARMv7 instructions"""
252
  cc_macros_cache = cc_macros()
253
  return ('__ARM_ARCH_7__' in cc_macros_cache or
254
          '__ARM_ARCH_7A__' in cc_macros_cache or
255
          '__ARM_ARCH_7R__' in cc_macros_cache or
256
          '__ARM_ARCH_7M__' in cc_macros_cache)
257

    
258

    
259
def arm_hard_float_abi():
260
  """Check for hardfloat or softfloat eabi on ARM"""
261
  # GCC versions 4.6 and above define __ARM_PCS or __ARM_PCS_VFP to specify
262
  # the Floating Point ABI used (PCS stands for Procedure Call Standard).
263
  # We use these as well as a couple of other defines to statically determine
264
  # what FP ABI used.
265
  # GCC versions 4.4 and below don't support hard-fp.
266
  # GCC versions 4.5 may support hard-fp without defining __ARM_PCS or
267
  # __ARM_PCS_VFP.
268

    
269
  if compiler_version() >= (4, 6, 0):
270
    return '__ARM_PCS_VFP' in cc_macros()
271
  elif compiler_version() < (4, 5, 0):
272
    return False
273
  elif '__ARM_PCS_VFP' in cc_macros():
274
    return True
275
  elif ('__ARM_PCS' in cc_macros() or
276
        '__SOFTFP' in cc_macros() or
277
        not '__VFP_FP__' in cc_macros()):
278
    return False
279
  else:
280
    print '''Node.js configure error: Your version of GCC does not report
281
      the Floating-Point ABI to compile for your hardware
282

    
283
      Please manually specify which floating-point ABI to use with the
284
      --with-arm-float-abi option.
285
      '''
286
    sys.exit()
287

    
288

    
289
def host_arch_cc():
290
  """Host architecture check using the CC command."""
291

    
292
  k = cc_macros()
293

    
294
  matchup = {
295
    '__x86_64__'  : 'x64',
296
    '__i386__'    : 'ia32',
297
    '__arm__'     : 'arm',
298
  }
299

    
300
  rtn = 'ia32' # default
301

    
302
  for i in matchup:
303
    if i in k and k[i] != '0':
304
      rtn = matchup[i]
305
      break
306

    
307
  return rtn
308

    
309

    
310
def host_arch_win():
311
  """Host architecture check using environ vars (better way to do this?)"""
312

    
313
  arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
314

    
315
  matchup = {
316
    'AMD64'  : 'x64',
317
    'x86'    : 'ia32',
318
    'arm'    : 'arm',
319
  }
320

    
321
  return matchup.get(arch, 'ia32')
322

    
323

    
324
def compiler_version():
325
  try:
326
    proc = subprocess.Popen(shlex.split(CC) + ['--version'], stdout=subprocess.PIPE)
327
  except WindowsError:
328
    return (0, False)
329

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

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

    
335
  return (version, is_clang)
336

    
337

    
338
def configure_arm(o):
339
  # V8 on ARM requires that armv7 is set. CPU Model detected by
340
  # the presence of __ARM_ARCH_7__ and the like defines in compiler
341
  if options.arm_float_abi:
342
    hard_float = options.arm_float_abi == 'hard'
343
  else:
344
    hard_float = arm_hard_float_abi()
345
  o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
346

    
347
  armv7 = is_arch_armv7()
348
  if armv7:
349
    # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
350
    o['variables']['arm_fpu'] = 'vfpv3'
351
    o['variables']['arm_neon'] = 0
352
  o['variables']['armv7'] = int(armv7)
353

    
354

    
355
def configure_node(o):
356
  o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
357
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
358
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
359
  o['variables']['node_install_npm'] = b(not options.without_npm)
360
  o['variables']['node_unsafe_optimizations'] = (
361
    1 if options.unsafe_optimizations else 0)
362
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
363

    
364
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
365
  target_arch = options.dest_cpu or host_arch
366
  o['variables']['host_arch'] = host_arch
367
  o['variables']['target_arch'] = target_arch
368

    
369
  if target_arch == 'arm':
370
    configure_arm(o)
371

    
372
  cc_version, is_clang = compiler_version()
373
  o['variables']['clang'] = 1 if is_clang else 0
374

    
375
  if not is_clang and cc_version != 0:
376
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
377

    
378
  # clang has always supported -fvisibility=hidden, right?
379
  if not is_clang and cc_version < (4,0,0):
380
    o['variables']['visibility'] = ''
381

    
382
  # By default, enable DTrace on SunOS systems. Don't allow it on other
383
  # systems, since it won't work.  (The MacOS build process is different than
384
  # SunOS, and we haven't implemented it.)
385
  if sys.platform.startswith('sunos'):
386
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
387
  elif sys.platform.startswith('linux'):
388
    o['variables']['node_use_dtrace'] = 'false'
389
    o['variables']['node_use_systemtap'] = b(options.with_dtrace)
390
    if options.systemtap_includes:
391
      o['include_dirs'] += [options.systemtap_includes]
392
  elif b(options.with_dtrace) == 'true':
393
    raise Exception(
394
       'DTrace is currently only supported on SunOS or Linux systems.')
395
  else:
396
    o['variables']['node_use_dtrace'] = 'false'
397
    o['variables']['node_use_systemtap'] = 'false'
398

    
399
  if options.no_ifaddrs:
400
    o['defines'] += ['SUNOS_NO_IFADDRS']
401

    
402
  # By default, enable ETW on Windows.
403
  if sys.platform.startswith('win32'):
404
    o['variables']['node_use_etw'] = b(not options.without_etw);
405
  elif b(options.with_etw) == 'true':
406
    raise Exception('ETW is only supported on Windows.')
407
  else:
408
    o['variables']['node_use_etw'] = 'false'
409

    
410

    
411
def configure_libz(o):
412
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
413

    
414
  # assume shared_zlib if one of these is set?
415
  if options.shared_zlib_libpath:
416
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
417
  if options.shared_zlib_libname:
418
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
419
  elif options.shared_zlib:
420
    o['libraries'] += ['-lz']
421
  if options.shared_zlib_includes:
422
    o['include_dirs'] += [options.shared_zlib_includes]
423

    
424

    
425
def configure_v8(o):
426
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
427
  o['variables']['node_shared_v8'] = b(options.shared_v8)
428

    
429
  # assume shared_v8 if one of these is set?
430
  if options.shared_v8_libpath:
431
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
432
  if options.shared_v8_libname:
433
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
434
  elif options.shared_v8:
435
    o['libraries'] += ['-lv8']
436
  if options.shared_v8_includes:
437
    o['include_dirs'] += [options.shared_v8_includes]
438

    
439

    
440
def configure_openssl(o):
441
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
442
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
443

    
444
  if options.without_ssl:
445
    return
446

    
447
  if options.no_ssl2:
448
    o['defines'] += ['OPENSSL_NO_SSL2=1']
449

    
450
  if options.shared_openssl:
451
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
452

    
453
    if options.shared_openssl_libpath:
454
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
455

    
456
    if options.shared_openssl_libname:
457
      libnames = options.shared_openssl_libname.split(',')
458
      o['libraries'] += ['-l%s' % s for s in libnames]
459
    else:
460
      o['libraries'] += libs.split()
461

    
462
    if options.shared_openssl_includes:
463
      o['include_dirs'] += [options.shared_openssl_includes]
464
    else:
465
      o['cflags'] += cflags.split()
466

    
467

    
468
output = {
469
  'variables': {},
470
  'include_dirs': [],
471
  'libraries': [],
472
  'defines': [],
473
  'cflags': [],
474
}
475

    
476
configure_node(output)
477
configure_libz(output)
478
configure_v8(output)
479
configure_openssl(output)
480

    
481
# variables should be a root level element,
482
# move everything else to target_defaults
483
variables = output['variables']
484
del output['variables']
485
output = {
486
  'variables': variables,
487
  'target_defaults': output
488
}
489
pprint.pprint(output, indent=2)
490

    
491
def write(filename, data):
492
  filename = os.path.join(root_dir, filename)
493
  print "creating ", filename
494
  f = open(filename, 'w+')
495
  f.write(data)
496

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

    
500
config = {
501
  'BUILDTYPE': 'Debug' if options.debug else 'Release',
502
  'USE_NINJA': str(int(options.use_ninja or 0)),
503
}
504
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
505

    
506
write('config.mk',
507
      '# Do not edit. Generated by the configure script.\n' + config)
508

    
509
if options.use_ninja:
510
  gyp_args = ['-f', 'ninja']
511
elif os.name == 'nt':
512
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto']
513
elif options.dest_os:
514
  gyp_args = ['-f', 'make-' + options.dest_os]
515
else:
516
  gyp_args = ['-f', 'make']
517

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