AMBuildScript
author David Anderson <dvander@alliedmods.net>
Tue Jan 01 16:28:34 2013 -0800 (2013-01-01)
changeset 252 1dee2330aa78
parent 251 ca99a81745fe
child 253 544c478362c2
permissions -rw-r--r--
Fix linux/mac support.
     1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
     2 # 
     3 # Copyright (C) 2004-2012 David Anderson
     4 # 
     5 # This file is part of SourcePawn.
     6 # 
     7 # SourcePawn is free software: you can redistribute it and/or modify it under
     8 # the terms of the GNU General Public License as published by the Free
     9 # Software Foundation, either version 3 of the License, or (at your option)
    10 # any later version.
    11 # 
    12 # SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15 # 
    16 # You should have received a copy of the GNU General Public License along with
    17 # SourcePawn. If not, see http://www.gnu.org/licenses/.
    18 #
    19 
    20 import os
    21 import sys
    22 from ambuild.command import SymlinkCommand
    23 
    24 class KE:
    25 	def __init__(self):
    26 		self.compiler = Cpp.Compiler()
    27 
    28 		if AMBuild.mode == 'config':
    29 			#Detect compilers
    30 			self.compiler.DetectAll(AMBuild)
    31 
    32 			#Set up defines
    33 			cxx = self.compiler.cxx
    34 			if isinstance(cxx, Cpp.CompatGCC):
    35 				if isinstance(cxx, Cpp.GCC):
    36 					self.vendor = 'gcc'
    37 				elif isinstance(cxx, Cpp.Clang):
    38 					self.vendor = 'clang'
    39 				self.compiler.AddToListVar('CFLAGS', '-pipe')
    40 				self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
    41 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
    42 					self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
    43 					self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
    44 				self.compiler.AddToListVar('CFLAGS', '-Wall')
    45 				self.compiler.AddToListVar('CFLAGS', '-Werror')
    46 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
    47 
    48 				if AMBuild.options.arch == 'x86':
    49 					self.compiler.AddToListVar('CFLAGS', '-m32')
    50 					self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
    51 				elif AMBuild.options.arch == 'x64':
    52 					self.compiler.AddToListVar('CFLAGS', '-m64')
    53 					self.compiler.AddToListVar('POSTLINKFLAGS', '-m64')
    54 				elif AMBuild.options.arch:
    55 					raise Exception('Unknown architecture: {0}'.format(AMBuild.options.arch))
    56 
    57 				# Disable some stuff we don't use, that gives us better binary
    58         # compatibility on Linux.
    59 				self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
    60 				self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
    61 				self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
    62 
    63 				# We don't really care about these.
    64 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
    65 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
    66 
    67 				# The compiler is too aggressive about what what should be a valid offsetof.
    68 				self.compiler.AddToListVar('CXXFLAGS', '-Wno-invalid-offsetof')
    69 
    70 				# This would otherwise forbid ((x = y) == NULL) in clang apparently.
    71 				if self.vendor == 'clang' and cxx.majorVersion > 1:
    72 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-null-arithmetic')
    73 				if self.vendor == 'clang' and \
    74 				   cxx.majorVersion >= 3 and \
    75 				   cxx.minorVersion >= 3:
    76 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-unused-private-field')
    77 
    78 				if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 7) or \
    79 						(self.vendor == 'clang' and cxx.majorVersion >= 3):
    80 					self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
    81 
    82 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lm')
    83 			elif isinstance(cxx, Cpp.MSVC):
    84 				self.vendor = 'msvc'
    85 				if AMBuild.options.debug == '1':
    86 					self.compiler.AddToListVar('CFLAGS', '/MTd')
    87 					self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
    88 				else:
    89 					self.compiler.AddToListVar('CFLAGS', '/MT')
    90 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
    91 				self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
    92 				self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
    93 				self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
    94 				self.compiler.AddToListVar('CXXFLAGS', '/GR-')
    95 				self.compiler.AddToListVar('CFLAGS', '/W3')
    96 				self.compiler.AddToListVar('CFLAGS', '/nologo')
    97 				self.compiler.AddToListVar('CFLAGS', '/Zi')
    98 				self.compiler.AddToListVar('CXXFLAGS', '/TP')
    99 				self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
   100 
   101 				self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
   102 				self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
   103 				self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
   104 				self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
   105 				self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
   106 				self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
   107 				self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
   108 				self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
   109 				self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
   110 				self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
   111 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
   112 				self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
   113 
   114 			#Optimization
   115 			if AMBuild.options.opt == '1':
   116 				self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
   117 				if self.vendor == 'gcc' or self.vendor == 'clang':
   118 					self.compiler.AddToListVar('CFLAGS', '-O3')
   119 				elif self.vendor == 'msvc':
   120 					self.compiler.AddToListVar('CFLAGS', '/Ox')
   121 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
   122 					self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
   123 
   124 			#Debugging
   125 			if AMBuild.options.debug == '1':
   126 				if self.vendor == 'gcc' or self.vendor == 'clang':
   127 					self.compiler.AddToListVar('CFLAGS', '-g3')
   128 				elif self.vendor == 'msvc':
   129 					self.compiler.AddToListVar('CFLAGS', '/Od')
   130 					self.compiler.AddToListVar('CFLAGS', '/RTC1')
   131 
   132 			#Platform-specifics
   133 			if AMBuild.target['platform'] == 'linux':
   134 				self.compiler.AddToListVar('CDEFINES', '_LINUX')
   135 				if self.vendor == 'gcc':
   136 					self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
   137 				if self.vendor == 'clang':
   138 					self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
   139 			elif AMBuild.target['platform'] == 'darwin':
   140 				self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
   141 				if AMBuild.options.arch == 'x86':
   142 					self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
   143 				elif AMBuild.options.arch == 'x64':
   144 					self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'x86_64'])
   145 				self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
   146 
   147 				# For OS X dylib versioning
   148 				import re
   149 				productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
   150 				productContents = productFile.read()
   151 				productFile.close()
   152 				m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
   153 				if m == None:
   154 					self.version = '1.0.0'
   155 				else:
   156 					major, minor, release = m.groups()
   157 					self.version = '{0}.{1}.{2}'.format(major, minor, release)
   158 				AMBuild.cache.CacheVariable('version', self.version)
   159 
   160 			#Finish up
   161 			self.compiler.ToConfig(AMBuild, 'compiler')
   162 			AMBuild.cache.CacheVariable('vendor', self.vendor)
   163 			self.targetMap = { }
   164 			AMBuild.cache.CacheVariable('targetMap', self.targetMap)
   165 		else:
   166 			self.compiler.FromConfig(AMBuild, 'compiler')
   167 			self.targetMap = AMBuild.cache['targetMap']
   168 
   169 	def DefaultCompiler(self):
   170 		return self.compiler.Clone()
   171 
   172 	def JobMatters(self, jobname):
   173 		file = sys._getframe().f_code.co_filename
   174 		if AMBuild.mode == 'config':
   175 			self.targetMap[jobname] = file
   176 			return True
   177 		if len(AMBuild.args) == 0:
   178 			return True
   179 		if not jobname in AMBuild.args:
   180 			return False
   181 
   182 ke = KE()
   183 globals = {
   184 	'KE': ke
   185 }
   186 
   187 FileList = [
   188 		['src', 'AMBuild.library'],
   189 		['src', 'AMBuild.shell'],
   190 		['AMBuild.dist']
   191 	]
   192 
   193 for parts in FileList:
   194 	AMBuild.Include(os.path.join(*parts), globals)
   195