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 @ 06810b29

History | View | Annotate | Download (14.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
parser.add_option("--no-ssl2",
103
    action="store_true",
104
    dest="no_ssl2",
105
    help="Disable OpenSSL v2")
106

    
107
parser.add_option("--shared-zlib",
108
    action="store_true",
109
    dest="shared_zlib",
110
    help="Link to a shared zlib DLL instead of static linking")
111

    
112
parser.add_option("--shared-zlib-includes",
113
    action="store",
114
    dest="shared_zlib_includes",
115
    help="Directory containing zlib header files")
116

    
117
parser.add_option("--shared-zlib-libpath",
118
    action="store",
119
    dest="shared_zlib_libpath",
120
    help="A directory to search for the shared zlib DLL")
121

    
122
parser.add_option("--shared-zlib-libname",
123
    action="store",
124
    dest="shared_zlib_libname",
125
    help="Alternative lib name to link to (default: 'z')")
126

    
127
parser.add_option("--with-dtrace",
128
    action="store_true",
129
    dest="with_dtrace",
130
    help="Build with DTrace (default is true on supported systems)")
131

    
132
parser.add_option("--without-dtrace",
133
    action="store_true",
134
    dest="without_dtrace",
135
    help="Build without DTrace")
136

    
137
parser.add_option("--with-etw",
138
    action="store_true",
139
    dest="with_etw",
140
    help="Build with ETW (default is true on Windows)")
141

    
142
parser.add_option("--without-etw",
143
    action="store_true",
144
    dest="without_etw",
145
    help="Build without ETW")
146

    
147
# CHECKME does this still work with recent releases of V8?
148
parser.add_option("--gdb",
149
    action="store_true",
150
    dest="gdb",
151
    help="add gdb support")
152

    
153
parser.add_option("--dest-cpu",
154
    action="store",
155
    dest="dest_cpu",
156
    help="CPU architecture to build for. Valid values are: arm, ia32, x64")
157

    
158
parser.add_option("--dest-os",
159
    action="store",
160
    dest="dest_os",
161
    help="Operating system to build for. Valid values are: "
162
         "win, mac, solaris, freebsd, linux")
163

    
164
parser.add_option("--no-ifaddrs",
165
    action="store_true",
166
    dest="no_ifaddrs",
167
    help="Use on deprecated SunOS systems that do not support ifaddrs.h")
168

    
169
parser.add_option("--with-arm-float-abi",
170
    action="store",
171
    dest="arm_float_abi",
172
    help="Specifies which floating-point ABI to use. Valid values are: "
173
         "soft, softfp, hard")
174

    
175
parser.add_option("--ninja",
176
    action="store_true",
177
    dest="use_ninja",
178
    help="Generate files for the ninja build system")
179

    
180
# Using --unsafe-optimizations voids your warranty.
181
parser.add_option("--unsafe-optimizations",
182
    action="store_true",
183
    dest="unsafe_optimizations",
184
    help=optparse.SUPPRESS_HELP)
185

    
186
(options, args) = parser.parse_args()
187

    
188

    
189
def b(value):
190
  """Returns the string 'true' if value is truthy, 'false' otherwise."""
191
  if value:
192
    return 'true'
193
  else:
194
    return 'false'
195

    
196

    
197
def pkg_config(pkg):
198
  cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
199
  libs = cmd.readline().strip()
200
  ret = cmd.close()
201
  if (ret): return None
202

    
203
  cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
204
  cflags = cmd.readline().strip()
205
  ret = cmd.close()
206
  if (ret): return None
207

    
208
  return (libs, cflags)
209

    
210

    
211
def cc_macros():
212
  """Checks predefined macros using the CC command."""
213

    
214
  try:
215
    p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'],
216
                         stdin=subprocess.PIPE,
217
                         stdout=subprocess.PIPE,
218
                         stderr=subprocess.PIPE)
219
  except OSError:
220
    print '''Node.js configure error: No acceptable C compiler found!
221

    
222
        Please make sure you have a C compiler installed on your system and/or
223
        consider adjusting the CC environment variable if you installed
224
        it in a non-standard prefix.
225
        '''
226
    sys.exit()
227

    
228
  p.stdin.write('\n')
229
  out = p.communicate()[0]
230

    
231
  out = str(out).split('\n')
232

    
233
  k = {}
234
  for line in out:
235
    lst = shlex.split(line)
236
    if len(lst) > 2:
237
      key = lst[1]
238
      val = lst[2]
239
      k[key] = val
240
  return k
241

    
242

    
243
def is_arch_armv7():
244
  """Check for ARMv7 instructions"""
245
  cc_macros_cache = cc_macros()
246
  return ('__ARM_ARCH_7__' in cc_macros_cache or
247
          '__ARM_ARCH_7A__' in cc_macros_cache or
248
          '__ARM_ARCH_7R__' in cc_macros_cache or
249
          '__ARM_ARCH_7M__' in cc_macros_cache)
250

    
251

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

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

    
276
      Please manually specify which floating-point ABI to use with the
277
      --with-arm-float-abi option.
278
      '''
279
    sys.exit()
280

    
281

    
282
def host_arch_cc():
283
  """Host architecture check using the CC command."""
284

    
285
  k = cc_macros()
286

    
287
  matchup = {
288
    '__x86_64__'  : 'x64',
289
    '__i386__'    : 'ia32',
290
    '__arm__'     : 'arm',
291
  }
292

    
293
  rtn = 'ia32' # default
294

    
295
  for i in matchup:
296
    if i in k and k[i] != '0':
297
      rtn = matchup[i]
298
      break
299

    
300
  return rtn
301

    
302

    
303
def host_arch_win():
304
  """Host architecture check using environ vars (better way to do this?)"""
305

    
306
  arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
307

    
308
  matchup = {
309
    'AMD64'  : 'x64',
310
    'x86'    : 'ia32',
311
    'arm'    : 'arm',
312
  }
313

    
314
  return matchup.get(arch, 'ia32')
315

    
316

    
317
def compiler_version():
318
  try:
319
    proc = subprocess.Popen(shlex.split(CC) + ['--version'], stdout=subprocess.PIPE)
320
  except WindowsError:
321
    return (0, False)
322

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

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

    
328
  return (version, is_clang)
329

    
330

    
331
def configure_arm(o):
332
  # V8 on ARM requires that armv7 is set. CPU Model detected by
333
  # the presence of __ARM_ARCH_7__ and the like defines in compiler
334
  if options.arm_float_abi:
335
    hard_float = options.arm_float_abi == 'hard'
336
  else:
337
    hard_float = arm_hard_float_abi()
338
  o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
339

    
340
  armv7 = is_arch_armv7()
341
  if armv7:
342
    # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
343
    o['variables']['arm_fpu'] = 'vfpv3'
344
    o['variables']['arm_neon'] = 0
345
  o['variables']['armv7'] = int(armv7)
346

    
347

    
348
def configure_node(o):
349
  o['variables']['v8_enable_gdbjit'] = 1 if options.gdb else 0
350
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
351
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
352
  o['variables']['node_install_npm'] = b(not options.without_npm)
353
  o['variables']['node_unsafe_optimizations'] = (
354
    1 if options.unsafe_optimizations else 0)
355
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
356

    
357
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
358
  target_arch = options.dest_cpu or host_arch
359
  o['variables']['host_arch'] = host_arch
360
  o['variables']['target_arch'] = target_arch
361

    
362
  if target_arch == 'arm':
363
    configure_arm(o)
364

    
365
  cc_version, is_clang = compiler_version()
366
  o['variables']['clang'] = 1 if is_clang else 0
367

    
368
  if not is_clang and cc_version != 0:
369
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
370

    
371
  # clang has always supported -fvisibility=hidden, right?
372
  if not is_clang and cc_version < (4,0,0):
373
    o['variables']['visibility'] = ''
374

    
375
  # By default, enable DTrace on SunOS systems. Don't allow it on other
376
  # systems, since it won't work.  (The MacOS build process is different than
377
  # SunOS, and we haven't implemented it.)
378
  if sys.platform.startswith('sunos'):
379
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
380
  elif sys.platform.startswith('linux'):
381
    o['variables']['node_use_dtrace'] = 'false'
382
    o['variables']['node_use_systemtap'] = b(not options.without_dtrace)
383
  elif b(options.with_dtrace) == 'true':
384
    raise Exception(
385
       'DTrace is currently only supported on SunOS or Linux systems.')
386
  else:
387
    o['variables']['node_use_dtrace'] = 'false'
388

    
389
  if options.no_ifaddrs:
390
    o['defines'] += ['SUNOS_NO_IFADDRS']
391

    
392
  # By default, enable ETW on Windows.
393
  if sys.platform.startswith('win32'):
394
    o['variables']['node_use_etw'] = b(not options.without_etw);
395
  elif b(options.with_etw) == 'true':
396
    raise Exception('ETW is only supported on Windows.')
397
  else:
398
    o['variables']['node_use_etw'] = 'false'
399

    
400

    
401
def configure_libz(o):
402
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
403

    
404
  # assume shared_zlib if one of these is set?
405
  if options.shared_zlib_libpath:
406
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
407
  if options.shared_zlib_libname:
408
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
409
  elif options.shared_zlib:
410
    o['libraries'] += ['-lz']
411
  if options.shared_zlib_includes:
412
    o['include_dirs'] += [options.shared_zlib_includes]
413

    
414

    
415
def configure_v8(o):
416
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
417
  o['variables']['node_shared_v8'] = b(options.shared_v8)
418

    
419
  # assume shared_v8 if one of these is set?
420
  if options.shared_v8_libpath:
421
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
422
  if options.shared_v8_libname:
423
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
424
  elif options.shared_v8:
425
    o['libraries'] += ['-lv8']
426
  if options.shared_v8_includes:
427
    o['include_dirs'] += [options.shared_v8_includes]
428

    
429

    
430
def configure_openssl(o):
431
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
432
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
433

    
434
  if options.without_ssl:
435
    return
436

    
437
  if options.no_ssl2:
438
    o['defines'] += ['OPENSSL_NO_SSL2=1']
439

    
440
  if options.shared_openssl:
441
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
442

    
443
    if options.shared_openssl_libpath:
444
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
445

    
446
    if options.shared_openssl_libname:
447
      libnames = options.shared_openssl_libname.split(',')
448
      o['libraries'] += ['-l%s' % s for s in libnames]
449
    else:
450
      o['libraries'] += libs.split()
451

    
452
    if options.shared_openssl_includes:
453
      o['include_dirs'] += [options.shared_openssl_includes]
454
    else:
455
      o['cflags'] += cflags.split()
456

    
457

    
458
output = {
459
  'variables': {},
460
  'include_dirs': [],
461
  'libraries': [],
462
  'defines': [],
463
  'cflags': [],
464
}
465

    
466
configure_node(output)
467
configure_libz(output)
468
configure_v8(output)
469
configure_openssl(output)
470

    
471
# variables should be a root level element,
472
# move everything else to target_defaults
473
variables = output['variables']
474
del output['variables']
475
output = {
476
  'variables': variables,
477
  'target_defaults': output
478
}
479
pprint.pprint(output, indent=2)
480

    
481
def write(filename, data):
482
  filename = os.path.join(root_dir, filename)
483
  print "creating ", filename
484
  f = open(filename, 'w+')
485
  f.write(data)
486

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

    
490
config = {
491
  'BUILDTYPE': 'Debug' if options.debug else 'Release',
492
  'USE_NINJA': str(int(options.use_ninja or 0)),
493
}
494
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
495

    
496
write('config.mk',
497
      '# Do not edit. Generated by the configure script.\n' + config)
498

    
499
if options.use_ninja:
500
  gyp_args = ['-f', 'ninja']
501
elif os.name == 'nt':
502
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=auto']
503
elif options.dest_os:
504
  gyp_args = ['-f', 'make-' + options.dest_os]
505
else:
506
  gyp_args = ['-f', 'make']
507

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