Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 1 | #!/usr/bin/env python |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 2 | import optparse |
| 3 | import os |
jbergstroem | 45605c9 | 2011-12-18 22:53:07 | [diff] [blame] | 4 | import pprint |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 5 | import re |
Ben Noordhuis | b9e1bb3 | 2011-11-15 16:17:05 | [diff] [blame] | 6 | import subprocess |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 7 | import sys |
Ryan Dahl | 5cf4cef | 2010-10-26 01:17:19 | [diff] [blame] | 8 | |
Ben Noordhuis | 5062741 | 2012-03-05 15:55:24 | [diff] [blame] | 9 | CC = os.environ.get('CC', 'cc') |
| 10 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 11 | root_dir = os.path.dirname(__file__) |
| 12 | sys.path.insert(0, os.path.join(root_dir, 'deps', 'v8', 'tools')) |
Ryan Dahl | 97c9745 | 2010-11-01 23:03:32 | [diff] [blame] | 13 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 14 | # parse our options |
| 15 | parser = optparse.OptionParser() |
Ryan Dahl | 97c9745 | 2010-11-01 23:03:32 | [diff] [blame] | 16 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 17 | parser.add_option("--debug", |
| 18 | action="store_true", |
| 19 | dest="debug", |
| 20 | help="Also build debug build") |
Ryan Dahl | 97c9745 | 2010-11-01 23:03:32 | [diff] [blame] | 21 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 22 | parser.add_option("--prefix", |
| 23 | action="store", |
| 24 | dest="prefix", |
| 25 | help="Select the install prefix (defaults to /usr/local)") |
| 26 | |
Fedor Indutny | a9f2c4a | 2011-12-17 08:09:14 | [diff] [blame] | 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 | |
Fedor Indutny | 6e76a7c | 2012-01-17 05:48:50 | [diff] [blame] | 32 | parser.add_option("--without-waf", |
| 33 | action="store_true", |
| 34 | dest="without_waf", |
| 35 | help="Don\'t install node-waf") |
| 36 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 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 | |
Ryan Dahl | e61de70 | 2011-12-16 23:00:23 | [diff] [blame] | 68 | parser.add_option("--openssl-use-sys", |
Nathan Rajlich | 70e6889 | 2012-03-17 19:57:24 | [diff] [blame] | 69 | action="store_true", |
Ryan Dahl | e61de70 | 2011-12-16 23:00:23 | [diff] [blame] | 70 | dest="openssl_use_sys", |
| 71 | help="Use the system OpenSSL instead of one included with Node") |
| 72 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 73 | parser.add_option("--openssl-includes", |
| 74 | action="store", |
| 75 | dest="openssl_includes", |
| 76 | help="A directory to search for the OpenSSL includes") |
| 77 | |
| 78 | parser.add_option("--openssl-libpath", |
| 79 | action="store", |
| 80 | dest="openssl_libpath", |
| 81 | help="A directory to search for the OpenSSL libraries") |
| 82 | |
| 83 | parser.add_option("--no-ssl2", |
| 84 | action="store_true", |
| 85 | dest="no_ssl2", |
| 86 | help="Disable OpenSSL v2") |
| 87 | |
T.C. Hollingsworth | d03b848 | 2012-02-26 23:02:21 | [diff] [blame] | 88 | parser.add_option("--shared-zlib", |
| 89 | action="store_true", |
| 90 | dest="shared_zlib", |
| 91 | help="Link to a shared zlib DLL instead of static linking") |
| 92 | |
| 93 | parser.add_option("--shared-zlib-includes", |
| 94 | action="store", |
| 95 | dest="shared_zlib_includes", |
| 96 | help="Directory containing zlib header files") |
| 97 | |
| 98 | parser.add_option("--shared-zlib-libpath", |
| 99 | action="store", |
| 100 | dest="shared_zlib_libpath", |
| 101 | help="A directory to search for the shared zlib DLL") |
| 102 | |
| 103 | parser.add_option("--shared-zlib-libname", |
| 104 | action="store", |
| 105 | dest="shared_zlib_libname", |
| 106 | help="Alternative lib name to link to (default: 'z')") |
| 107 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 108 | parser.add_option("--with-dtrace", |
| 109 | action="store_true", |
| 110 | dest="with_dtrace", |
Dave Pacheco | cc15299 | 2012-03-28 17:26:10 | [diff] [blame] | 111 | help="Build with DTrace (default is true on supported systems)") |
| 112 | |
| 113 | parser.add_option("--without-dtrace", |
| 114 | action="store_true", |
| 115 | dest="without_dtrace", |
| 116 | help="Build without DTrace") |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 117 | |
| 118 | # CHECKME does this still work with recent releases of V8? |
| 119 | parser.add_option("--gdb", |
| 120 | action="store_true", |
| 121 | dest="gdb", |
| 122 | help="add gdb support") |
| 123 | |
| 124 | parser.add_option("--dest-cpu", |
| 125 | action="store", |
| 126 | dest="dest_cpu", |
| 127 | help="CPU architecture to build for. Valid values are: arm, ia32, x64") |
| 128 | |
| 129 | (options, args) = parser.parse_args() |
| 130 | |
| 131 | |
Ben Noordhuis | a033261 | 2011-11-29 15:27:52 | [diff] [blame] | 132 | def b(value): |
| 133 | """Returns the string 'true' if value is truthy, 'false' otherwise.""" |
| 134 | if value: |
| 135 | return 'true' |
| 136 | else: |
| 137 | return 'false' |
| 138 | |
| 139 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 140 | def pkg_config(pkg): |
| 141 | cmd = os.popen('pkg-config --libs %s' % pkg, 'r') |
| 142 | libs = cmd.readline().strip() |
| 143 | ret = cmd.close() |
| 144 | if (ret): return None |
| 145 | |
| 146 | cmd = os.popen('pkg-config --cflags %s' % pkg, 'r') |
| 147 | cflags = cmd.readline().strip() |
| 148 | ret = cmd.close() |
| 149 | if (ret): return None |
| 150 | |
| 151 | return (libs, cflags) |
| 152 | |
| 153 | |
Nathan Rajlich | dc75232 | 2012-03-15 22:17:25 | [diff] [blame] | 154 | def host_arch_cc(): |
| 155 | """Host architecture check using the CC command.""" |
Nathan Rajlich | 19133ca | 2012-02-20 20:27:07 | [diff] [blame] | 156 | |
Alex Xu | 5abcdc9 | 2012-03-16 23:01:53 | [diff] [blame] | 157 | p = subprocess.Popen(CC.split() + ['-dM', '-E', '-'], |
Ben Noordhuis | 5062741 | 2012-03-05 15:55:24 | [diff] [blame] | 158 | stdin=subprocess.PIPE, |
| 159 | stdout=subprocess.PIPE, |
| 160 | stderr=subprocess.PIPE) |
Nathan Rajlich | 19133ca | 2012-02-20 20:27:07 | [diff] [blame] | 161 | p.stdin.write('\n') |
| 162 | out = p.communicate()[0] |
| 163 | |
| 164 | out = str(out).split('\n') |
| 165 | |
| 166 | k = {} |
| 167 | for line in out: |
| 168 | import shlex |
| 169 | lst = shlex.split(line) |
| 170 | if len(lst) > 2: |
| 171 | key = lst[1] |
| 172 | val = lst[2] |
| 173 | k[key] = val |
| 174 | |
| 175 | matchup = { |
| 176 | '__x86_64__' : 'x64', |
| 177 | '__i386__' : 'ia32', |
| 178 | '__arm__' : 'arm', |
Karl Skomski | 09ccbef | 2012-02-13 13:28:43 | [diff] [blame] | 179 | } |
| 180 | |
Nathan Rajlich | 19133ca | 2012-02-20 20:27:07 | [diff] [blame] | 181 | rtn = 'ia32' # default |
Karl Skomski | 09ccbef | 2012-02-13 13:28:43 | [diff] [blame] | 182 | |
Nathan Rajlich | 19133ca | 2012-02-20 20:27:07 | [diff] [blame] | 183 | for i in matchup: |
| 184 | if i in k and k[i] != '0': |
| 185 | rtn = matchup[i] |
| 186 | break |
| 187 | |
| 188 | return rtn |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 189 | |
| 190 | |
Nathan Rajlich | dc75232 | 2012-03-15 22:17:25 | [diff] [blame] | 191 | def host_arch_win(): |
| 192 | """Host architecture check using environ vars (better way to do this?)""" |
| 193 | |
| 194 | arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86') |
| 195 | |
| 196 | matchup = { |
| 197 | 'AMD64' : 'x64', |
| 198 | 'x86' : 'ia32', |
| 199 | 'arm' : 'arm', |
| 200 | } |
| 201 | |
| 202 | return matchup.get(arch, 'ia32') |
| 203 | |
| 204 | |
| 205 | def host_arch(): |
| 206 | """Host architecture. One of arm, ia32 or x64.""" |
| 207 | if os.name == 'nt': |
| 208 | arch = host_arch_win() |
| 209 | else: |
| 210 | arch = host_arch_cc() |
| 211 | return arch |
| 212 | |
| 213 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 214 | def target_arch(): |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 215 | return host_arch() |
| 216 | |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 217 | |
| 218 | def gcc_version(): |
| 219 | try: |
Ben Noordhuis | 5062741 | 2012-03-05 15:55:24 | [diff] [blame] | 220 | proc = subprocess.Popen([CC, '-v'], stderr=subprocess.PIPE) |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 221 | except OSError: |
| 222 | return None |
Ben Noordhuis | 5062741 | 2012-03-05 15:55:24 | [diff] [blame] | 223 | # TODO parse clang output |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 224 | version = proc.communicate()[1].split('\n')[-2] |
| 225 | match = re.match('gcc version (\d+)\.(\d+)\.(\d+)', version) |
Ben Noordhuis | 5062741 | 2012-03-05 15:55:24 | [diff] [blame] | 226 | if not match: return None |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 227 | return ['LLVM' in version] + map(int, match.groups()) |
| 228 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 229 | |
| 230 | def configure_node(o): |
Ben Noordhuis | 93465d3 | 2012-01-15 15:50:58 | [diff] [blame] | 231 | # TODO add gdb |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 232 | o['variables']['node_prefix'] = options.prefix if options.prefix else '' |
Fedor Indutny | a9f2c4a | 2011-12-17 08:09:14 | [diff] [blame] | 233 | o['variables']['node_install_npm'] = b(not options.without_npm) |
Fedor Indutny | 6e76a7c | 2012-01-17 05:48:50 | [diff] [blame] | 234 | o['variables']['node_install_waf'] = b(not options.without_waf) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 235 | o['variables']['host_arch'] = host_arch() |
Ben Noordhuis | 93465d3 | 2012-01-15 15:50:58 | [diff] [blame] | 236 | o['variables']['target_arch'] = options.dest_cpu or target_arch() |
Shigeki Ohtsu | 680d75a | 2012-01-18 09:37:02 | [diff] [blame] | 237 | o['default_configuration'] = 'Debug' if options.debug else 'Release' |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 238 | |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 239 | # turn off strict aliasing if gcc < 4.6.0 unless it's llvm-gcc |
| 240 | # see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45883 |
| 241 | # see http://code.google.com/p/v8/issues/detail?id=884 |
Ben Noordhuis | 5062741 | 2012-03-05 15:55:24 | [diff] [blame] | 242 | o['variables']['strict_aliasing'] = b( |
| 243 | 'clang' in CC or gcc_version() >= [False, 4, 6, 0]) |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 244 | |
Ben Noordhuis | 5ebc05f | 2012-03-05 16:01:59 | [diff] [blame] | 245 | # clang has always supported -fvisibility=hidden, right? |
| 246 | if 'clang' not in CC and gcc_version() < [False, 4, 0, 0]: |
| 247 | o['variables']['visibility'] = '' |
Ben Noordhuis | 30b29d8 | 2012-03-02 01:14:27 | [diff] [blame] | 248 | |
Dave Pacheco | cc15299 | 2012-03-28 17:26:10 | [diff] [blame] | 249 | # By default, enable DTrace on SunOS systems. Don't allow it on other |
| 250 | # systems, since it won't work. (The MacOS build process is different than |
| 251 | # SunOS, and we haven't implemented it.) |
| 252 | if sys.platform.startswith('sunos'): |
| 253 | o['variables']['node_use_dtrace'] = b(not options.without_dtrace); |
| 254 | elif b(options.with_dtrace) == 'true': |
| 255 | raise Exception('DTrace is currently only supported on SunOS systems.') |
| 256 | else: |
| 257 | o['variables']['node_use_dtrace'] = 'false' |
| 258 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 259 | |
| 260 | def configure_libz(o): |
T.C. Hollingsworth | d03b848 | 2012-02-26 23:02:21 | [diff] [blame] | 261 | o['variables']['node_shared_zlib'] = b(options.shared_zlib) |
| 262 | |
| 263 | # assume shared_zlib if one of these is set? |
| 264 | if options.shared_zlib_libpath: |
| 265 | o['libraries'] += ['-L%s' % options.shared_zlib_libpath] |
| 266 | if options.shared_zlib_libname: |
| 267 | o['libraries'] += ['-l%s' % options.shared_zlib_libname] |
| 268 | elif options.shared_zlib: |
| 269 | o['libraries'] += ['-lz'] |
| 270 | if options.shared_zlib_includes: |
| 271 | o['include_dirs'] += [options.shared_zlib_includes] |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 272 | |
| 273 | |
| 274 | def configure_v8(o): |
Ben Noordhuis | a033261 | 2011-11-29 15:27:52 | [diff] [blame] | 275 | o['variables']['v8_use_snapshot'] = b(not options.without_snapshot) |
| 276 | o['variables']['node_shared_v8'] = b(options.shared_v8) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 277 | |
| 278 | # assume shared_v8 if one of these is set? |
| 279 | if options.shared_v8_libpath: |
| 280 | o['libraries'] += ['-L%s' % options.shared_v8_libpath] |
| 281 | if options.shared_v8_libname: |
| 282 | o['libraries'] += ['-l%s' % options.shared_v8_libname] |
isaacs | 59ecf2c | 2012-02-23 22:52:18 | [diff] [blame] | 283 | elif options.shared_v8: |
| 284 | o['libraries'] += ['-lv8'] |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 285 | if options.shared_v8_includes: |
| 286 | o['include_dirs'] += [options.shared_v8_includes] |
isaacs | 59ecf2c | 2012-02-23 22:52:18 | [diff] [blame] | 287 | o['variables']['node_shared_v8_includes'] = options.shared_v8_includes |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 288 | |
| 289 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 290 | def configure_openssl(o): |
Ben Noordhuis | a033261 | 2011-11-29 15:27:52 | [diff] [blame] | 291 | o['variables']['node_use_openssl'] = b(not options.without_ssl) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 292 | |
| 293 | if options.without_ssl: |
| 294 | return |
| 295 | |
| 296 | if options.no_ssl2: |
| 297 | o['defines'] += ['OPENSSL_NO_SSL2=1'] |
| 298 | |
Ryan Dahl | e61de70 | 2011-12-16 23:00:23 | [diff] [blame] | 299 | if not options.openssl_use_sys: |
| 300 | o['variables']['node_use_system_openssl'] = b(False) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 301 | else: |
Ryan Dahl | e61de70 | 2011-12-16 23:00:23 | [diff] [blame] | 302 | out = pkg_config('openssl') |
| 303 | (libs, cflags) = out if out else ('', '') |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 304 | |
Ryan Dahl | e61de70 | 2011-12-16 23:00:23 | [diff] [blame] | 305 | if options.openssl_libpath: |
| 306 | o['libraries'] += ['-L%s' % options.openssl_libpath, '-lssl', '-lcrypto'] |
| 307 | else: |
| 308 | o['libraries'] += libs.split() |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 309 | |
Ryan Dahl | e61de70 | 2011-12-16 23:00:23 | [diff] [blame] | 310 | if options.openssl_includes: |
| 311 | o['include_dirs'] += [options.openssl_includes] |
| 312 | else: |
| 313 | o['cflags'] += cflags.split() |
| 314 | |
| 315 | o['variables']['node_use_system_openssl'] = b( |
| 316 | libs or cflags or options.openssl_libpath or options.openssl_includes) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 317 | |
| 318 | |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 319 | output = { |
| 320 | 'variables': {}, |
| 321 | 'include_dirs': [], |
| 322 | 'libraries': [], |
| 323 | 'defines': [], |
| 324 | 'cflags': [], |
| 325 | } |
| 326 | |
| 327 | configure_node(output) |
| 328 | configure_libz(output) |
| 329 | configure_v8(output) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 330 | configure_openssl(output) |
| 331 | |
| 332 | # variables should be a root level element, |
| 333 | # move everything else to target_defaults |
| 334 | variables = output['variables'] |
| 335 | del output['variables'] |
| 336 | output = { |
| 337 | 'variables': variables, |
| 338 | 'target_defaults': output |
| 339 | } |
Ryan Dahl | 624f70e | 2011-12-23 22:24:50 | [diff] [blame] | 340 | pprint.pprint(output, indent=2) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 341 | |
Ben Noordhuis | e493b29 | 2012-01-17 22:02:15 | [diff] [blame] | 342 | def write(filename, data): |
| 343 | filename = os.path.join(root_dir, filename) |
| 344 | print "creating ", filename |
| 345 | with open(filename, 'w+') as f: |
| 346 | f.write(data) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 347 | |
Ben Noordhuis | e493b29 | 2012-01-17 22:02:15 | [diff] [blame] | 348 | write('config.gypi', "# Do not edit. Generated by the configure script.\n" + |
| 349 | pprint.pformat(output, indent=2)) |
| 350 | |
| 351 | write('config.mk', "# Do not edit. Generated by the configure script.\n" + |
| 352 | ("BUILDTYPE=%s\n" % ('Debug' if options.debug else 'Release'))) |
Ryan Dahl | 14b04b0 | 2011-11-15 03:02:44 | [diff] [blame] | 353 | |
Nathan Rajlich | dc75232 | 2012-03-15 22:17:25 | [diff] [blame] | 354 | if os.name == 'nt': |
| 355 | subprocess.call(['python', 'tools/gyp_node', '-f', 'msvs', |
| 356 | '-G', 'msvs_version=2010']) |
| 357 | else: |
| 358 | subprocess.call(['tools/gyp_node', '-f', 'make']) |