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

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 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
(options, args) = parser.parse_args()
181

    
182

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

    
190

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

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

    
202
  return (libs, cflags)
203

    
204

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

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

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

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

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

    
227
  k = {}
228
  for line in out:
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(shlex.split(CC) + ['--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(shlex.split(CC) + ['-dumpversion'], stdout=subprocess.PIPE)
320
  version = tuple(map(int, proc.communicate()[0].split('.')))
321

    
322
  return (version, is_clang)
323

    
324

    
325
def configure_node(o):
326
  # TODO add gdb
327
  o['variables']['v8_no_strict_aliasing'] = 1 # work around compiler bugs
328
  o['variables']['node_prefix'] = os.path.expanduser(options.prefix or '')
329
  o['variables']['node_install_npm'] = b(not options.without_npm)
330
  o['default_configuration'] = 'Debug' if options.debug else 'Release'
331

    
332
  host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc()
333
  target_arch = options.dest_cpu or host_arch
334
  o['variables']['host_arch'] = host_arch
335
  o['variables']['target_arch'] = target_arch
336

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

    
347
  cc_version, is_clang = compiler_version()
348
  o['variables']['clang'] = 1 if is_clang else 0
349

    
350
  if not is_clang and cc_version != 0:
351
    o['variables']['gcc_version'] = 10 * cc_version[0] + cc_version[1]
352

    
353
  # clang has always supported -fvisibility=hidden, right?
354
  if not is_clang and cc_version < (4,0,0):
355
    o['variables']['visibility'] = ''
356

    
357
  # By default, enable DTrace on SunOS systems. Don't allow it on other
358
  # systems, since it won't work.  (The MacOS build process is different than
359
  # SunOS, and we haven't implemented it.)
360
  if sys.platform.startswith('sunos'):
361
    o['variables']['node_use_dtrace'] = b(not options.without_dtrace)
362
  elif b(options.with_dtrace) == 'true':
363
    raise Exception('DTrace is currently only supported on SunOS systems.')
364
  else:
365
    o['variables']['node_use_dtrace'] = 'false'
366

    
367
  if options.no_ifaddrs:
368
    o['defines'] += ['SUNOS_NO_IFADDRS']
369

    
370
  # By default, enable ETW on Windows.
371
  if sys.platform.startswith('win32'):
372
    o['variables']['node_use_etw'] = b(not options.without_etw);
373
  elif b(options.with_etw) == 'true':
374
    raise Exception('ETW is only supported on Windows.')
375
  else:
376
    o['variables']['node_use_etw'] = 'false'
377

    
378

    
379
def configure_libz(o):
380
  o['variables']['node_shared_zlib'] = b(options.shared_zlib)
381

    
382
  # assume shared_zlib if one of these is set?
383
  if options.shared_zlib_libpath:
384
    o['libraries'] += ['-L%s' % options.shared_zlib_libpath]
385
  if options.shared_zlib_libname:
386
    o['libraries'] += ['-l%s' % options.shared_zlib_libname]
387
  elif options.shared_zlib:
388
    o['libraries'] += ['-lz']
389
  if options.shared_zlib_includes:
390
    o['include_dirs'] += [options.shared_zlib_includes]
391

    
392

    
393
def configure_v8(o):
394
  o['variables']['v8_use_snapshot'] = b(not options.without_snapshot)
395
  o['variables']['node_shared_v8'] = b(options.shared_v8)
396

    
397
  # assume shared_v8 if one of these is set?
398
  if options.shared_v8_libpath:
399
    o['libraries'] += ['-L%s' % options.shared_v8_libpath]
400
  if options.shared_v8_libname:
401
    o['libraries'] += ['-l%s' % options.shared_v8_libname]
402
  elif options.shared_v8:
403
    o['libraries'] += ['-lv8']
404
  if options.shared_v8_includes:
405
    o['include_dirs'] += [options.shared_v8_includes]
406

    
407

    
408
def configure_openssl(o):
409
  o['variables']['node_use_openssl'] = b(not options.without_ssl)
410
  o['variables']['node_shared_openssl'] = b(options.shared_openssl)
411

    
412
  if options.without_ssl:
413
    return
414

    
415
  if options.no_ssl2:
416
    o['defines'] += ['OPENSSL_NO_SSL2=1']
417

    
418
  if options.shared_openssl:
419
    (libs, cflags) = pkg_config('openssl') or ('-lssl -lcrypto', '')
420

    
421
    if options.shared_openssl_libpath:
422
      o['libraries'] += ['-L%s' % options.shared_openssl_libpath]
423

    
424
    if options.shared_openssl_libname:
425
      libnames = options.shared_openssl_libname.split(',')
426
      o['libraries'] += ['-l%s' % s for s in libnames]
427
    else:
428
      o['libraries'] += libs.split()
429

    
430
    if options.shared_openssl_includes:
431
      o['include_dirs'] += [options.shared_openssl_includes]
432
    else:
433
      o['cflags'] += cflags.split()
434

    
435

    
436
output = {
437
  'variables': {},
438
  'include_dirs': [],
439
  'libraries': [],
440
  'defines': [],
441
  'cflags': [],
442
}
443

    
444
configure_node(output)
445
configure_libz(output)
446
configure_v8(output)
447
configure_openssl(output)
448

    
449
# variables should be a root level element,
450
# move everything else to target_defaults
451
variables = output['variables']
452
del output['variables']
453
output = {
454
  'variables': variables,
455
  'target_defaults': output
456
}
457
pprint.pprint(output, indent=2)
458

    
459
def write(filename, data):
460
  filename = os.path.join(root_dir, filename)
461
  print "creating ", filename
462
  f = open(filename, 'w+')
463
  f.write(data)
464

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

    
468
config = {
469
  'BUILDTYPE': 'Debug' if options.debug else 'Release',
470
  'USE_NINJA': str(int(options.use_ninja or 0)),
471
}
472
config = '\n'.join(map('='.join, config.iteritems())) + '\n'
473

    
474
write('config.mk',
475
      '# Do not edit. Generated by the configure script.\n' + config)
476

    
477
if options.use_ninja:
478
  gyp_args = ['-f', 'ninja']
479
elif os.name == 'nt':
480
  gyp_args = ['-f', 'msvs', '-G', 'msvs_version=2010']
481
elif options.dest_os:
482
  gyp_args = ['-f', 'make-' + options.dest_os]
483
else:
484
  gyp_args = ['-f', 'make']
485

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