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 @ 1205734e

History | View | Annotate | Download (13.5 KB)

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

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

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

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

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

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

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

    
32
parser.add_option("--without-waf",
33
    action="store_true",
34
    dest="without_waf",
35
    help="Don\'t install node-waf")
36

    
37
parser.add_option("--without-ssl",
38
    action="store_true",
39
    dest="without_ssl",
40
    help="Build without SSL")
41

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

    
48
parser.add_option("--shared-v8",
49
    action="store_true",
50
    dest="shared_v8",
51
    help="Link to a shared V8 DLL instead of static linking")
52

    
53
parser.add_option("--shared-v8-includes",
54
    action="store",
55
    dest="shared_v8_includes",
56
    help="Directory containing V8 header files")
57

    
58
parser.add_option("--shared-v8-libpath",
59
    action="store",
60
    dest="shared_v8_libpath",
61
    help="A directory to search for the shared V8 DLL")
62

    
63
parser.add_option("--shared-v8-libname",
64
    action="store",
65
    dest="shared_v8_libname",
66
    help="Alternative lib name to link to (default: 'v8')")
67

    
68
parser.add_option("--shared-openssl",
69
    action="store_true",
70
    dest="shared_openssl",
71
    help="Link to a shared OpenSSl DLL instead of static linking")
72

    
73
parser.add_option("--shared-openssl-includes",
74
    action="store",
75
    dest="shared_openssl_includes",
76
    help="Directory containing OpenSSL header files")
77

    
78
parser.add_option("--shared-openssl-libpath",
79
    action="store",
80
    dest="shared_openssl_libpath",
81
    help="A directory to search for the shared OpenSSL DLLs")
82

    
83
parser.add_option("--shared-openssl-libname",
84
    action="store",
85
    dest="shared_openssl_libname",
86
    help="Alternative lib name to link to (default: 'crypto,ssl')")
87

    
88
# deprecated
89
parser.add_option("--openssl-use-sys",
90
    action="store_true",
91
    dest="shared_openssl",
92
    help=optparse.SUPPRESS_HELP)
93

    
94
# deprecated
95
parser.add_option("--openssl-includes",
96
    action="store",
97
    dest="shared_openssl_includes",
98
    help=optparse.SUPPRESS_HELP)
99

    
100
# deprecated
101
parser.add_option("--openssl-libpath",
102
    action="store",
103
    dest="shared_openssl_libpath",
104
    help=optparse.SUPPRESS_HELP)
105

    
106
parser.add_option("--no-ssl2",
107
    action="store_true",
108
    dest="no_ssl2",
109
    help="Disable OpenSSL v2")
110

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

    
116
parser.add_option("--shared-zlib-includes",
117
    action="store",
118
    dest="shared_zlib_includes",
119
    help="Directory containing zlib header files")
120

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

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

    
131
parser.add_option("--with-dtrace",
132
    action="store_true",
133
    dest="with_dtrace",
134
    help="Build with DTrace (default is true on supported systems)")
135

    
136
parser.add_option("--without-dtrace",
137
    action="store_true",
138
    dest="without_dtrace",
139
    help="Build without DTrace")
140

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

    
146
parser.add_option("--without-etw",
147
    action="store_true",
148
    dest="without_etw",
149
    help="Build without ETW")
150

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

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

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

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

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

    
179
(options, args) = parser.parse_args()
180

    
181

    
182
def b(value):
183
  """Returns the string 'true' if value is truthy, 'false' otherwise."""
184
  if value:
185
    return 'true'
186
  else:
187
    return 'false'
188

    
189

    
190
def pkg_config(pkg):
191
  cmd = os.popen('pkg-config --libs %s' % pkg, 'r')
192
  libs = cmd.readline().strip()
193
  ret = cmd.close()
194
  if (ret): return None
195

    
196
  cmd = os.popen('pkg-config --cflags %s' % pkg, 'r')
197
  cflags = cmd.readline().strip()
198
  ret = cmd.close()
199
  if (ret): return None
200

    
201
  return (libs, cflags)
202

    
203

    
204
def cc_macros():
205
  """Checks predefined macros using the CC command."""
206

    
207
  try:
208
    p = subprocess.Popen(CC.split() + ['-dM', '-E', '-'],
209
                         stdin=subprocess.PIPE,
210
                         stdout=subprocess.PIPE,
211
                         stderr=subprocess.PIPE)
212
  except OSError:
213
    print '''Node.js configure error: No acceptable C compiler found!
214

    
215
        Please make sure you have a C compiler installed on your system and/or
216
        consider adjusting the CC environment variable if you installed
217
        it in a non-standard prefix.
218
        '''
219
    sys.exit()
220

    
221
  p.stdin.write('\n')
222
  out = p.communicate()[0]
223

    
224
  out = str(out).split('\n')
225

    
226
  k = {}
227
  for line in out:
228
    import shlex
229
    lst = shlex.split(line)
230
    if len(lst) > 2:
231
      key = lst[1]
232
      val = lst[2]
233
      k[key] = val
234
  return k
235

    
236

    
237
def is_arch_armv7():
238
  """Check for ARMv7 instructions"""
239
  cc_macros_cache = cc_macros()
240
  return ('__ARM_ARCH_7__' in cc_macros_cache or
241
          '__ARM_ARCH_7A__' in cc_macros_cache or
242
          '__ARM_ARCH_7R__' in cc_macros_cache or
243
          '__ARM_ARCH_7M__' in cc_macros_cache)
244

    
245

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

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

    
270
      Please manually specify which floating-point ABI to use with the
271
      --with-arm-float-abi option.
272
      '''
273
    sys.exit()
274

    
275

    
276
def host_arch_cc():
277
  """Host architecture check using the CC command."""
278

    
279
  k = cc_macros()
280

    
281
  matchup = {
282
    '__x86_64__'  : 'x64',
283
    '__i386__'    : 'ia32',
284
    '__arm__'     : 'arm',
285
  }
286

    
287
  rtn = 'ia32' # default
288

    
289
  for i in matchup:
290
    if i in k and k[i] != '0':
291
      rtn = matchup[i]
292
      break
293

    
294
  return rtn
295

    
296

    
297
def host_arch_win():
298
  """Host architecture check using environ vars (better way to do this?)"""
299

    
300
  arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86')
301

    
302
  matchup = {
303
    'AMD64'  : 'x64',
304
    'x86'    : 'ia32',
305
    'arm'    : 'arm',
306
  }
307

    
308
  return matchup.get(arch, 'ia32')
309

    
310

    
311
def compiler_version():
312
  try:
313
    proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
314
  except WindowsError:
315
    return (0, False)
316

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

    
319
  proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
320
  version = tuple(map(int, proc.communicate()[0].split('.')))
321

    
322
  return (version, is_clang)
323

    
324

    
325
def configure_arm(o):
326
  # V8 on ARM requires that armv7 is set. CPU Model detected by
327
  # the presence of __ARM_ARCH_7__ and the like defines in compiler
328
  if options.arm_float_abi:
329
    hard_float = options.arm_float_abi == 'hard'
330
  else:
331
    hard_float = arm_hard_float_abi()
332
  o['variables']['v8_use_arm_eabi_hardfloat'] = b(hard_float)
333

    
334
  armv7 = is_arch_armv7()
335
  if armv7:
336
    # CHECKME VFPv3 implies ARMv7+ but is the reverse true as well?
337
    o['variables']['arm_fpu'] = 'vfpv3'
338
    o['variables']['arm_neon'] = 0
339
  o['variables']['armv7'] = int(armv7)
340

    
341

    
342
def configure_node(o):
343
  # TODO add gdb
344
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
345
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
346
  o['variables']['node_install_npm'] = b(not options.without_npm)
347
  o['variables']['node_install_waf'] = b(not options.without_waf)
348
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
349

    
350
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
351
  target_arch = options.dest_cpu or host_arch
352
  o['variables']['host_arch'] = host_arch
353
  o['variables']['target_arch'] = target_arch
354

    
355
  if target_arch == 'arm':
356
    configure_arm(o)
357

    
358
  cc_version, is_clang = compiler_version()
359
  o['variables']['clang'] = 1 if is_clang else 0
360

    
361
  if not is_clang and cc_version != 0:
362
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
363

    
364
  # clang has always supported -fvisibility=hidden, right?
365
  if not is_clang and cc_version < (4,0,0):
366
    o['variables']['visibility'] = ''
367

    
368
  # By default, enable DTrace on SunOS systems. Don't allow it on other
369
  # systems, since it won't work.  (The MacOS build process is different than
370
  # SunOS, and we haven't implemented it.)
371
  if sys.platform.startswith('sunos'):
372
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
373
  elif b(options.with_dtrace) == 'true':
374
    raise Exception('DTrace is currently only supported on SunOS systems.')
375
  else:
376
    o['variables']['node_use_dtrace'] = 'false'
377

    
378
  if options.no_ifaddrs:
379
    o['defines'] += ['SUNOS_NO_IFADDRS']
380

    
381
  # By default, enable ETW on Windows.
382
  if sys.platform.startswith('win32'):
383
    o['variables']['node_use_etw'] = b(not options.without_etw);
384
  elif b(options.with_etw) == 'true':
385
    raise Exception('ETW is only supported on Windows.')
386
  else:
387
    o['variables']['node_use_etw'] = 'false'
388

    
389

    
390
def configure_libz(o):
391
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
392

    
393
  # assume shared_zlib if one of these is set?
394
  if options.shared_zlib_libpath:
395
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
396
  if options.shared_zlib_libname:
397
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
398
  elif options.shared_zlib:
399
    o['libraries'] += ['-lz']
400
  if options.shared_zlib_includes:
401
    o['include_dirs'] += [options.shared_zlib_includes]
402

    
403

    
404
def configure_v8(o):
405
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
406
  o['variables']['node_shared_v8'] = b(options.shared_v8)
407

    
408
  # assume shared_v8 if one of these is set?
409
  if options.shared_v8_libpath:
410
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
411
  if options.shared_v8_libname:
412
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
413
  elif options.shared_v8:
414
    o['libraries'] += ['-lv8']
415
  if options.shared_v8_includes:
416
    o['include_dirs'] += [options.shared_v8_includes]
417

    
418

    
419
def configure_openssl(o):
420
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
421
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
422

    
423
  if options.without_ssl:
424
    return
425

    
426
  if options.no_ssl2:
427
    o['defines'] += ['OPENSSL_NO_SSL2=1']
428

    
429
  if options.shared_openssl:
430
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
431

    
432
    if options.shared_openssl_libpath:
433
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
434

    
435
    if options.shared_openssl_libname:
436
      libnames = options.shared_openssl_libname.split(',')
437
      o['libraries'] += ['-l%s' % s for s in libnames]
438
    else:
439
      o['libraries'] += libs.split()
440

    
441
    if options.shared_openssl_includes:
442
      o['include_dirs'] += [options.shared_openssl_includes]
443
    else:
444
      o['cflags'] += cflags.split()
445

    
446

    
447
output = {
448
  'variables': {},
449
  'include_dirs': [],
450
  'libraries': [],
451
  'defines': [],
452
  'cflags': [],
453
}
454

    
455
configure_node(output)
456
configure_libz(output)
457
configure_v8(output)
458
configure_openssl(output)
459

    
460
# variables should be a root level element,
461
# move everything else to target_defaults
462
variables = output['variables']
463
del output['variables']
464
output = {
465
  'variables': variables,
466
  'target_defaults': output
467
}
468
pprint.pprint(output, indent=2)
469

    
470
def write(filename, data):
471
  filename = os.path.join(root_dir, filename)
472
  print "creating ", filename
473
  f = open(filename, 'w+')
474
  f.write(data)
475

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

    
479
write('config.mk', "# Do not edit. Generated by the configure script.\n" +
480
  ("BUILDTYPE=%s\n" % ('Debug' if options.debug else 'Release')))
481

    
482
if os.name == 'nt':
483
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=2010']
484
elif options.dest_os:
485
  gyp_args = ['-f', 'make-' + options.dest_os]
486
else:
487
  gyp_args = ['-f', 'make']
488

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