AMBuildScript
author David Anderson <danderson@mozilla.com>
Wed Jul 25 01:30:33 2012 -0700 (2012-07-25)
changeset 92 e3974e7360e9
parent 91 5f4402180204
child 93 23189d937087
permissions -rw-r--r--
Add GCC/Linux support.
     1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
     2 import os
     3 import sys
     4 from ambuild.command import SymlinkCommand
     5 
     6 class KE:
     7 	def __init__(self):
     8 		self.compiler = Cpp.Compiler()
     9 
    10 		if AMBuild.mode == 'config':
    11 			#Detect compilers
    12 			self.compiler.DetectAll(AMBuild)
    13 
    14 			#Set up defines
    15 			cxx = self.compiler.cxx
    16 			if isinstance(cxx, Cpp.CompatGCC):
    17 				if isinstance(cxx, Cpp.GCC):
    18 					self.vendor = 'gcc'
    19 				elif isinstance(cxx, Cpp.Clang):
    20 					self.vendor = 'clang'
    21 				self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
    22 				self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
    23 				self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
    24 				self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
    25 				self.compiler.AddToListVar('CFLAGS', '-pipe')
    26 				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
    27 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
    28 					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
    29 					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
    30 				self.compiler.AddToListVar('CFLAGS', '-Wall')
    31 				self.compiler.AddToListVar('CFLAGS', '-Werror')
    32 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
    33 
    34 				if AMBuild.options.arch == 'x86':
    35 					self.compiler.AddToListVar('CFLAGS', '-m32')
    36 					self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
    37 				elif AMBuild.options.arch == 'x64':
    38 					self.compiler.AddToListVar('CFLAGS', '-m64')
    39 					self.compiler.AddToListVar('POSTLINKFLAGS', '-m64')
    40 				elif AMBuild.options.arch:
    41 					raise Exception('Unknown architecture: {0}'.format(AMBuild.options.arch))
    42 
    43 				# Disable some stuff we don't use, that gives us better binary
    44         # compatibility on Linux.
    45 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
    46 				self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
    47 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
    48 
    49 				# We don't really care about these.
    50 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
    51 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
    52 
    53 				# The compiler is too aggressive about what what should be a valid offsetof.
    54 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-invalid-offsetof')
    55 
    56 				# This would otherwise forbid ((x = y) == NULL) in clang apparently.
    57 				if self.vendor == 'clang':
    58 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-null-arithmetic')
    59 
    60 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \
    61 						(self.vendor == 'clang' and cxx.majorVersion >= 3):
    62 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
    63 
    64 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lm')
    65 			elif isinstance(cxx, Cpp.MSVC):
    66 				self.vendor = 'msvc'
    67 				if AMBuild.options.debug == '1':
    68 					self.compiler.AddToListVar('CFLAGS', '/MTd')
    69 					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
    70 				else:
    71 					self.compiler.AddToListVar('CFLAGS', '/MT')
    72 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
    73 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
    74 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
    75 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
    76 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
    77 				self.compiler.AddToListVar('CFLAGS', '/W3')
    78 				self.compiler.AddToListVar('CFLAGS', '/nologo')
    79 				self.compiler.AddToListVar('CFLAGS', '/Zi')
    80 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
    81 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
    82 
    83 				# if AMBuild.options.arch == 'x86':
    84 				# 	self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
    85 				# elif AMBuild.options.arch == 'x64':
    86 				# 	self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X64')
    87 				# elif AMBuild.options.arch:
    88 				# 	raise Exception('Unknown architecture: {0}'.format(AMBuild.options.arch))
    89 
    90 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
    91 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
    92 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
    93 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
    94 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
    95 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
    96 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
    97 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
    98 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
    99 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   100 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   101 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   102 
   103 			#Optimization
   104 			if AMBuild.options.opt == '1':
   105 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   106 				if self.vendor == 'gcc' or self.vendor == 'clang':
   107 					self.compiler.AddToListVar('CFLAGS', '-O3')
   108 				elif self.vendor == 'msvc':
   109 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   110 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   111 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   112 
   113 			#Debugging
   114 			if AMBuild.options.debug == '1':
   115 				self.compiler.AddToListVar('CDEFINES', 'DEBUG')
   116 				self.compiler.AddToListVar('CDEFINES', '_DEBUG')
   117 				if self.vendor == 'gcc' or self.vendor == 'clang':
   118 					self.compiler.AddToListVar('CFLAGS', '-g3')
   119 				elif self.vendor == 'msvc':
   120 					self.compiler.AddToListVar('CFLAGS', '/Od')
   121 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   122 
   123 			#Platform-specifics
   124 			if AMBuild.target['platform'] == 'linux':
   125 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   126 				if self.vendor == 'gcc':
   127 					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   128 				if self.vendor == 'clang':
   129 					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   130 			elif AMBuild.target['platform'] == 'darwin':
   131 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   132 				if AMBuild.options.arch == 'x86':
   133 					self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   134 				elif AMBuild.options.arch == 'x64':
   135 					self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'x86_64'])
   136 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   137 
   138 				# For OS X dylib versioning
   139 				import re
   140 				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   141 				productContents = productFile.read()
   142 				productFile.close()
   143 				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   144 				if m == None:
   145 					self.version = '1.0.0'
   146 				else:
   147 					major, minor, release = m.groups()
   148 					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   149 				AMBuild.cache.CacheVariable('version', self.version)
   150 
   151 			#Finish up
   152 			self.compiler.ToConfig(AMBuild, 'compiler')
   153 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   154 			self.targetMap = { }
   155 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   156 		else:
   157 			self.compiler.FromConfig(AMBuild, 'compiler')
   158 			self.targetMap = AMBuild.cache['targetMap']
   159 
   160 	def DefaultCompiler(self):
   161 		return self.compiler.Clone()
   162 
   163 	def JobMatters(self, jobname):
   164 		file = sys._getframe().f_code.co_filename
   165 		if AMBuild.mode == 'config':
   166 			self.targetMap[jobname] = file
   167 			return True
   168 		if len(AMBuild.args) == 0:
   169 			return True
   170 		if not jobname in AMBuild.args:
   171 			return False
   172 
   173 ke = KE()
   174 globals = {
   175 	'KE': ke
   176 }
   177 
   178 FileList = [
   179 		['src', 'AMBuild.library'],
   180 		['src', 'AMBuild.shell']
   181 	]
   182 
   183 for parts in FileList:
   184 	AMBuild.Include(os.path.join(*parts), globals)
   185