Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode Target Phase Python Script

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 <module>  
from Foundation import NSMutableDictionary  
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/Foundation/__init__.py", line 8, in <module>  
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/objc/__init__.py", line 26, in <module>  
from _bridgesupport import *  
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC/objc/_bridgesupport.py", line 9, in <module>  
import pkg_resources  
File "/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/pkg_resources.py", line 651, in <module>  
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.

like image 381
Jorge Ortiz Avatar asked Oct 14 '22 12:10

Jorge Ortiz


2 Answers

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.

like image 122
freespace Avatar answered Nov 15 '22 06:11

freespace


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.

like image 40
Ned Deily Avatar answered Nov 15 '22 05:11

Ned Deily