Skip to content

Commit ddf424d

Browse files
author
ronald.oussoren
committed
MacOS X: Enable 4-way universal builds
This patch adds a new configure argument on OSX: --with-universal-archs=[32-bit|64-bit|all] When used with the --enable-universalsdk option this controls which CPU architectures are includes in the framework. The default is 32-bit, meaning i386 and ppc. The most useful alternative is 'all', which includes all 4 CPU architectures supported by MacOS X (i386, ppc, x86_64 and ppc64). This includes limited support for the Carbon bindings in 64-bit mode as well, limited because (a) I haven't done extensive testing and (b) a large portion of the Carbon API's aren't available in 64-bit mode anyway. I've also duplicated a feature of Apple's build of python: setting the environment variable 'ARCHFLAGS' controls the '-arch' flags used for building extensions using distutils. git-svn-id: http://svn.python.org/projects/python/trunk@63955 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent f3fa570 commit ddf424d

52 files changed

Lines changed: 1124 additions & 202 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Doc/library/macos.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,19 @@ Note the capitalization of the module name; this is a historical artifact.
5858
elaborate functionality was available), but it provides a convenient location to
5959
attach a breakpoint in a low-level debugger like :program:`gdb`.
6060

61+
.. note::
62+
63+
Not available in 64-bit mode.
64+
6165

6266
.. function:: SysBeep()
6367

6468
Ring the bell.
6569

70+
.. note::
71+
72+
Not available in 64-bit mode.
73+
6674

6775
.. function:: GetTicks()
6876

@@ -74,13 +82,20 @@ Note the capitalization of the module name; this is a historical artifact.
7482
Return the file creator and file type as two four-character strings. The *file*
7583
parameter can be a pathname or an ``FSSpec`` or ``FSRef`` object.
7684

85+
.. note::
86+
87+
It is not possible to use an ``FSSpec`` in 64-bit mode.
88+
7789

7890
.. function:: SetCreatorAndType(file, creator, type)
7991

8092
Set the file creator and file type. The *file* parameter can be a pathname or an
8193
``FSSpec`` or ``FSRef`` object. *creator* and *type* must be four character
8294
strings.
8395

96+
.. note::
97+
98+
It is not possible to use an ``FSSpec`` in 64-bit mode.
8499

85100
.. function:: openrf(name [, mode])
86101

@@ -98,3 +113,12 @@ Note the capitalization of the module name; this is a historical artifact.
98113
from an application bundle either when it has been started with
99114
:program:`pythonw` instead of :program:`python` or when running as an applet.
100115

116+
.. function:: splash([resourceid])
117+
118+
Opens a splash screen by resource id. Use resourceid ``0`` to close
119+
the splash screen.
120+
121+
.. note::
122+
123+
Not available in 64-bit mode.
124+

Include/Python.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#ifndef Py_PYTHON_H
2-
#define Py_PYTHON_H
1+
#ifndef Py_PYTHON_H #define Py_PYTHON_H
32
/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
43

54
/* Include nearly all Python header files */
65

76
#include "patchlevel.h"
87
#include "pyconfig.h"
8+
#include "pymacconfig.h"
99

1010
/* Cyclic gc is always enabled, starting with release 2.3a1. Supply the
1111
* old symbol for the benefit of extension modules written before then

Include/pymacconfig.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#ifndef PYMACCONFIG_H
2+
#define PYMACCONFIG_H
3+
/*
4+
* This file moves some of the autoconf magic to compile-time
5+
* when building on MacOSX. This is needed for building 4-way
6+
* universal binaries and for 64-bit universal binaries because
7+
* the values redefined below aren't configure-time constant but
8+
* only compile-time constant in these scenarios.
9+
*/
10+
11+
#if defined(__APPLE__)
12+
13+
# undef SIZEOF_LONG
14+
# undef SIZEOF_PTHREAD_T
15+
# undef SIZEOF_SIZE_T
16+
# undef SIZEOF_TIME_T
17+
# undef SIZEOF_VOID_P
18+
19+
# undef VA_LIST_IS_ARRAY
20+
# if defined(__LP64__) && defined(__x86_64__)
21+
# define VA_LIST_IS_ARRAY 1
22+
# endif
23+
24+
# undef HAVE_LARGEFILE_SUPPORT
25+
# ifndef __LP64__
26+
# define HAVE_LARGEFILE_SUPPORT 1
27+
# endif
28+
29+
# undef SIZEOF_LONG
30+
# ifdef __LP64__
31+
# define SIZEOF_LONG 8
32+
# define SIZEOF_PTHREAD_T 8
33+
# define SIZEOF_SIZE_T 8
34+
# define SIZEOF_TIME_T 8
35+
# define SIZEOF_VOID_P 8
36+
# else
37+
# define SIZEOF_LONG 4
38+
# define SIZEOF_PTHREAD_T 4
39+
# define SIZEOF_SIZE_T 4
40+
# define SIZEOF_TIME_T 4
41+
# define SIZEOF_VOID_P 4
42+
# endif
43+
44+
# if defined(__LP64__)
45+
/* MacOSX 10.4 (the first release to suppport 64-bit code
46+
* at all) only supports 64-bit in the UNIX layer.
47+
* Therefore surpress the toolbox-glue in 64-bit mode.
48+
*/
49+
50+
/* In 64-bit mode setpgrp always has no argments, in 32-bit
51+
* mode that depends on the compilation environment
52+
*/
53+
# undef SETPGRP_HAVE_ARG
54+
55+
# endif
56+
57+
#endif /* defined(_APPLE__) */
58+
59+
#endif /* PYMACCONFIG_H */

Include/pymactoolbox.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
#endif
99

1010
#include <Carbon/Carbon.h>
11+
12+
#ifndef __LP64__
1113
#include <QuickTime/QuickTime.h>
14+
#endif /* !__LP64__ */
1215

1316
/*
1417
** Helper routines for error codes and such.
@@ -18,8 +21,11 @@ extern PyObject *PyMac_OSErrException; /* Exception for OSErr */
1821
PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */
1922
PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */
2023
PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */
24+
#ifndef __LP64__
2125
extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert
2226
fsspec->path */
27+
#endif /* __LP64__ */
28+
2329
/*
2430
** These conversion routines are defined in mactoolboxglue.c itself.
2531
*/
@@ -83,8 +89,10 @@ PyObject *PyMac_Buildwide(wide *); /* Convert wide to PyObject */
8389
#endif /* USE_TOOLBOX_OBJECT_GLUE */
8490

8591
/* macfs exports */
92+
#ifndef __LP64__
8693
int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */
8794
PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */
95+
#endif /* !__LP64__ */
8896

8997
int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */
9098
PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */
@@ -101,39 +109,54 @@ extern PyObject *CmpInstObj_New(ComponentInstance);
101109
extern int CmpInstObj_Convert(PyObject *, ComponentInstance *);
102110

103111
/* Ctl exports */
112+
#ifndef __LP64__
104113
extern PyObject *CtlObj_New(ControlHandle);
105114
extern int CtlObj_Convert(PyObject *, ControlHandle *);
115+
#endif /* !__LP64__ */
106116

107117
/* Dlg exports */
118+
#ifndef __LP64__
108119
extern PyObject *DlgObj_New(DialogPtr);
109120
extern int DlgObj_Convert(PyObject *, DialogPtr *);
110121
extern PyObject *DlgObj_WhichDialog(DialogPtr);
122+
#endif /* !__LP64__ */
111123

112124
/* Drag exports */
125+
#ifndef __LP64__
113126
extern PyObject *DragObj_New(DragReference);
114127
extern int DragObj_Convert(PyObject *, DragReference *);
128+
#endif /* !__LP64__ */
115129

116130
/* List exports */
131+
#ifndef __LP64__
117132
extern PyObject *ListObj_New(ListHandle);
118133
extern int ListObj_Convert(PyObject *, ListHandle *);
134+
#endif /* !__LP64__ */
119135

120136
/* Menu exports */
137+
#ifndef __LP64__
121138
extern PyObject *MenuObj_New(MenuHandle);
122139
extern int MenuObj_Convert(PyObject *, MenuHandle *);
140+
#endif /* !__LP64__ */
123141

124142
/* Qd exports */
143+
#ifndef __LP64__
125144
extern PyObject *GrafObj_New(GrafPtr);
126145
extern int GrafObj_Convert(PyObject *, GrafPtr *);
127146
extern PyObject *BMObj_New(BitMapPtr);
128147
extern int BMObj_Convert(PyObject *, BitMapPtr *);
129148
extern PyObject *QdRGB_New(RGBColor *);
130149
extern int QdRGB_Convert(PyObject *, RGBColor *);
150+
#endif /* !__LP64__ */
131151

132152
/* Qdoffs exports */
153+
#ifndef __LP64__
133154
extern PyObject *GWorldObj_New(GWorldPtr);
134155
extern int GWorldObj_Convert(PyObject *, GWorldPtr *);
156+
#endif /* !__LP64__ */
135157

136158
/* Qt exports */
159+
#ifndef __LP64__
137160
extern PyObject *TrackObj_New(Track);
138161
extern int TrackObj_Convert(PyObject *, Track *);
139162
extern PyObject *MovieObj_New(Movie);
@@ -146,6 +169,7 @@ extern PyObject *UserDataObj_New(UserData);
146169
extern int UserDataObj_Convert(PyObject *, UserData *);
147170
extern PyObject *MediaObj_New(Media);
148171
extern int MediaObj_Convert(PyObject *, Media *);
172+
#endif /* !__LP64__ */
149173

150174
/* Res exports */
151175
extern PyObject *ResObj_New(Handle);
@@ -154,13 +178,17 @@ extern PyObject *OptResObj_New(Handle);
154178
extern int OptResObj_Convert(PyObject *, Handle *);
155179

156180
/* TE exports */
181+
#ifndef __LP64__
157182
extern PyObject *TEObj_New(TEHandle);
158183
extern int TEObj_Convert(PyObject *, TEHandle *);
184+
#endif /* !__LP64__ */
159185

160186
/* Win exports */
187+
#ifndef __LP64__
161188
extern PyObject *WinObj_New(WindowPtr);
162189
extern int WinObj_Convert(PyObject *, WindowPtr *);
163190
extern PyObject *WinObj_WhichWindow(WindowPtr);
191+
#endif /* !__LP64__ */
164192

165193
/* CF exports */
166194
extern PyObject *CFObj_New(CFTypeRef);

Lib/distutils/sysconfig.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,26 @@ def get_config_vars(*args):
539539
flags = re.sub('-isysroot [^ \t]*', ' ', flags)
540540
_config_vars[key] = flags
541541

542+
else:
543+
544+
# Allow the user to override the architecture flags using
545+
# an environment variable.
546+
# NOTE: This name was introduced by Apple in OSX 10.5 and
547+
# is used by several scripting languages distributed with
548+
# that OS release.
549+
550+
if 'ARCHFLAGS' in os.environ:
551+
arch = os.environ['ARCHFLAGS']
552+
for key in ('LDFLAGS', 'BASECFLAGS',
553+
# a number of derived variables. These need to be
554+
# patched up as well.
555+
'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
556+
557+
flags = _config_vars[key]
558+
flags = re.sub('-arch\s+\w+\s', ' ', flags)
559+
flags = flags + ' ' + arch
560+
_config_vars[key] = flags
561+
542562
if args:
543563
vals = []
544564
for name in args:

Lib/distutils/unixccompiler.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def _darwin_compiler_fixup(compiler_so, cc_args):
6464
stripArch = '-arch' in cc_args
6565
stripSysroot = '-isysroot' in cc_args
6666

67-
if stripArch:
67+
if stripArch or 'ARCHFLAGS' in os.environ:
6868
while 1:
6969
try:
7070
index = compiler_so.index('-arch')
@@ -73,6 +73,12 @@ def _darwin_compiler_fixup(compiler_so, cc_args):
7373
except ValueError:
7474
break
7575

76+
if 'ARCHFLAGS' in os.environ and not stripArch:
77+
# User specified different -arch flags in the environ,
78+
# see also distutils.sysconfig
79+
compiler_so = compiler_so + ' ' + os.environ['ARCHFLAGS']
80+
81+
7682
if stripSysroot:
7783
try:
7884
index = compiler_so.index('-isysroot')

Lib/distutils/util.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,19 @@ def get_platform ():
125125
osname = "macosx"
126126

127127

128-
if (release + '.') < '10.4.' and \
129-
get_config_vars().get('UNIVERSALSDK', '').strip():
128+
if (release + '.') >= '10.4.' and \
129+
'-arch' in get_config_vars().get('CFLAGS', '').strip():
130130
# The universal build will build fat binaries, but not on
131131
# systems before 10.4
132+
#
133+
# Try to detect 4-way universal builds, those have machine-type
134+
# 'universal' instead of 'fat'.
135+
132136
machine = 'fat'
133137

138+
if '-arch x86_64' in get_config_vars().get('CFLAGS'):
139+
machine = 'universal'
140+
134141
elif machine in ('PowerPC', 'Power_Macintosh'):
135142
# Pick a sane name for the PPC architecture.
136143
machine = 'ppc'

Lib/test/test_macos.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import unittest
2+
import MacOS
3+
import Carbon.File
4+
from test import test_support
5+
import os
6+
7+
TESTFN2 = test_support.TESTFN + '2'
8+
9+
class TestMacOS(unittest.TestCase):
10+
11+
def testOpenRF(self):
12+
try:
13+
fp = open(test_support.TESTFN, 'w')
14+
fp.write('hello world\n')
15+
fp.close()
16+
17+
rfp = MacOS.openrf(test_support.TESTFN, '*wb')
18+
rfp.write('goodbye world\n')
19+
rfp.close()
20+
21+
22+
fp = open(test_support.TESTFN, 'r')
23+
data = fp.read()
24+
fp.close()
25+
self.assertEquals(data, 'hello world\n')
26+
27+
rfp = MacOS.openrf(test_support.TESTFN, '*rb')
28+
data = rfp.read(100)
29+
data2 = rfp.read(100)
30+
rfp.close()
31+
self.assertEquals(data, 'goodbye world\n')
32+
self.assertEquals(data2, '')
33+
34+
35+
finally:
36+
os.unlink(test_support.TESTFN)
37+
38+
def test_main():
39+
test_support.run_unittest(TestMacOS)
40+
41+
42+
if __name__ == '__main__':
43+
test_main()

Mac/IDLE/Makefile.in

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ IDLE.app: \
4242
$(srcdir)/../Icons/PythonSource.icns \
4343
$(srcdir)/../Icons/PythonCompiled.icns Info.plist
4444
rm -fr IDLE.app
45-
$(RUNSHARED) $(BUILDPYTHON) $(BUNDLEBULDER) \
45+
$(RUNSHARED) arch -ppc -i386 $(BUILDPYTHON) $(BUNDLEBULDER) \
4646
--builddir=. \
4747
--name=IDLE \
4848
--link-exec \
@@ -51,7 +51,7 @@ IDLE.app: \
5151
--iconfile=$(srcdir)/../Icons/IDLE.icns \
5252
--resource=$(srcdir)/../Icons/PythonSource.icns \
5353
--resource=$(srcdir)/../Icons/PythonCompiled.icns \
54-
--python=$(prefix)/Resources/Python.app/Contents/MacOS/Python \
54+
--python=$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)`test -f "$(DESTDIR)$(prefix)/Resources/Python.app/Contents/MacOS/$(PYTHONFRAMEWORK)-32" && echo "-32"` \
5555
build
5656

5757

Mac/IDLE/idlemain.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
# Make sure sys.executable points to the python interpreter inside the
1414
# framework, instead of at the helper executable inside the application
1515
# bundle (the latter works, but doesn't allow access to the window server)
16-
sys.executable = os.path.join(sys.prefix, 'bin', 'python')
16+
if sys.executable.endswith('-32'):
17+
sys.executable = os.path.join(sys.prefix, 'bin', 'python-32')
18+
else:
19+
sys.executable = os.path.join(sys.prefix, 'bin', 'python')
1720

1821
# Look for the -psn argument that the launcher adds and remove it, it will
1922
# only confuse the IDLE startup code.

0 commit comments

Comments
 (0)