#!/usr/bin/env python # # Attribution Notice # ------------------ # This file uses parts of Node.js `configure`. # Please refer to https://github.com/joyent/node. # import optparse import os import pprint import re import shlex import subprocess import sys import platform CC = os.environ.get('CC', 'cc') root_dir = os.path.dirname(__file__) build_dir = './build' # Parse options parser = optparse.OptionParser() parser.add_option("--debug", action="store_true", dest="debug", help="Also build the debug build.") parser.add_option("--dest-cpu", action="store", dest="dest_cpu", help="CPU architecture to build for. Valid values are: ia32, x64.") parser.add_option("--shared", action="store_true", dest="shared", help="Build and use shared libsnowcrash instead of static one.") parser.add_option("--include-integration-tests", action="store_true", dest="include_integration_tests", help="Configure for integration testing using Cucumber") (options, args) = parser.parse_args() def write(filename, data): filename = os.path.join(root_dir, filename) print "creating ", filename f = open(filename, 'w+') f.write(data) def cc_macros(): """Checks predefined macros using the CC command.""" try: p = subprocess.Popen(shlex.split(CC) + ['-dM', '-E', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError: print '''Configure error: No acceptable C compiler found! Please make sure you have a C compiler installed on your system and/or consider adjusting the CC environment variable if you installed it in a non-standard prefix. ''' sys.exit() p.stdin.write('\n') out = p.communicate()[0] out = str(out).split('\n') k = {} for line in out: lst = shlex.split(line) if len(lst) > 2: key = lst[1] val = lst[2] k[key] = val return k def host_arch_cc(): """Host architecture check using the CC command.""" k = cc_macros() matchup = { '__x86_64__' : 'x64', '__i386__' : 'ia32', '__arm__' : 'arm', } rtn = 'ia32' # default for i in matchup: if i in k and k[i] != '0': rtn = matchup[i] break return rtn def host_arch_win(): """Host architecture check using environ vars (better way to do this?)""" arch = os.environ.get('PROCESSOR_ARCHITECTURE', 'x86') matchup = { 'AMD64' : 'x64', 'x86' : 'ia32', 'arm' : 'arm', } return matchup.get(arch, 'ia32') def configure_snowcrash(o): # Build configuration o['default_configuration'] = 'Debug' if options.debug else 'Release' # Architecture host_arch = host_arch_win() if os.name == 'nt' else host_arch_cc() target_arch = options.dest_cpu or host_arch o['variables']['host_arch'] = host_arch o['variables']['target_arch'] = target_arch o['variables']['libsnowcrash_type'] = 'shared_library' if options.shared else 'static_library' # # Cucumber testing environment # # TODO: use bundle check if options.include_integration_tests: print "Installing dependencies for integration tests..." try: if sys.platform == 'win32': subprocess.call(["bundle.bat", "install"]) else: subprocess.call(["bundle", "install"]) except OSError as e: if e.errno == os.errno.ENOENT: raise RuntimeError( "Integration test dependecies rely on Ruby Bundler " "but it cannot be find in the system $PATH. " "Please make sure to install Bundler or/and to " "add it to the $PATH." ) else: raise # # config.gypi # output = { 'variables': { 'python': sys.executable }, 'include_dirs': [], 'libraries': [], 'defines': [], 'cflags': [], } configure_snowcrash(output) # variables should be a root level element, # move everything else to target_defaults variables = output['variables'] del output['variables'] output = { 'variables': variables, 'target_defaults': output } write('config.gypi', "# Do not edit. Generated by the configure script.\n" + pprint.pformat(output, indent=2) + "\n") # # config.mk # config = { 'BUILDTYPE': 'Debug' if options.debug else 'Release', 'PYTHON': sys.executable, 'BUILD_DIR': build_dir, 'INTEGRATION_TESTS': '1' if options.include_integration_tests else '' } config = '\n'.join(map('='.join, config.iteritems())) + '\n' write('config.mk', '# Do not edit. Generated by the configure script.\n' + config) # # Gyp call # print "creating makefiles" gyp_args = ['--generator-output', build_dir, '--depth', '.'] if sys.platform == 'win32': # Windows gyp_args.extend(['-f', 'msvs']) else: # Posix systems gyp_args.extend(['-f', 'make']) # Include common.gypi and config.gypi if sys.platform == 'win32': options_fn = os.path.join(root_dir, 'config.gypi') else: options_fn = os.path.join(os.path.abspath(root_dir), 'config.gypi') if os.path.exists(options_fn): gyp_args.extend(['-I', options_fn]) subprocess.call([sys.executable, 'tools/gyp/gyp_main.py'] + gyp_args) # All done print "All OK."