https://github.com/twitter/heron
Raw File
Tip revision: ea8641a25b2c393a00757e6e227acef024cddd7a authored by Heron Release System on 09 March 2016, 21:31:45 UTC
Release 0.13.0-C (2016-03-09)
Tip revision: ea8641a
bazel_configure.py
#!/usr/bin/env python2.7 
import os, sys
import subprocess, shutil

######################################################################
# Architecture and system defines
######################################################################
ARCH_AND_SYS = { 
  ('x86_64', 'Darwin') : ('IS_I386_MACOSX', 'IS_MACOSX'),
  ('x86_64', 'Linux' )  : ('IS_I386_LINUX',  'IS_LINUX'),
}

######################################################################
# Discover the name of the user compiling
######################################################################
def discover_user():
  return subprocess.check_output("whoami", shell=True).strip("\n")
  
######################################################################
# Discover the name of the host compiling
######################################################################
def discover_host():
  return subprocess.check_output("uname -n", shell=True).strip("\n")
  
######################################################################
# Get the time of the setup - does not change every time you compile
######################################################################
def discover_timestamp():
  return subprocess.check_output("date", shell=True).strip("\n")
  
######################################################################
# Get the processor the platform is running on
######################################################################
def discover_processor():
  return subprocess.check_output("uname -m", shell=True).strip("\n")

######################################################################
# Get the operating system of the platform
######################################################################
def discover_os():
  return subprocess.check_output("uname -s", shell=True).strip("\n")

######################################################################
# Get the operating system version
######################################################################
def discover_os_version():
  return subprocess.check_output("uname -r", shell=True).strip("\n")
  
######################################################################
# Get the git sha of the branch - you are working
######################################################################
def discover_git_sha():
  return subprocess.check_output("git rev-parse HEAD", shell=True).strip("\n")

######################################################################
# Get the name of branch - you are working on
######################################################################
def discover_git_branch():
  return subprocess.check_output("git rev-parse --abbrev-ref HEAD", shell=True).strip("\n")

######################################################################
# Utility functions for system defines
######################################################################
def define_string(name, value):
  return '#define %s "%s"\n' % (name, value)

def define_value(name, value):
  return '#define %s %s\n' % (name, value)

######################################################################
# Discover where a program is located using the PATH variable
######################################################################
def which(program):
  def is_exe(fpath):
    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

  def ext_candidates(fpath):
    yield fpath
    for ext in os.environ.get("PATHEXT", "").split(os.pathsep):
      yield fpath + ext

  fpath, fname = os.path.split(program)
  if fpath:
    if is_exe(program):
      return program
  else:
    for path in os.environ["PATH"].split(os.pathsep):
      exe_file = os.path.join(path, program)
      for candidate in ext_candidates(exe_file):
        if is_exe(candidate):
          return candidate

  return None

######################################################################
# Discover the real path of the program
######################################################################
def real_program_path(program_name):
  which_path = which(program_name)
  if which_path:
    return os.path.realpath(which_path)

  return None

######################################################################
# Get the real path of the program
######################################################################
def real_path(apath):
  return os.path.realpath(apath)

######################################################################
# Discover the program using env variable/program name 
######################################################################
def discover_program(program_name, env_variable = ""):
  env_value = program_name
  if len(env_variable) > 0:
    try:
      env_value = os.environ[env_variable]
    except KeyError:
      pass

  return real_program_path(env_value)
      
######################################################################
# Get the platform we are running
######################################################################
def discover_platform():
  output = subprocess.Popen(['uname'], stdout=subprocess.PIPE).communicate()
  return output[0].strip("\n")

######################################################################
# Make the file executable
######################################################################
def make_executable(path):
  mode = os.stat(path).st_mode
  mode |= (mode & 0444) >> 2    # copy R bits to X
  os.chmod(path, mode)

######################################################################
# Discover a tool needed to compile Heron
######################################################################
def discover_tool(program, msg, envvar = ""):
  VALUE = discover_program(program, envvar)
  if not VALUE:
    print 'You need to have %s installed to build Heron.' % (program)
    print 'Note: Some vendors install %s with a versioned name' % (program)
    print '(like /usr/bin/%s-4.8). You can set the %s environment' % (program, envvar)
    print 'variable to specify the full path to yours.'
    sys.exit(1)
  print 'Using %s: \t\t "%s"' % (msg, VALUE)
  return VALUE

######################################################################
# Discover the linker directory
######################################################################
def discover_linker(environ):
  BLDFLAG = '-B' + os.path.dirname(environ['LD'])
  return BLDFLAG

######################################################################
# Discover a tool needed but default to certain value if not able to
######################################################################
def discover_tool_default(program, msg, envvar, defvalue):
  VALUE = discover_program(program, envvar)
  if not VALUE:
    VALUE = defvalue
    print '%s : \t\t\t not found, but ok' % (program)
  else:
    print 'Using %s : \t\t\t "%s"' % (msg, VALUE)
  return VALUE

######################################################################
# Discover the includes paths for files
######################################################################
def discover_include_paths(program):
  includes_command = program + ' -E -x c++ - -v 2>&1 < /dev/null '  \
    + '| sed -n \'/search starts here:/,/End of search list/p\' '  \
    + '| sed \'/#include.*/d\' ' \
    + '| sed \'/End of search list./d\' '
  includes = subprocess.Popen(includes_command, shell=True, stdout=subprocess.PIPE).communicate()[0]
  include_paths = [real_path(path.strip()) for path in includes.split('\n')]
  builtin_includes  = '\n'.join([
    '  cxx_builtin_include_directory: "%s"' % item for item in include_paths
  ])
  return builtin_includes

######################################################################
# Generate the shell script that recreates the environment
######################################################################
def write_env_exec_file(platform, environ):

  env_exec_file = 'scripts/env_exec.sh'
  out_file = open(env_exec_file, 'w')
  out_file.write('#!/bin/bash\n\n')
  out_file.write('set -eu \n\n')

  # If C environment is set, export them
  if 'CC' in os.environ:
    out_file.write('export CC=' + os.environ['CC'] + '\n')
  if 'CPP' in os.environ:
    out_file.write('export CPP=' + os.environ['CPP'] + '\n')
  if 'CFLAGS' in os.environ:
    out_file.write('export CFLAGS=' + os.environ['CFLAGS'] + '\n')

  # If CXX environment is set, export them
  if 'CXX' in os.environ:
    out_file.write('export CXX=' + os.environ['CXX'] + '\n')
  if 'CXXCPP' in os.environ:
    out_file.write('export CXXCPP=' + os.environ['CXXCPP'] + '\n')
  if 'CXXFLAGS' in os.environ:
    out_file.write('export CXXFLAGS=' + os.environ['CXXFLAGS'] + '\n')

  # If linker environment is set, export them
  if 'LDFLAGS' in os.environ:
    out_file.write('export LDFLAGS=' + os.environ['LDFLAGS'] + '\n')
  if 'LIBS' in os.environ:
    out_file.write('export LIBS=' + os.environ['LIBS'] + '\n')

  # Invoke the programs
  out_file.write('# Execute the input programs\n')
  out_file.write('$*')

  make_executable(env_exec_file)
  print 'Wrote the environment exec file:  \t"%s"' % (env_exec_file)


######################################################################
# Generate system defines based on processor, os and os version
######################################################################
def generate_system_defines():
  key = (discover_processor(), discover_os(), discover_os_version())
  if key in ARCH_AND_SYS:
    defines = ARCH_AND_SYS[key]
  else:
    key = (discover_processor(), discover_os())
    defines = ARCH_AND_SYS[key]

  strings = []
  for define in defines:
    strings.append(define_value(define, '1'))
  return "".join(strings)

######################################################################
# Write heron config header at config/heron-config.h
######################################################################
def write_heron_config_header(config_file):
  if os.path.exists(config_file): os.unlink(config_file)
  out_file = open(config_file, 'w')
  out_file.write(define_string('PACKAGE', 'heron'))
  out_file.write(define_string('PACKAGE_NAME', 'heron'))
  out_file.write(define_string('PACKAGE_VERSION', 'unversioned'))
    
  out_file.write(define_string('PACKAGE_COMPILE_USER', discover_user()))
  out_file.write(define_string('PACKAGE_COMPILE_HOST', discover_host()))
  out_file.write(define_string('PACKAGE_COMPILE_TIME', discover_timestamp()))

  out_file.write(define_string('GIT_SHA', discover_git_sha()))
  out_file.write(define_string('GIT_BRANCH', discover_git_branch()))
  out_file.write(generate_system_defines())
  out_file.close()
  print 'Wrote the heron config header file: \t"%s"' % (config_file) 

######################################################################
# MAIN program that sets up your workspace for bazel
######################################################################
def main():
  env_map = dict()

  # Discover the platform
  platform = discover_platform()

  # Discover the tools environment
  env_map['CC'] = discover_tool('gcc',"C compiler", 'CC')
  env_map['CXX'] = discover_tool('g++',"C++ compiler", 'CXX')
  env_map['CPP'] = discover_tool('cpp',"C preprocessor", 'CPP')
  env_map['CXXCPP'] = discover_tool('cpp',"C++ preprocessor", 'CXXCPP')
  env_map['LD'] =  discover_tool('ld',"linker", 'LD')
  env_map['BLDFLAG'] = discover_linker(env_map)

  # Discover the utilities
  env_map['AUTOMAKE'] = discover_tool('automake', "Automake")
  env_map['AUTOCONF'] = discover_tool('autoconf', "Autoconf")
  env_map['MAKE'] = discover_tool('make', "Make")
  env_map['CMAKE'] = discover_tool('cmake', "CMake")
  env_map['PYTHON2'] = discover_tool('python2', "Python2")

  if platform == "Darwin":
    env_map['AR'] = discover_tool('libtool', "archiver", 'AR')
  else:
    env_map['AR'] = discover_tool('ar', "archiver", 'AR')

  env_map['GCOV']= discover_tool('gcov',"coverage tool", 'GCOV')
  env_map['DWP'] = discover_tool_default('dwp', "dwp", 'DWP', '/usr/bin/dwp')
  env_map['NM'] = discover_tool_default('nm', "nm", 'NM', '/usr/bin/nm')
  env_map['OBJCOPY'] = discover_tool_default('objcopy', "objcopy", 'OBJCOPY', '/usr/bin/objcopy')
  env_map['OBJDUMP'] = discover_tool_default('objdump', "objdump", 'OBJDUMP', '/usr/bin/objdump')
  env_map['STRIP'] = discover_tool_default('strip', "strip", 'STRIP', '/usr/bin/strip')

  # write the environment executable file
  write_env_exec_file(platform, env_map)

if __name__ == '__main__':
  main()
back to top