llvm.py revision b8e80941
1848b8605Smrg"""llvm 2848b8605Smrg 3848b8605SmrgTool-specific initialization for LLVM 4848b8605Smrg 5848b8605Smrg""" 6848b8605Smrg 7848b8605Smrg# 8848b8605Smrg# Copyright (c) 2009 VMware, Inc. 9848b8605Smrg# 10848b8605Smrg# Permission is hereby granted, free of charge, to any person obtaining 11848b8605Smrg# a copy of this software and associated documentation files (the 12848b8605Smrg# "Software"), to deal in the Software without restriction, including 13848b8605Smrg# without limitation the rights to use, copy, modify, merge, publish, 14848b8605Smrg# distribute, sublicense, and/or sell copies of the Software, and to 15848b8605Smrg# permit persons to whom the Software is furnished to do so, subject to 16848b8605Smrg# the following conditions: 17848b8605Smrg# 18848b8605Smrg# The above copyright notice and this permission notice shall be included 19848b8605Smrg# in all copies or substantial portions of the Software. 20848b8605Smrg# 21848b8605Smrg# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY 22848b8605Smrg# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 23848b8605Smrg# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24848b8605Smrg# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25848b8605Smrg# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26848b8605Smrg# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27848b8605Smrg# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28848b8605Smrg# 29848b8605Smrg 30848b8605Smrgimport os 31848b8605Smrgimport os.path 32848b8605Smrgimport re 33848b8605Smrgimport sys 34848b8605Smrgimport distutils.version 35848b8605Smrg 36848b8605Smrgimport SCons.Errors 37848b8605Smrgimport SCons.Util 38848b8605Smrg 39848b8605Smrg 40b8e80941Smrgrequired_llvm_version = '3.3' 41848b8605Smrg 42848b8605Smrg 43848b8605Smrgdef generate(env): 44848b8605Smrg env['llvm'] = False 45848b8605Smrg 46848b8605Smrg try: 47848b8605Smrg llvm_dir = os.environ['LLVM'] 48848b8605Smrg except KeyError: 49848b8605Smrg # Do nothing -- use the system headers/libs 50848b8605Smrg llvm_dir = None 51848b8605Smrg else: 52848b8605Smrg if not os.path.isdir(llvm_dir): 53b8e80941Smrg raise SCons.Errors.InternalError("Specified LLVM directory not found") 54848b8605Smrg 55848b8605Smrg if env['debug']: 56848b8605Smrg llvm_subdir = 'Debug' 57848b8605Smrg else: 58848b8605Smrg llvm_subdir = 'Release' 59848b8605Smrg 60848b8605Smrg llvm_bin_dir = os.path.join(llvm_dir, llvm_subdir, 'bin') 61848b8605Smrg if not os.path.isdir(llvm_bin_dir): 62848b8605Smrg llvm_bin_dir = os.path.join(llvm_dir, 'bin') 63848b8605Smrg if not os.path.isdir(llvm_bin_dir): 64b8e80941Smrg raise SCons.Errors.InternalError("LLVM binary directory not found") 65848b8605Smrg 66848b8605Smrg env.PrependENVPath('PATH', llvm_bin_dir) 67848b8605Smrg 68848b8605Smrg if env['platform'] == 'windows': 69848b8605Smrg # XXX: There is no llvm-config on Windows, so assume a standard layout 70848b8605Smrg if llvm_dir is None: 71b8e80941Smrg print('scons: LLVM environment variable must be specified when building for windows') 72848b8605Smrg return 73848b8605Smrg 74848b8605Smrg # Try to determine the LLVM version from llvm/Config/config.h 75b8e80941Smrg llvm_config = os.path.join(llvm_dir, 'include/llvm/Config/llvm-config.h') 76848b8605Smrg if not os.path.exists(llvm_config): 77b8e80941Smrg print('scons: could not find %s' % llvm_config) 78848b8605Smrg return 79b8e80941Smrg llvm_version_major_re = re.compile(r'^#define LLVM_VERSION_MAJOR ([0-9]+)') 80b8e80941Smrg llvm_version_minor_re = re.compile(r'^#define LLVM_VERSION_MINOR ([0-9]+)') 81848b8605Smrg llvm_version = None 82b8e80941Smrg llvm_version_major = None 83b8e80941Smrg llvm_version_minor = None 84848b8605Smrg for line in open(llvm_config, 'rt'): 85b8e80941Smrg mo = llvm_version_major_re.match(line) 86848b8605Smrg if mo: 87b8e80941Smrg llvm_version_major = mo.group(1) 88b8e80941Smrg mo = llvm_version_minor_re.match(line) 89b8e80941Smrg if mo: 90b8e80941Smrg llvm_version_minor = mo.group(1) 91b8e80941Smrg if llvm_version_major is not None and llvm_version_minor is not None: 92b8e80941Smrg llvm_version = distutils.version.LooseVersion('%s.%s' % (llvm_version_major, llvm_version_minor)) 93b8e80941Smrg 94848b8605Smrg if llvm_version is None: 95b8e80941Smrg print('scons: could not determine the LLVM version from %s' % llvm_config) 96848b8605Smrg return 97848b8605Smrg if llvm_version < distutils.version.LooseVersion(required_llvm_version): 98b8e80941Smrg print('scons: LLVM version %s found, but %s is required' % (llvm_version, required_llvm_version)) 99848b8605Smrg return 100848b8605Smrg 101848b8605Smrg env.Prepend(CPPPATH = [os.path.join(llvm_dir, 'include')]) 102848b8605Smrg env.Prepend(LIBPATH = [os.path.join(llvm_dir, 'lib')]) 103b8e80941Smrg # LIBS should match the output of `llvm-config --libs engine mcjit bitwriter x86asmprinter irreader` 104b8e80941Smrg if llvm_version >= distutils.version.LooseVersion('5.0'): 105b8e80941Smrg env.Prepend(LIBS = [ 106b8e80941Smrg 'LLVMX86Disassembler', 'LLVMX86AsmParser', 107b8e80941Smrg 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter', 108b8e80941Smrg 'LLVMDebugInfoCodeView', 'LLVMCodeGen', 109b8e80941Smrg 'LLVMScalarOpts', 'LLVMInstCombine', 110b8e80941Smrg 'LLVMTransformUtils', 111b8e80941Smrg 'LLVMBitWriter', 'LLVMX86Desc', 112b8e80941Smrg 'LLVMMCDisassembler', 'LLVMX86Info', 113b8e80941Smrg 'LLVMX86AsmPrinter', 'LLVMX86Utils', 114b8e80941Smrg 'LLVMMCJIT', 'LLVMExecutionEngine', 'LLVMTarget', 115b8e80941Smrg 'LLVMAnalysis', 'LLVMProfileData', 116b8e80941Smrg 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 117b8e80941Smrg 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 118b8e80941Smrg 'LLVMSupport', 119b8e80941Smrg 'LLVMIRReader', 'LLVMAsmParser', 120b8e80941Smrg 'LLVMDemangle', 'LLVMGlobalISel', 'LLVMDebugInfoMSF', 121b8e80941Smrg 'LLVMBinaryFormat', 122b8e80941Smrg ]) 123b8e80941Smrg if env['platform'] == 'windows' and env['crosscompile']: 124b8e80941Smrg # LLVM 5.0 requires MinGW w/ pthreads due to use of std::thread and friends. 125b8e80941Smrg assert env['gcc'] 126b8e80941Smrg env['CXX'] = env['CXX'] + '-posix' 127b8e80941Smrg elif llvm_version >= distutils.version.LooseVersion('4.0'): 128b8e80941Smrg env.Prepend(LIBS = [ 129b8e80941Smrg 'LLVMX86Disassembler', 'LLVMX86AsmParser', 130b8e80941Smrg 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter', 131b8e80941Smrg 'LLVMDebugInfoCodeView', 'LLVMCodeGen', 132b8e80941Smrg 'LLVMScalarOpts', 'LLVMInstCombine', 133b8e80941Smrg 'LLVMTransformUtils', 134b8e80941Smrg 'LLVMBitWriter', 'LLVMX86Desc', 135b8e80941Smrg 'LLVMMCDisassembler', 'LLVMX86Info', 136b8e80941Smrg 'LLVMX86AsmPrinter', 'LLVMX86Utils', 137b8e80941Smrg 'LLVMMCJIT', 'LLVMExecutionEngine', 'LLVMTarget', 138b8e80941Smrg 'LLVMAnalysis', 'LLVMProfileData', 139b8e80941Smrg 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 140b8e80941Smrg 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 141b8e80941Smrg 'LLVMSupport', 142b8e80941Smrg 'LLVMIRReader', 'LLVMAsmParser', 143b8e80941Smrg 'LLVMDemangle', 'LLVMGlobalISel', 'LLVMDebugInfoMSF', 144b8e80941Smrg ]) 145b8e80941Smrg elif llvm_version >= distutils.version.LooseVersion('3.9'): 146b8e80941Smrg env.Prepend(LIBS = [ 147b8e80941Smrg 'LLVMX86Disassembler', 'LLVMX86AsmParser', 148b8e80941Smrg 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter', 149b8e80941Smrg 'LLVMDebugInfoCodeView', 'LLVMCodeGen', 150b8e80941Smrg 'LLVMScalarOpts', 'LLVMInstCombine', 151b8e80941Smrg 'LLVMInstrumentation', 'LLVMTransformUtils', 152b8e80941Smrg 'LLVMBitWriter', 'LLVMX86Desc', 153b8e80941Smrg 'LLVMMCDisassembler', 'LLVMX86Info', 154b8e80941Smrg 'LLVMX86AsmPrinter', 'LLVMX86Utils', 155b8e80941Smrg 'LLVMMCJIT', 'LLVMExecutionEngine', 'LLVMTarget', 156b8e80941Smrg 'LLVMAnalysis', 'LLVMProfileData', 157b8e80941Smrg 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 158b8e80941Smrg 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 159b8e80941Smrg 'LLVMSupport', 160b8e80941Smrg 'LLVMIRReader', 'LLVMASMParser' 161b8e80941Smrg ]) 162b8e80941Smrg elif llvm_version >= distutils.version.LooseVersion('3.7'): 163848b8605Smrg env.Prepend(LIBS = [ 164848b8605Smrg 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser', 165b8e80941Smrg 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter', 166b8e80941Smrg 'LLVMCodeGen', 'LLVMScalarOpts', 'LLVMProfileData', 167b8e80941Smrg 'LLVMInstCombine', 'LLVMInstrumentation', 'LLVMTransformUtils', 'LLVMipa', 168b8e80941Smrg 'LLVMAnalysis', 'LLVMX86Desc', 'LLVMMCDisassembler', 169b8e80941Smrg 'LLVMX86Info', 'LLVMX86AsmPrinter', 'LLVMX86Utils', 170b8e80941Smrg 'LLVMMCJIT', 'LLVMTarget', 'LLVMExecutionEngine', 171b8e80941Smrg 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 172b8e80941Smrg 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 'LLVMSupport' 173b8e80941Smrg ]) 174b8e80941Smrg elif llvm_version >= distutils.version.LooseVersion('3.6'): 175b8e80941Smrg env.Prepend(LIBS = [ 176b8e80941Smrg 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser', 177b8e80941Smrg 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter', 178b8e80941Smrg 'LLVMCodeGen', 'LLVMScalarOpts', 'LLVMProfileData', 179b8e80941Smrg 'LLVMInstCombine', 'LLVMTransformUtils', 'LLVMipa', 180b8e80941Smrg 'LLVMAnalysis', 'LLVMX86Desc', 'LLVMMCDisassembler', 181b8e80941Smrg 'LLVMX86Info', 'LLVMX86AsmPrinter', 'LLVMX86Utils', 182b8e80941Smrg 'LLVMMCJIT', 'LLVMTarget', 'LLVMExecutionEngine', 183b8e80941Smrg 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 184b8e80941Smrg 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 'LLVMSupport' 185b8e80941Smrg ]) 186b8e80941Smrg elif llvm_version >= distutils.version.LooseVersion('3.5'): 187b8e80941Smrg env.Prepend(LIBS = [ 188b8e80941Smrg 'LLVMMCDisassembler', 189b8e80941Smrg 'LLVMBitWriter', 'LLVMMCJIT', 'LLVMRuntimeDyld', 190b8e80941Smrg 'LLVMX86Disassembler', 'LLVMX86AsmParser', 'LLVMX86CodeGen', 191b8e80941Smrg 'LLVMSelectionDAG', 'LLVMAsmPrinter', 'LLVMX86Desc', 192b8e80941Smrg 'LLVMObject', 'LLVMMCParser', 'LLVMBitReader', 'LLVMX86Info', 193b8e80941Smrg 'LLVMX86AsmPrinter', 'LLVMX86Utils', 'LLVMJIT', 194848b8605Smrg 'LLVMExecutionEngine', 'LLVMCodeGen', 'LLVMScalarOpts', 195848b8605Smrg 'LLVMInstCombine', 'LLVMTransformUtils', 'LLVMipa', 196848b8605Smrg 'LLVMAnalysis', 'LLVMTarget', 'LLVMMC', 'LLVMCore', 197b8e80941Smrg 'LLVMSupport' 198848b8605Smrg ]) 199848b8605Smrg else: 200848b8605Smrg env.Prepend(LIBS = [ 201b8e80941Smrg 'LLVMMCDisassembler', 202848b8605Smrg 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser', 203848b8605Smrg 'LLVMX86CodeGen', 'LLVMX86Desc', 'LLVMSelectionDAG', 204848b8605Smrg 'LLVMAsmPrinter', 'LLVMMCParser', 'LLVMX86AsmPrinter', 205848b8605Smrg 'LLVMX86Utils', 'LLVMX86Info', 'LLVMMCJIT', 'LLVMJIT', 206848b8605Smrg 'LLVMExecutionEngine', 'LLVMCodeGen', 'LLVMScalarOpts', 207848b8605Smrg 'LLVMInstCombine', 'LLVMTransformUtils', 'LLVMipa', 208848b8605Smrg 'LLVMAnalysis', 'LLVMTarget', 'LLVMMC', 'LLVMCore', 209b8e80941Smrg 'LLVMSupport', 'LLVMRuntimeDyld', 'LLVMObject' 210848b8605Smrg ]) 211848b8605Smrg env.Append(LIBS = [ 212848b8605Smrg 'imagehlp', 213848b8605Smrg 'psapi', 214848b8605Smrg 'shell32', 215b8e80941Smrg 'advapi32', 216b8e80941Smrg 'ole32', 217b8e80941Smrg 'uuid', 218848b8605Smrg ]) 219b8e80941Smrg 220848b8605Smrg if env['msvc']: 221848b8605Smrg # Some of the LLVM C headers use the inline keyword without 222848b8605Smrg # defining it. 223848b8605Smrg env.Append(CPPDEFINES = [('inline', '__inline')]) 224b8e80941Smrg # Match some of the warning options from llvm/cmake/modules/HandleLLVMOptions.cmake 225b8e80941Smrg env.AppendUnique(CXXFLAGS = [ 226b8e80941Smrg '/wd4355', # 'this' : used in base member initializer list 227b8e80941Smrg '/wd4624', # 'derived class' : destructor could not be generated because a base class destructor is inaccessible 228b8e80941Smrg ]) 229848b8605Smrg if env['build'] in ('debug', 'checked'): 230848b8605Smrg # LLVM libraries are static, build with /MT, and they 231848b8605Smrg # automatically link agains LIBCMT. When we're doing a 232848b8605Smrg # debug build we'll be linking against LIBCMTD, so disable 233848b8605Smrg # that. 234848b8605Smrg env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT']) 235848b8605Smrg else: 236b8e80941Smrg llvm_config = os.environ.get('LLVM_CONFIG', 'llvm-config') 237b8e80941Smrg if not env.Detect(llvm_config): 238b8e80941Smrg print('scons: %s script not found' % llvm_config) 239848b8605Smrg return 240848b8605Smrg 241b8e80941Smrg llvm_version = env.backtick('%s --version' % llvm_config).rstrip() 242848b8605Smrg llvm_version = distutils.version.LooseVersion(llvm_version) 243848b8605Smrg 244848b8605Smrg if llvm_version < distutils.version.LooseVersion(required_llvm_version): 245b8e80941Smrg print('scons: LLVM version %s found, but %s is required' % (llvm_version, required_llvm_version)) 246848b8605Smrg return 247848b8605Smrg 248848b8605Smrg try: 249848b8605Smrg # Treat --cppflags specially to prevent NDEBUG from disabling 250848b8605Smrg # assertion failures in debug builds. 251b8e80941Smrg cppflags = env.ParseFlags('!%s --cppflags' % llvm_config) 252848b8605Smrg try: 253848b8605Smrg cppflags['CPPDEFINES'].remove('NDEBUG') 254848b8605Smrg except ValueError: 255848b8605Smrg pass 256848b8605Smrg env.MergeFlags(cppflags) 257848b8605Smrg 258848b8605Smrg # Match llvm --fno-rtti flag 259b8e80941Smrg cxxflags = env.backtick('%s --cxxflags' % llvm_config).split() 260848b8605Smrg if '-fno-rtti' in cxxflags: 261848b8605Smrg env.Append(CXXFLAGS = ['-fno-rtti']) 262848b8605Smrg 263b8e80941Smrg components = ['engine', 'mcjit', 'bitwriter', 'x86asmprinter', 'mcdisassembler', 'irreader'] 264848b8605Smrg 265b8e80941Smrg env.ParseConfig('%s --libs ' % llvm_config + ' '.join(components)) 266b8e80941Smrg env.ParseConfig('%s --ldflags' % llvm_config) 267848b8605Smrg if llvm_version >= distutils.version.LooseVersion('3.5'): 268b8e80941Smrg env.ParseConfig('%s --system-libs' % llvm_config) 269848b8605Smrg env.Append(CXXFLAGS = ['-std=c++11']) 270848b8605Smrg except OSError: 271b8e80941Smrg print('scons: llvm-config version %s failed' % llvm_version) 272848b8605Smrg return 273848b8605Smrg 274848b8605Smrg assert llvm_version is not None 275848b8605Smrg env['llvm'] = True 276848b8605Smrg 277b8e80941Smrg print('scons: Found LLVM version %s' % llvm_version) 278848b8605Smrg env['LLVM_VERSION'] = llvm_version 279848b8605Smrg 280848b8605Smrg # Define HAVE_LLVM macro with the major/minor version number (e.g., 0x0206 for 2.6) 281848b8605Smrg llvm_version_major = int(llvm_version.version[0]) 282848b8605Smrg llvm_version_minor = int(llvm_version.version[1]) 283848b8605Smrg llvm_version_hex = '0x%02x%02x' % (llvm_version_major, llvm_version_minor) 284848b8605Smrg env.Prepend(CPPDEFINES = [('HAVE_LLVM', llvm_version_hex)]) 285848b8605Smrg 286848b8605Smrgdef exists(env): 287848b8605Smrg return True 288848b8605Smrg 289848b8605Smrg# vim:set ts=4 sw=4 et: 290