views:

641

answers:

3

Hi everybody:

I am trying to add a Python script to into my project to obtain the build and marketing numbers directly from Git.

I have created a new target phase and that runs a script as explained in:
http://yeahrightkeller.com/2008/10/19/xcode-run-script-build-phase-tip/

And I have written a Python script that parses the program Info.plist using

from Foundation import NSMutableDictionary

However the script fails while being compiled and reports the following error to the build results: Running a custom build phase script: gitversion.py
Traceback (most recent call last):
File "/Users/jorge/Documents/Programming iPod/Pruebas/RowOrder/Scripts/gitversion.py", line 9, in
from Foundation import NSMutableDictionary
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/Foundation/init.py", line 8, in
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/objc/init.py", line 26, in
from _bridgesupport import *
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/objc/_bridgesupport.py", line 9, in
import pkg_resources
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 651, in
class Environment(object):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 654, in Environment
def init(self, search_path=None, platform=get_supported_platform(), python=PY_MAJOR):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 55, in get_supported_platform
plat = get_build_platform(); m = macosVersionString.match(plat)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 181, in get_build_platform
plat = get_platform()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/util.py", line 97, in get_platform
cfgvars = get_config_vars()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/sysconfig.py", line 525, in get_config_vars
func()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/distutils/sysconfig.py", line 408, in _init_posix
raise DistutilsPlatformError(my_msg)
distutils.errors.DistutilsPlatformError: $MACOSX_DEPLOYMENT_TARGET mismatch: now "10.5" but "10.6" during configure
Finished running custom build phase script: gitversion.py (exit status = 1)

Clearly, distutils has somehow hardcoded that it is compiled for version 10.6 (Snow Leopard, that is the one I am using), but the project has the MacOSX Deployment target set to 10.5.

If i try to set this variable in the project to 10.6, I then get: ld: library not found for -lcrt1.10.6.o

Any ideas on how to solve this issue? Thanks in advance.

A: 

Apple distributes Python 2.5 and 2.6 with Snow Leopard (10.6) and both are built with a deployment target of 10.6. If you really do need to target your application for 10.5, you can't safely use the Apple-supplied Pythons on 10.6 to deploy on 10.5.

The easiest solution may be to download and install a Python 2.6 from python.org. That Python is targeted for 10.3+, so it will work on both 10.5 and 10.6. You'll probably also need to ensure that that Python is installed on all machines where your app will be deployed.

Another option might be to create a separate stand-alone helper app using py2app with the python.org 2.6 and deploy that along with your main app. Or create your whole app under py2app. In either case, the app would contain its own python framework interpreter and framework, independent of the system version.

EDIT: Based on your comment, I'm not sure I understand your problem. Since you are running on 10.6, it's not clear to me (1) why you have the deployment target set to 10.5 and (2) if you need to have the deployment set to 10.5. I'm going to guess that you had an existing Xcode project that was developed on 10.5 and then imported or upgraded from Xcode on 10.5 to Xcode on 10.6. If that is the case, then I think the only thing that should have been needed to be done is to change the Active SDK from 10.5 to 10.6 (in the overview) in the top of the project window. Doing just that and forcing a Clean All Targets should solve the crt library not found error; if not, there is something wrong with the project dependencies.

On the other hand, if you really do need to develop on 10.6 for 10.5, then it seems that your gitversion.py is introducing an inadvertent dependency on python 2.6 (as can be seen by the traceback), which is not part of 10.5. Unless you really need python 2.6 features, you should be able to eliminate that by using python 2.5 which Apple provides on both 10.5 and 10.6. In that case, perhaps all you need to do is to ensure that you invoke python in the build phase script with /usr/bin/python2.5 rather than just python.

Ned Deily
Thanks a lot for your answer Ned.Deploying for 10.5 is a must given the error that I get with 10.6. But 10.5 isn't working because the distutils expect 10.6 (as indicated by the environment variable.) Is there a way to tell distutils to work for 10.5 or to use the 10.5 version?The goal for me is only to add a python script as a target phase because reading and writing the plist is easier, not to deploy a python app.
Jorge Ortiz
See additional comments above. Hope that helps!
Ned Deily
Thanks again Ned.This is not a MacOSX project, but an iPhone one and it seems to require 10.5 as target because otherwise I get: ld: library not found for -lcrt1.10.6.o even after cleaning the target.I have decided to go the hard way and replace the python script with a perl script that does exactly the same.I am not getting the same error with perl. God bless Perl! Thanks TMTOWTDI!I still believe that there is a problem with python when used as a script of an iPhone project, but I have a workaround for it.
Jorge Ortiz
+1  A: 

For the purposes of this script, you can simply temporarily set the value of MACOSX_DEPLOYMENT_TARGET to 10.6. So your command would be:

env MACOSX_DEPLOYMENT_TARGET=10.6 gitversion.py
Maxence
+1  A: 

I have the same problem, and I wanted to keep the python version because handling the plist via NSMutableDictionary is much nicer than using regex on Info.plist.

Building on Maxence's answer, the solution was to strip the python code out of the Run Script build phase into a gitversion.py file:

#!/usr/bin/env python
import os
from Foundation import NSMutableDictionary
from subprocess import Popen, PIPE

p = Popen(
        "/sw/bin/git rev-parse --short HEAD", 
        stdout=PIPE, 
        close_fds=True,
        shell=True)

version = p.stdout.read()
print version
info = os.environ['INFOPLIST_FILE']
print info
plist = NSMutableDictionary.dictionaryWithContentsOfFile_(info)
print plist
plist['revision'] = version[:-1]
plist.writeToFile_atomically_(info, 1)

Then replace the original Run Script with a shell script:

env MACOSX_DEPLOYMENT_TARGET=10.6 python gitversion.py

Be sure to remember to change the Shell setting to /bin/sh.

freespace