1 """
2 Test suite for _osx_support: shared OS X support functions.
3 """
4
5 import os
6 import platform
7 import stat
8 import sys
9 import unittest
10
11 from test.support import os_helper
12
13 import _osx_support
14
15 @unittest.skipUnless(sys.platform.startswith("darwin"), "requires OS X")
16 class ESC[4;38;5;81mTest_OSXSupport(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
17
18 def setUp(self):
19 self.maxDiff = None
20 self.prog_name = 'bogus_program_xxxx'
21 self.temp_path_dir = os.path.abspath(os.getcwd())
22 self.env = self.enterContext(os_helper.EnvironmentVarGuard())
23 for cv in ('CFLAGS', 'LDFLAGS', 'CPPFLAGS',
24 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'CC',
25 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
26 'PY_CORE_CFLAGS', 'PY_CORE_LDFLAGS'):
27 if cv in self.env:
28 self.env.unset(cv)
29
30 def add_expected_saved_initial_values(self, config_vars, expected_vars):
31 # Ensure that the initial values for all modified config vars
32 # are also saved with modified keys.
33 expected_vars.update(('_OSX_SUPPORT_INITIAL_'+ k,
34 config_vars[k]) for k in config_vars
35 if config_vars[k] != expected_vars[k])
36
37 def test__find_executable(self):
38 if self.env['PATH']:
39 self.env['PATH'] = self.env['PATH'] + ':'
40 self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
41 os_helper.unlink(self.prog_name)
42 self.assertIsNone(_osx_support._find_executable(self.prog_name))
43 self.addCleanup(os_helper.unlink, self.prog_name)
44 with open(self.prog_name, 'w') as f:
45 f.write("#!/bin/sh\n/bin/echo OK\n")
46 os.chmod(self.prog_name, stat.S_IRWXU)
47 self.assertEqual(self.prog_name,
48 _osx_support._find_executable(self.prog_name))
49
50 def test__read_output(self):
51 if self.env['PATH']:
52 self.env['PATH'] = self.env['PATH'] + ':'
53 self.env['PATH'] = self.env['PATH'] + os.path.abspath(self.temp_path_dir)
54 os_helper.unlink(self.prog_name)
55 self.addCleanup(os_helper.unlink, self.prog_name)
56 with open(self.prog_name, 'w') as f:
57 f.write("#!/bin/sh\n/bin/echo ExpectedOutput\n")
58 os.chmod(self.prog_name, stat.S_IRWXU)
59 self.assertEqual('ExpectedOutput',
60 _osx_support._read_output(self.prog_name))
61
62 def test__find_build_tool(self):
63 out = _osx_support._find_build_tool('cc')
64 self.assertTrue(os.path.isfile(out),
65 'cc not found - check xcode-select')
66
67 def test__get_system_version(self):
68 self.assertTrue(platform.mac_ver()[0].startswith(
69 _osx_support._get_system_version()))
70
71 def test__remove_original_values(self):
72 config_vars = {
73 'CC': 'gcc-test -pthreads',
74 }
75 expected_vars = {
76 'CC': 'clang -pthreads',
77 }
78 cv = 'CC'
79 newvalue = 'clang -pthreads'
80 _osx_support._save_modified_value(config_vars, cv, newvalue)
81 self.assertNotEqual(expected_vars, config_vars)
82 _osx_support._remove_original_values(config_vars)
83 self.assertEqual(expected_vars, config_vars)
84
85 def test__save_modified_value(self):
86 config_vars = {
87 'CC': 'gcc-test -pthreads',
88 }
89 expected_vars = {
90 'CC': 'clang -pthreads',
91 }
92 self.add_expected_saved_initial_values(config_vars, expected_vars)
93 cv = 'CC'
94 newvalue = 'clang -pthreads'
95 _osx_support._save_modified_value(config_vars, cv, newvalue)
96 self.assertEqual(expected_vars, config_vars)
97
98 def test__save_modified_value_unchanged(self):
99 config_vars = {
100 'CC': 'gcc-test -pthreads',
101 }
102 expected_vars = config_vars.copy()
103 cv = 'CC'
104 newvalue = 'gcc-test -pthreads'
105 _osx_support._save_modified_value(config_vars, cv, newvalue)
106 self.assertEqual(expected_vars, config_vars)
107
108 def test__supports_universal_builds(self):
109 import platform
110 mac_ver_tuple = tuple(int(i) for i in
111 platform.mac_ver()[0].split('.')[0:2])
112 self.assertEqual(mac_ver_tuple >= (10, 4),
113 _osx_support._supports_universal_builds())
114
115 def test__find_appropriate_compiler(self):
116 compilers = (
117 ('gcc-test', 'i686-apple-darwin11-llvm-gcc-4.2'),
118 ('clang', 'clang version 3.1'),
119 )
120 config_vars = {
121 'CC': 'gcc-test -pthreads',
122 'CXX': 'cc++-test',
123 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
124 'LDFLAGS': '-arch ppc -arch i386 -g',
125 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
126 'BLDSHARED': 'gcc-test -bundle -arch ppc -arch i386 -g',
127 'LDSHARED': 'gcc-test -bundle -arch ppc -arch i386 '
128 '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
129 }
130 expected_vars = {
131 'CC': 'clang -pthreads',
132 'CXX': 'clang++',
133 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
134 'LDFLAGS': '-arch ppc -arch i386 -g',
135 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
136 'BLDSHARED': 'clang -bundle -arch ppc -arch i386 -g',
137 'LDSHARED': 'clang -bundle -arch ppc -arch i386 '
138 '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
139 }
140 self.add_expected_saved_initial_values(config_vars, expected_vars)
141
142 suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
143 self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
144 for c_name, c_output in compilers:
145 os_helper.unlink(c_name)
146 self.addCleanup(os_helper.unlink, c_name)
147 with open(c_name, 'w') as f:
148 f.write("#!/bin/sh\n/bin/echo " + c_output)
149 os.chmod(c_name, stat.S_IRWXU)
150 self.assertEqual(expected_vars,
151 _osx_support._find_appropriate_compiler(
152 config_vars))
153
154 def test__remove_universal_flags(self):
155 config_vars = {
156 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
157 'LDFLAGS': '-arch ppc -arch i386 -g',
158 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
159 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
160 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
161 '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
162 }
163 expected_vars = {
164 'CFLAGS': '-fno-strict-aliasing -g -O3 ',
165 'LDFLAGS': ' -g',
166 'CPPFLAGS': '-I. ',
167 'BLDSHARED': 'gcc-4.0 -bundle -g',
168 'LDSHARED': 'gcc-4.0 -bundle -g',
169 }
170 self.add_expected_saved_initial_values(config_vars, expected_vars)
171
172 self.assertEqual(expected_vars,
173 _osx_support._remove_universal_flags(
174 config_vars))
175
176 def test__remove_universal_flags_alternate(self):
177 # bpo-38360: also test the alternate single-argument form of -isysroot
178 config_vars = {
179 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
180 'LDFLAGS': '-arch ppc -arch i386 -g',
181 'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.4u.sdk',
182 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
183 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
184 '-isysroot/Developer/SDKs/MacOSX10.4u.sdk -g',
185 }
186 expected_vars = {
187 'CFLAGS': '-fno-strict-aliasing -g -O3 ',
188 'LDFLAGS': ' -g',
189 'CPPFLAGS': '-I. ',
190 'BLDSHARED': 'gcc-4.0 -bundle -g',
191 'LDSHARED': 'gcc-4.0 -bundle -g',
192 }
193 self.add_expected_saved_initial_values(config_vars, expected_vars)
194
195 self.assertEqual(expected_vars,
196 _osx_support._remove_universal_flags(
197 config_vars))
198
199 def test__remove_unsupported_archs(self):
200 config_vars = {
201 'CC': 'clang',
202 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
203 'LDFLAGS': '-arch ppc -arch i386 -g',
204 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
205 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
206 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
207 '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
208 }
209 expected_vars = {
210 'CC': 'clang',
211 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch i386 ',
212 'LDFLAGS': ' -arch i386 -g',
213 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
214 'BLDSHARED': 'gcc-4.0 -bundle -arch i386 -g',
215 'LDSHARED': 'gcc-4.0 -bundle -arch i386 '
216 '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
217 }
218 self.add_expected_saved_initial_values(config_vars, expected_vars)
219
220 suffix = (':' + self.env['PATH']) if self.env['PATH'] else ''
221 self.env['PATH'] = os.path.abspath(self.temp_path_dir) + suffix
222 c_name = 'clang'
223 os_helper.unlink(c_name)
224 self.addCleanup(os_helper.unlink, c_name)
225 # exit status 255 means no PPC support in this compiler chain
226 with open(c_name, 'w') as f:
227 f.write("#!/bin/sh\nexit 255")
228 os.chmod(c_name, stat.S_IRWXU)
229 self.assertEqual(expected_vars,
230 _osx_support._remove_unsupported_archs(
231 config_vars))
232
233 def test__override_all_archs(self):
234 self.env['ARCHFLAGS'] = '-arch x86_64'
235 config_vars = {
236 'CC': 'clang',
237 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 ',
238 'LDFLAGS': '-arch ppc -arch i386 -g',
239 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
240 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
241 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
242 '-isysroot /Developer/SDKs/MacOSX10.4u.sdk -g',
243 }
244 expected_vars = {
245 'CC': 'clang',
246 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch x86_64',
247 'LDFLAGS': ' -g -arch x86_64',
248 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.4u.sdk',
249 'BLDSHARED': 'gcc-4.0 -bundle -g -arch x86_64',
250 'LDSHARED': 'gcc-4.0 -bundle -isysroot '
251 '/Developer/SDKs/MacOSX10.4u.sdk -g -arch x86_64',
252 }
253 self.add_expected_saved_initial_values(config_vars, expected_vars)
254
255 self.assertEqual(expected_vars,
256 _osx_support._override_all_archs(
257 config_vars))
258
259 def test__check_for_unavailable_sdk(self):
260 config_vars = {
261 'CC': 'clang',
262 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
263 '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
264 'LDFLAGS': '-arch ppc -arch i386 -g',
265 'CPPFLAGS': '-I. -isysroot /Developer/SDKs/MacOSX10.1.sdk',
266 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
267 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
268 '-isysroot /Developer/SDKs/MacOSX10.1.sdk -g',
269 }
270 expected_vars = {
271 'CC': 'clang',
272 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
273 ' ',
274 'LDFLAGS': '-arch ppc -arch i386 -g',
275 'CPPFLAGS': '-I. ',
276 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
277 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
278 ' -g',
279 }
280 self.add_expected_saved_initial_values(config_vars, expected_vars)
281
282 self.assertEqual(expected_vars,
283 _osx_support._check_for_unavailable_sdk(
284 config_vars))
285
286 def test__check_for_unavailable_sdk_alternate(self):
287 # bpo-38360: also test the alternate single-argument form of -isysroot
288 config_vars = {
289 'CC': 'clang',
290 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
291 '-isysroot/Developer/SDKs/MacOSX10.1.sdk',
292 'LDFLAGS': '-arch ppc -arch i386 -g',
293 'CPPFLAGS': '-I. -isysroot/Developer/SDKs/MacOSX10.1.sdk',
294 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
295 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
296 '-isysroot/Developer/SDKs/MacOSX10.1.sdk -g',
297 }
298 expected_vars = {
299 'CC': 'clang',
300 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
301 ' ',
302 'LDFLAGS': '-arch ppc -arch i386 -g',
303 'CPPFLAGS': '-I. ',
304 'BLDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 -g',
305 'LDSHARED': 'gcc-4.0 -bundle -arch ppc -arch i386 '
306 ' -g',
307 }
308 self.add_expected_saved_initial_values(config_vars, expected_vars)
309
310 self.assertEqual(expected_vars,
311 _osx_support._check_for_unavailable_sdk(
312 config_vars))
313
314 def test_get_platform_osx(self):
315 # Note, get_platform_osx is currently tested more extensively
316 # indirectly by test_sysconfig and test_distutils
317 config_vars = {
318 'CFLAGS': '-fno-strict-aliasing -g -O3 -arch ppc -arch i386 '
319 '-isysroot /Developer/SDKs/MacOSX10.1.sdk',
320 'MACOSX_DEPLOYMENT_TARGET': '10.6',
321 }
322 result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ')
323 self.assertEqual(('macosx', '10.6', 'fat'), result)
324
325 if __name__ == "__main__":
326 unittest.main()