OSX的Cython链接错误

时间:2019-04-05 04:30:57

标签: python c cython cythonize

我与此SO post有一个非常相似的问题;但是,在此处实施建议的修复程序后-我仍然收到以下错误。

我正在尝试编译Cython生成的C文件。

cython ConnectFour.pyx --embed

我尝试像这样编译我的c文件:

gcc -I /usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/Headers -o ConnectFour ConnectFour.c

但是我遇到以下错误:

Undefined symbols for architecture x86_64:
  "_PyBaseObject_Type", referenced from:
      ___Pyx_InBases in ConnectFour-3c26d7.o
  "_PyBytes_FromStringAndSize", referenced from:
      ___pyx_pymod_exec_ConnectFour in ConnectFour-3c26d7.o
      ___Pyx_InitStrings in ConnectFour-3c26d7.o
  "_PyCFunction_NewEx", referenced from:
      ___pyx_pymod_exec_ConnectFour in ConnectFour-3c26d7.o
  "_PyCFunction_Type", referenced from:
      ___Pyx_PyObject_CallOneArg in ConnectFour-3c26d7.o
      ___Pyx_PyObject_CallNoArg in ConnectFour-3c26d7.o
      ___Pyx_PyObject_Call2Args in ConnectFour-3c26d7.o
      ___Pyx_PyCFunction_FastCall in ConnectFour-3c26d7.o
      ___pyx_pf_11ConnectFour_36eval_heuristic_score in ConnectFour-3c26d7.o
      ___pyx_pf_11ConnectFour_38list_valid_col_idxs in ConnectFour-3c26d7.o
      ___pyx_pf_11ConnectFour_40deep_copy_board in ConnectFour-3c26d7.o
      ...
  "_PyCode_New", referenced from:
      ___Pyx_InitCachedConstants in ConnectFour-3c26d7.o
      ___Pyx_CreateCodeObjectForTraceback in ConnectFour-3c26d7.o
  "_PyDict_Copy", referenced from:
      ___pyx_pw_11ConnectFour_7profile_1wrapper in ConnectFour-3c26d7.o
      ___pyx_pw_11ConnectFour_5timer_1wrapper in ConnectFour-3c26d7.o
  "_PyDict_GetItemString", referenced from:
      ___pyx_pymod_exec_ConnectFour in ConnectFour-3c26d7.o
  "_PyDict_GetItemWithError", referenced from:
      ___Pyx_PyDict_GetItem in ConnectFour-3c26d7.o
  "_PyDict_New", referenced from:
      ___pyx_pymod_exec_ConnectFour in ConnectFour-3c26d7.o
      ___Pyx_Import in ConnectFour-3c26d7.o
      ___Pyx_CyFunction_get_dict in ConnectFour-3c26d7.o
      ___Pyx_CyFunction_get_annotations in ConnectFour-3c26d7.o
      ___pyx_pf_11ConnectFour_28count_players in ConnectFour-3c26d7.o
      ___pyx_pf_11ConnectFour_52num_in_a_row in ConnectFour-3c26d7.o

我是根据thisthis出现的,所以我张贴了一些图书馆链接吗?所以我尝试了以下方法。

gcc -I /usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/Headers -o ConnectFour ConnectFour.c -l/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib

现在我得到一个lib not found错误。

  

ld:找不到库   -l / usr / local / Cellar / python3 / 3.7.0 / Frameworks / Python.framework / Versions / 3.7 / lib / libpython3.7.dylib

在这里,我完全不懂阅读所有这些SO帖子(第一次处理C),因此将逐步感谢您的回答。

我需要什么才能编译然后运行C文件而不会出错?

我知道我的标题位于/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/Headers中,而库位于/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib

我在OSX上,并且使用Homebrew安装了Python。

2 个答案:

答案 0 :(得分:1)

尝试运行

gcc -I /usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/Headers -o ConnectFour ConnectFour.c -L/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7 -lpython3.7

-L标志将该目录添加到搜索路径,然后使用-l进行链接(因为-l似乎不接受绝对路径),在Linux上,至少使用-l时会省略lib前缀和扩展名,我从未使用过MacOSX,因此如果不起作用,请尝试使用不同的组合。

答案 1 :(得分:0)

因此,根据@ead的建议,我最终更仔细地阅读了this SO post,事实证明这是一个很大的帮助。为遇到类似问题的人写以下内容。

运行cython ConnectFour.pyx --embed之后,我的目标是将.c文件编译为可执行文件。这意味着(1)需要构建.o目标文件,并且(2)将.o目标文件转换为可运行的可执行文件,如下所示:./MyExecutable

步骤1.构建.o目标文件

我们需要运行以下命令,但是我遇到的问题是找出如何获取我的标志。

gcc -c hello.c -o hello.o <our cflags>

自从我通过Homebrew安装Python以来,Python及其标头文件就位于我的以下目录中。

/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/bin/

为了为我生成cflag-我必须运行以下命令。注意--cflags标志。该命令为我的Python 3安装运行config实用程序,该实用程序安装在奇怪的目录中(因为我是通过Homebrew安装的Python)。

/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/bin/python3.7-config
--cflags

下面是它为我生成的标志的摘要。

-I/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/include/python3.7m -I/usr/local.......etc etc.

使用这些标志,我运行了以下命令来生成目标文件。

gcc -c ConnectFour.c -o ConnectFour.o -I/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/include/python3.7m -I/...etc etc.

步骤2。将目标文件转换为可执行文件

为了生成可执行文件,我们需要运行以下命令。

gcc main.o hello.o -o prog <our ldflags>

要生成ldflags,这一次我需要运行以下命令。再次,我们使用config实用程序,但是这次使用--ldflags。

/usr/local/Cellar/python3/3.7.0/Frameworks/Python.framework/Versions/3.7/bin/python3.7-config --ldflags

这为我生成了以下标志。

-L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/config-3.7m-darwin -lpython3.7m ...etc. etc.

使用这些标志,我运行以下命令来生成我的可执行文件。

gcc ConnectFour.o -o ConnectFour -L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.7/lib/python3.7/config-3.7m-darwin -lpython3.7m ...etc. etc.

完成!弹出一个可执行文件,我像运行其他C可执行文件一样运行它。

特别感谢@ead向我指出正确的方向。