Skip to content

Commit 21ed16a

Browse files
committed
Added one call to Py_Main(), for OSX framework builds only, that will get the
actual script to run in case we are running from an applet. If we are indeed running an applet we skip the normal option processing leaving it all to the applet code. This allows us to get use the normal python binary in the Python.app bundle, giving us all the normal command line options through PythonLauncher while still allowing Python.app to be used as the template for building applets. Consequently, pythonforbundle is gone, and Mac/Python/macmain.c isn't used on OSX anymore.
1 parent 94416e5 commit 21ed16a

File tree

5 files changed

+132
-45
lines changed

5 files changed

+132
-45
lines changed

Include/pymactoolbox.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ char *PyMac_StrError(int); /* strerror with mac errors */
3434
PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */
3535
PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */
3636
extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert fsspec->path */
37-
37+
#ifdef WITH_NEXT_FRAMEWORK
38+
extern char *PyMac_GetAppletScriptFile(void); /* Return applet script file or NULL */
39+
#endif
3840
/*
3941
** These conversion routines are defined in mactoolboxglue.c itself.
4042
*/

Mac/OSX/Makefile

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ LD=cc
3737
REZ=/Developer/Tools/Rez
3838
DEREZ=/Developer/Tools/DeRez
3939

40-
OBJECTS=$(builddir)/Mac/Python/macmain.o \
41-
$(builddir)/Mac/Python/macgetargv.o
42-
4340
PYTHON=$(builddir)/python.exe
4441
APPTEMPLATE=$(srcdir)/Mac/OSXResources/app
4542
APPSUBDIRS=MacOS Resources Resources/English.lproj
@@ -53,7 +50,7 @@ install_PythonLauncher:
5350
cd $(srcdir)/Mac/OSX/PythonLauncher/PythonLauncher.pbproj ; \
5451
pbxbuild -target PythonLauncher -buildstyle Deployment DSTROOT=/ install
5552

56-
install_Python: pythonforbundle
53+
install_Python: $(PYTHON)
5754
@for i in $(PYTHONAPPSDIR) $(APPINSTALLDIR) $(APPINSTALLDIR)/Contents; do \
5855
if test ! -d $$i; then \
5956
echo "Creating directory $$i"; \
@@ -91,7 +88,7 @@ install_Python: pythonforbundle
9188
esac; \
9289
done; \
9390
done
94-
$(INSTALL_PROGRAM) $(STRIPFLAG) pythonforbundle $(APPINSTALLDIR)/Contents/MacOS/python
91+
$(INSTALL_PROGRAM) $(STRIPFLAG) $(PYTHON) $(APPINSTALLDIR)/Contents/MacOS/python
9592
# Create a temporary version of the resources here
9693
$(PYTHON) $(RFCONVERTER) -r $(RESOURCEDIR)/dialogs.rsrc dialogs.rsrc
9794
$(PYTHON) $(RFCONVERTER) -r $(RESOURCEDIR)/errors.rsrc errors.rsrc
@@ -231,14 +228,3 @@ dontinstallmacsubtree:
231228
l=`cd $(srcdir)/Mac/Lib; pwd`; \
232229
echo $$l > $(prefix)/lib/python$(VERSION)/site-packages/Mac.pth ; \
233230
echo $$l/lib-scriptpackages >> $(prefix)/lib/python$(VERSION)/site-packages/Mac.pth
234-
235-
pythonforbundle: $(OBJECTS)
236-
$(LD) $(LDFLAGS) $(OBJECTS) -o pythonforbundle
237-
238-
# Rules to build each file in OBJECTS - is there a better way?
239-
$(builddir)/Mac/Python/macmain.o: $(srcdir)/Mac/Python/macmain.c
240-
$(CC) $(CFLAGS) -c $(srcdir)/Mac/Python/macmain.c -o $@
241-
242-
$(builddir)/Mac/Python/macgetargv.o: $(srcdir)/Mac/Python/macgetargv.c
243-
$(CC) $(CFLAGS) -c $(srcdir)/Mac/Python/macgetargv.c -o $@
244-

Mac/OSX/README

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,29 @@
1-
This directory contains a Makefile that will create a proof-of-concept
2-
Mac OS X application for Python. The process is far from streamlined,
3-
and it will definitely change in future releases of Python, but I wanted to
4-
include this in the current distribution so people could play with it.
1+
This directory contains a Makefile that will create a couple of python-related
2+
applications (fullblown OSX .app applications, that is) in /Applications/Python,
3+
and a hidden helper application Python.app inside the Python.framework. In addition
4+
it has a target "installmacsubtree" that installs the relevant portions of the
5+
Mac subtree into the Python.framework.
56

6-
To create a fullblown Python.app proceed as follows.
7+
It is normally invoked indirectly through the main Makefile, as the last step
8+
in the sequence
9+
1. configure --enable-framework
10+
2. make
11+
3. make frameworkinstall
12+
4. make osxapps
713

8-
1. In the main Python source directory configure python with
9-
configure --enable-framework
10-
2. Do a "make clean" if you did a previous build, then "make".
11-
3. Install this as a framework with "make frameworkinstall". This puts a Python
12-
framework into /Library/Frameworks.
13-
4. Come back here (Mac/OSX) and build and install the application,
14-
with "make install".
15-
5. It is probably a good idea to add the Mac-specific modules to the framework,
16-
with "make installmacsubtree". This puts a MacPython lib directory into
17-
sys.prefix/Mac/Lib. Again, this is a temporary measure.
18-
6. To actually find the Lib directory installed in step 5 you add a line
19-
to your site.py file (the one in /Library/Frameworks/....):
20-
sys.path.append(os.path.join(sys.prefix, 'Mac/Lib'))
14+
The interesting targets in the makefile are:
15+
installmacsubtree - explained above,
16+
dontinstallmacsubtree - Put only a .pth file into the framework (pointing to this
17+
sourcetree), which may be easier for development,
18+
install_all - install all three .app applications,
19+
install_Python - install the hidden interpreter .app into the framework,
20+
install_PythonLauncher - install the user-visible script launch helper
21+
install_IDE - install the IDE
22+
installunixprograms - install symlinks/scripts mimicking normal unix Python into
23+
/usr/local.
2124

22-
You are now done. In your Applications you should have a "Python", with the icon
23-
being a falling 16 Ton weight with a shadow under it. You can drop Python scripts
24-
on this and the will be run, in a full-windowing environment. Note that you
25-
do not get sys.stdin, and that sys.stdout goes to the console (Use
26-
Applications/Utilities/Console to see it).
27-
28-
For some reason the application only accepts files with TEXT type, not straight unix
29-
typeless files.
3025

3126
Something to take note of is that the ".rsrc" files in the distribution are not
3227
actually resource files, they're AppleSingle encoded resource files.
3328

34-
Jack Jansen, jack@oratrix.com, 11-Sep-01.
29+
Jack Jansen, jack@oratrix.com, 02-Aug-02

Modules/main.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,22 @@ Py_Main(int argc, char **argv)
135135

136136
PySys_ResetWarnOptions();
137137

138+
#if defined(WITH_NEXT_FRAMEWORK)
139+
/* If we are running from a framework it could be that we are actually
140+
** the main program for an applet. If so, the next call will return the
141+
** filename that we are supposed to run.
142+
*/
143+
filename = PyMac_GetAppletScriptFile();
144+
if (filename != NULL) {
145+
if ((fp = fopen(filename, "r")) == NULL) {
146+
fprintf(stderr, "%s: can't open file '%s'\n",
147+
argv[0], filename);
148+
exit(2);
149+
}
150+
}
151+
/* Skip option-processing if we are an applet */
152+
if (filename == NULL)
153+
#endif
138154
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
139155
if (c == 'c') {
140156
/* -c is the last option; following arguments
@@ -261,7 +277,7 @@ Py_Main(int argc, char **argv)
261277
(p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
262278
unbuffered = 1;
263279

264-
if (command == NULL && _PyOS_optind < argc &&
280+
if (command == NULL && filename == NULL && _PyOS_optind < argc &&
265281
strcmp(argv[_PyOS_optind], "-") != 0)
266282
{
267283
filename = argv[_PyOS_optind];

Python/mactoolboxglue.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,94 @@ PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
175175
}
176176

177177
#endif /* TARGET_API_MAC_OSX */
178+
179+
#ifdef WITH_NEXT_FRAMEWORK
180+
/*
181+
** In a bundle, find a file "resourceName" of type "resourceType". Return the
182+
** full pathname in "resourceURLCstr".
183+
*/
184+
static int
185+
locateResourcePy(CFStringRef resourceType, CFStringRef resourceName, char *resourceURLCStr, int length)
186+
{
187+
CFBundleRef mainBundle = NULL;
188+
CFURLRef URL, absoluteURL;
189+
CFStringRef filenameString, filepathString;
190+
CFIndex size, i;
191+
CFArrayRef arrayRef = NULL;
192+
int success = 0;
193+
194+
#if TARGET_API_MAC_OSX
195+
CFURLPathStyle thePathStyle = kCFURLPOSIXPathStyle;
196+
#else
197+
CFURLPathStyle thePathStyle = kCFURLHFSPathStyle;
198+
#endif
199+
200+
/* Get a reference to our main bundle */
201+
mainBundle = CFBundleGetMainBundle();
202+
203+
/* If we are running inside a bundle, look through it. Otherwise, do nothing. */
204+
if (mainBundle) {
205+
206+
/* Look for py files in the main bundle by type */
207+
arrayRef = CFBundleCopyResourceURLsOfType( mainBundle,
208+
resourceType,
209+
NULL );
210+
211+
/* See if there are any filename matches */
212+
size = CFArrayGetCount(arrayRef);
213+
for (i = 0; i < size; i++) {
214+
URL = CFArrayGetValueAtIndex(arrayRef, i);
215+
filenameString = CFURLCopyLastPathComponent(URL);
216+
if (CFStringCompare(filenameString, resourceName, 0) == kCFCompareEqualTo) {
217+
/* We found a match, get the file's full path */
218+
absoluteURL = CFURLCopyAbsoluteURL(URL);
219+
filepathString = CFURLCopyFileSystemPath(absoluteURL, thePathStyle);
220+
CFRelease(absoluteURL);
221+
222+
/* Copy the full path into the caller's character buffer */
223+
success = CFStringGetCString(filepathString, resourceURLCStr, length,
224+
kCFStringEncodingMacRoman);
225+
226+
CFRelease(filepathString);
227+
}
228+
CFRelease(filenameString);
229+
}
230+
CFRelease(arrayRef);
231+
}
232+
return success;
233+
}
234+
235+
/*
236+
** iff we are running in a .app framework then we could be
237+
** the main program for an applet. In that case, return the
238+
** script filename for the applet.
239+
** Otherwise return NULL.
240+
*/
241+
char *
242+
PyMac_GetAppletScriptFile(void)
243+
{
244+
static char scriptpath[1024];
245+
246+
/* First we see whether we have __rawmain__.py and run that if it
247+
** is there. This is used for applets that want sys.argv to be
248+
** unix-like: __rawmain__ will construct it (from the initial appleevent)
249+
** and then call __main__.py.
250+
*/
251+
if (locateResourcePy(CFSTR("py"), CFSTR("__rawmain__.py"), scriptpath, 1024)) {
252+
return scriptpath;
253+
} else if (locateResourcePy(CFSTR("pyc"), CFSTR("__rawmain__.pyc"), scriptpath, 1024)) {
254+
return scriptpath;
255+
} else if (locateResourcePy(CFSTR("py"), CFSTR("__main__.py"), scriptpath, 1024)) {
256+
return scriptpath;
257+
} else if (locateResourcePy(CFSTR("pyc"), CFSTR("__main__.pyc"), scriptpath, 1024)) {
258+
return scriptpath;
259+
}
260+
return NULL;
261+
}
262+
263+
#endif
264+
265+
178266
/* Convert a 4-char string object argument to an OSType value */
179267
int
180268
PyMac_GetOSType(PyObject *v, OSType *pr)

0 commit comments

Comments
 (0)