Fix linux/mac support.
1 # vim: set ts=2 sw=2 tw=99 noet ft=python:
3 # Copyright (C) 2004-2012 David Anderson
5 # This file is part of SourcePawn.
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)
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.
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/.
22 from ambuild.command import SymlinkCommand
26 self.compiler = Cpp.Compiler()
28 if AMBuild.mode == 'config':
30 self.compiler.DetectAll(AMBuild)
33 cxx = self.compiler.cxx
34 if isinstance(cxx, Cpp.CompatGCC):
35 if isinstance(cxx, Cpp.GCC):
37 elif isinstance(cxx, Cpp.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')
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))
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')
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')
67 # The compiler is too aggressive about what what should be a valid offsetof.
68 self.compiler.AddToListVar('CXXFLAGS', '-Wno-invalid-offsetof')
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')
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')
82 self.compiler.AddToListVar('POSTLINKFLAGS', '-lm')
83 elif isinstance(cxx, Cpp.MSVC):
85 if AMBuild.options.debug == '1':
86 self.compiler.AddToListVar('CFLAGS', '/MTd')
87 self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
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')
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')
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')
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')
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++')
147 # For OS X dylib versioning
149 productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
150 productContents = productFile.read()
152 m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
154 self.version = '1.0.0'
156 major, minor, release = m.groups()
157 self.version = '{0}.{1}.{2}'.format(major, minor, release)
158 AMBuild.cache.CacheVariable('version', self.version)
161 self.compiler.ToConfig(AMBuild, 'compiler')
162 AMBuild.cache.CacheVariable('vendor', self.vendor)
164 AMBuild.cache.CacheVariable('targetMap', self.targetMap)
166 self.compiler.FromConfig(AMBuild, 'compiler')
167 self.targetMap = AMBuild.cache['targetMap']
169 def DefaultCompiler(self):
170 return self.compiler.Clone()
172 def JobMatters(self, jobname):
173 file = sys._getframe().f_code.co_filename
174 if AMBuild.mode == 'config':
175 self.targetMap[jobname] = file
177 if len(AMBuild.args) == 0:
179 if not jobname in AMBuild.args:
188 ['src', 'AMBuild.library'],
189 ['src', 'AMBuild.shell'],
193 for parts in FileList:
194 AMBuild.Include(os.path.join(*parts), globals)