所以我的问题是:在Objective C Mac OS X应用程序中构建python用作插件运行时的当前最佳实践是什么?如何确保它与应用程序捆绑在一起,并且可以在构建最终的Objective C应用程序之前安装任何可能需要的其他库?
解决方法@H_301_6@
我想出了一种似乎运作良好的方法.
首先,从official website下载要使用的python版本的源代码.在某处提取存档.我正在使用Python 3.4.2.根据您使用的特定版本调整系统上的命令.
创建一个将用于此开发python版本的构建目录.整个目录中应该没有空格,以确保bash正确解释了she-bang(#!)行.我使用了/Users/myaccount/development/python/devbuild/python3.4.2.
进入解压缩的Python目录并运行以下命令:
./configure --prefix="/Users/myaccount/development/python/devbuild/python3.4.2"
make
make install
这将在该开发构建目录中安装python.设置Python路径以使用正确的目录:
export PYTHONPATH="/Users/myaccount/development/python/devbuild/python3.4.2/lib/python3.4/site-packages/"
进入python bin目录(/Users/myaccount/development/python/devbuild/python3.4.2/bin)并使用pip3安装你需要的任何模块. $PYTHONPATH设置将确保将模块安装到正确的site-packages目录中.
找到一个方便的PyObjC存储库的家,并在那里克隆它.然后签出最新的版本标签并安装它,确保你的$PYTHONPATH仍然正确:
hg clone https://bitbucket.org/ronaldoussoren/pyobjc
cd pyobjc
hg tags
hg checkout [the id of the latest version from the tag list]
/Users/myaccount/development/python/devbuild/python3.4.2/bin/python3 ./install.py
每当你需要更新python模块时,只需确保使用正确的python bin和$PYTHONPATH.
现在将python添加到Xcode项目中.
将/Users/myaccount/development/python/devbuild/python3.4.2目录拖到Xcode项目中,将其设置为不根据需要复制项目,以及创建文件夹引用.
将/Users/myaccount/development/python/devbuild/python3.4.2/include/python3.4m添加到Xcode项目的Build Settings中的Header Search Paths设置.不确定是否有办法将此作为一个通用步骤来搜索我们刚刚添加的文件夹引用目录.
将`/Users/myaccount/development/python/devbuild/python3.4.2/lib/libpython3.4m.a库拖到Xcode项目中,将其设置为引用而不复制.
现在可以使用Big Nerd Ranch scripting tutorial repository的代码进行一些修改.
插件管理器代码需要一个NSString扩展来处理Python API似乎非常喜欢的wchar_t字符串:
@interface NSString (WcharEncodedString)
- (wchar_t*) getWideString;
@end
@implementation NSString (WcharEncodedString)
- (wchar_t*) getWideString {
const char* tmp = [self cStringUsingEncoding:NSUTF8StringEncoding];
unsigned long buflen = strlen(tmp) + 1;
wchar_t* buffer = malloc(buflen * sizeof(wchar_t));
mbstowcs(buffer,tmp,buflen);
return buffer;
}
@end
Python标题应包含如下:
#include "Python.h"
在调用Py_Initialize()之前,需要运行以下代码,以便按照Zorg在其他问题上的建议设置正确的python可执行文件,PYTHONPATH和PYTHONHOME.
NSString* executablePath = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/bin"];
Py_SetProgramName([executablePath getWideString]);
NSString* pythonDirectory = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/lib"];
Py_SetPath([pythonDirectory getWideString]);
Py_SetPythonHome([pythonDirectory getWideString]);
最后,需要在PluginExecutor.py文件中扩展python路径以包含高级lib路径的各个子目录.将以下代码添加到Plugin Executor文件的顶部:
import sys
from os import walk
path = sys.path.copy()
for p in path:
for root,dirs,files in walk(p):
if p is not root:
sys.path.append(root)
如果事情开始崩溃,我会发布更新,但现在这似乎是一个有效的解决方案.
首先,从official website下载要使用的python版本的源代码.在某处提取存档.我正在使用Python 3.4.2.根据您使用的特定版本调整系统上的命令.
创建一个将用于此开发python版本的构建目录.整个目录中应该没有空格,以确保bash正确解释了she-bang(#!)行.我使用了/Users/myaccount/development/python/devbuild/python3.4.2.
进入解压缩的Python目录并运行以下命令:
./configure --prefix="/Users/myaccount/development/python/devbuild/python3.4.2" make make install
这将在该开发构建目录中安装python.设置Python路径以使用正确的目录:
export PYTHONPATH="/Users/myaccount/development/python/devbuild/python3.4.2/lib/python3.4/site-packages/"
进入python bin目录(/Users/myaccount/development/python/devbuild/python3.4.2/bin)并使用pip3安装你需要的任何模块. $PYTHONPATH设置将确保将模块安装到正确的site-packages目录中.
找到一个方便的PyObjC存储库的家,并在那里克隆它.然后签出最新的版本标签并安装它,确保你的$PYTHONPATH仍然正确:
hg clone https://bitbucket.org/ronaldoussoren/pyobjc cd pyobjc hg tags hg checkout [the id of the latest version from the tag list] /Users/myaccount/development/python/devbuild/python3.4.2/bin/python3 ./install.py
每当你需要更新python模块时,只需确保使用正确的python bin和$PYTHONPATH.
现在将python添加到Xcode项目中.
将/Users/myaccount/development/python/devbuild/python3.4.2目录拖到Xcode项目中,将其设置为不根据需要复制项目,以及创建文件夹引用.
将/Users/myaccount/development/python/devbuild/python3.4.2/include/python3.4m添加到Xcode项目的Build Settings中的Header Search Paths设置.不确定是否有办法将此作为一个通用步骤来搜索我们刚刚添加的文件夹引用目录.
将`/Users/myaccount/development/python/devbuild/python3.4.2/lib/libpython3.4m.a库拖到Xcode项目中,将其设置为引用而不复制.
现在可以使用Big Nerd Ranch scripting tutorial repository的代码进行一些修改.
插件管理器代码需要一个NSString扩展来处理Python API似乎非常喜欢的wchar_t字符串:
@interface NSString (WcharEncodedString) - (wchar_t*) getWideString; @end @implementation NSString (WcharEncodedString) - (wchar_t*) getWideString { const char* tmp = [self cStringUsingEncoding:NSUTF8StringEncoding]; unsigned long buflen = strlen(tmp) + 1; wchar_t* buffer = malloc(buflen * sizeof(wchar_t)); mbstowcs(buffer,tmp,buflen); return buffer; } @end
Python标题应包含如下:
#include "Python.h"
在调用Py_Initialize()之前,需要运行以下代码,以便按照Zorg在其他问题上的建议设置正确的python可执行文件,PYTHONPATH和PYTHONHOME.
NSString* executablePath = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/bin"]; Py_SetProgramName([executablePath getWideString]); NSString* pythonDirectory = [[NSBundle mainBundle] pathForResource:@"python3.4" ofType:nil inDirectory:@"python3.4.2/lib"]; Py_SetPath([pythonDirectory getWideString]); Py_SetPythonHome([pythonDirectory getWideString]);
最后,需要在PluginExecutor.py文件中扩展python路径以包含高级lib路径的各个子目录.将以下代码添加到Plugin Executor文件的顶部:
import sys from os import walk path = sys.path.copy() for p in path: for root,dirs,files in walk(p): if p is not root: sys.path.append(root)
如果事情开始崩溃,我会发布更新,但现在这似乎是一个有效的解决方案.