Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用autotools与库同时构建Python接口 我现在有一个C++语言库,用GNU自动工具构建,我想给它添加一个Python接口。使用SWIG我已经开发了接口,但是我在弄清楚如何将Python模块的编译与流程的其余部分集成时遇到了一些问题_C++_Python_Swig_Autotools_Autoconf - Fatal编程技术网

如何使用autotools与库同时构建Python接口 我现在有一个C++语言库,用GNU自动工具构建,我想给它添加一个Python接口。使用SWIG我已经开发了接口,但是我在弄清楚如何将Python模块的编译与流程的其余部分集成时遇到了一些问题

如何使用autotools与库同时构建Python接口 我现在有一个C++语言库,用GNU自动工具构建,我想给它添加一个Python接口。使用SWIG我已经开发了接口,但是我在弄清楚如何将Python模块的编译与流程的其余部分集成时遇到了一些问题,c++,python,swig,autotools,autoconf,C++,Python,Swig,Autotools,Autoconf,我已经研究了AM_PATH_PYTHON,但是这个宏似乎没有为PYTHON.h设置include路径,所以当我编译我的模块时,我会遇到一系列关于缺少include文件的错误。有没有办法从AM_path_Python中获取Python包含路径和ldflags 我不认为可以使用Python的distutils方法(setup.py),因为这需要库的位置来链接新模块。由于库尚未在编译时安装,因此我必须使用相对路径(例如../src/lib.so),一旦安装了Python模块,该路径当然会中断(因为库当

我已经研究了AM_PATH_PYTHON,但是这个宏似乎没有为PYTHON.h设置include路径,所以当我编译我的模块时,我会遇到一系列关于缺少include文件的错误。有没有办法从AM_path_Python中获取Python包含路径和ldflags

我不认为可以使用Python的distutils方法(setup.py),因为这需要库的位置来链接新模块。由于库尚未在编译时安装,因此我必须使用相对路径(例如../src/lib.so),一旦安装了Python模块,该路径当然会中断(因为库当时位于/usr/lib或/usr/local/lib中)

编辑:

现在它可以找到正在编译的.h文件,但是在安装它(在正确的位置)之后,Python无法加载模块。代码生成foo.so,当我“导入foo”时,我得到以下结果:

ImportError: dynamic module does not define init function (initfoo) ImportError:动态模块未定义初始化函数(initfoo) 但是,如果我将它从foo.so重命名为_foo.so,那么它的加载和运行都很好,除非我必须“导入_foo”,我不希望这样做。当我按照SWIG指令在当前目录中生成_foo.so时,“import foo”起作用,因此我不确定在站点目录中安装库时它为什么会中断

编辑2:


问题是我忘了将SWIG生成的foo.py与_foo.so一起复制到安装目录中。一旦我做到了这一点,一切都如期进行!现在,我只需要找出一些自动生成规则,将文件复制到安装目录…

要找到包含路径,我将使用
python config
。诀窍是使用与安装在
$python
中的python对应的
python配置

AM_PATH_PYTHON
AC_ARG_VAR([PYTHON_INCLUDE], [Include flags for python, bypassing python-config])
AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config])
AS_IF([test -z "$PYTHON_INCLUDE"], [
  AS_IF([test -z "$PYTHON_CONFIG"], [
    AC_PATH_PROGS([PYTHON_CONFIG],
                  [python$PYTHON_VERSION-config python-config],
                  [no],
                  [`dirname $PYTHON`])
    AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])])
  ])
  AC_MSG_CHECKING([python include flags])
  PYTHON_INCLUDE=`$PYTHON_CONFIG --includes`
  AC_MSG_RESULT([$PYTHON_INCLUDE])
])

另一种选择是查看
distutils.sysconfig
模块(这与使用distutils构建代码无关)。运行
python-c“import distutils.sysconfig;help(distutils.sysconfig)”
并查看一下。

下面是我从我的
`configure.ac
调用的autoconf宏,以查找python包含目录(PYTHONINC)和python安装目录(通过AM_PATH_python)

然后我的
wrap/python/Makefile.am
使用Libtool构建两个Swig模块,如下所示:

SUBDIRS = . cgi-bin ajax tests

AM_CPPFLAGS = -I$(PYTHONINC) -I$(top_srcdir)/src $(BUDDY_CPPFLAGS) \
              -DSWIG_TYPE_TABLE=spot

EXTRA_DIST = spot.i buddy.i
python_PYTHON = $(srcdir)/spot.py $(srcdir)/buddy.py
pyexec_LTLIBRARIES = _spot.la _buddy.la

MAINTAINERCLEANFILES = \
  $(srcdir)/spot_wrap.cxx $(srcdir)/spot.py \
  $(srcdir)/buddy_wrap.cxx $(srcdir)/buddy.py

## spot

_spot_la_SOURCES = $(srcdir)/spot_wrap.cxx $(srcdir)/spot_wrap.h
_spot_la_LDFLAGS = -avoid-version -module
_spot_la_LIBADD = $(top_builddir)/src/libspot.la

$(srcdir)/spot_wrap.cxx: $(srcdir)/spot.i
        $(SWIG) -c++ -python -I$(srcdir) -I$(top_srcdir)/src $(srcdir)/spot.i


$(srcdir)/spot.py: $(srcdir)/spot.i
        $(MAKE) $(AM_MAKEFLAGS) spot_wrap.cxx

## buddy

_buddy_la_SOURCES = $(srcdir)/buddy_wrap.cxx
_buddy_la_LDFLAGS = -avoid-version -module $(BUDDY_LDFLAGS)

$(srcdir)/buddy_wrap.cxx: $(srcdir)/buddy.i
        $(SWIG) -c++ -python $(BUDDY_CPPFLAGS) $(srcdir)/buddy.i

$(srcdir)/buddy.py: $(srcdir)/buddy.i
        $(MAKE) $(AM_MAKEFLAGS) buddy_wrap.cxx
上述规则使得Swig的结果被视为源文件(即分布在tarball中),其方式与Bison生成的解析器相同。这样,最终用户不需要安装Swig

运行
make
时,Libtool会将
*.so
文件隐藏在一些
.libs/
目录中,但在
make install
之后,它们会被复制到正确的位置

唯一的技巧是如何在运行
makeinstall
之前从源目录中使用模块。例如,在运行
时检查
。对于这种情况,我(使用
configure
)生成一个名为
run
的脚本,在运行任何
python
脚本之前设置
PYTHONPATH
,并通过该
run
脚本执行所有测试用例。以下是
run的内容。在
configure
替换任何值之前的
中:

# Darwin needs some help in figuring out where non-installed libtool
# libraries are (on this platform libtool encodes the expected final
# path of dependent libraries in each library).
modpath='../.libs:@top_builddir@/src/.libs:@top_builddir@/buddy/src/.libs'

# .. is for the *.py files, and ../.libs for the *.so.  We used to
# rely on a module called ltihooks.py to teach the import function how
# to load a Libtool library, but it started to cause issues with
# Python 2.6.
pypath='..:../.libs:@srcdir@/..:@srcdir@/../.libs:$PYTHONPATH'

test -z "$1" &&
  PYTHONPATH=$pypath DYLD_LIBRARY_PATH=$modpath exec @PYTHON@

case $1 in
  *.py)
    PYTHONPATH=$pypath DYLD_LIBRARY_PATH=$modpath exec @PYTHON@ "$@";;
  *.test)
    exec sh -x "$@";;
  *)
    echo "Unknown extension" >&2
    exit 2;;
esac

如果你想在一个真实的项目中看到这一切,你可以从

中得到它。我知道这是一篇老文章,但因为我在这里登陆了:有一些m4宏使得使用swig编译python绑定非常容易:

在命令行上手动构建 无需将SWIG步骤添加到makefiles中,您就可以使用以下命令构建SWIG扩展名(如果您有source_file.cpp和_extension.i来创建python模块):

注意:在共享对象的名称前加下划线很重要,否则在执行导入扩展时Python将无法找到它

将SWIG添加到Autoconf

我在Python中编写了一个小程序,其中需要用C++编写的一个文件(如舍入法)。 您需要额外的Autoconf宏来启用SWIG支持。正如johanvdw所指出的,如果您使用这两个m4宏:ax_pck_swig和ax_swig_python,将会更加容易。我下载了它并将其放置在我的项目树的m4子目录中:

trunk
    ├── configure.ac
    ├── __init__.py
    ├── m4
    │   ├── ax_pkg_swig.m4
    │   ├── ax_swig_python.m4
    │   ├── libtool.m4
    │   ├── lt~obsolete.m4
    │   ├── ltoptions.m4
    │   ├── ltsugar.m4
    │   └── ltversion.m4
    ├── Makefile.am
    ├── rounding_swig
    │   ├── compile.txt
    │   ├── __init__.py
    │   ├── Makefile.am
    │   ├── rnd_C.cpp
    │   ├── rounding.i
    │   ├── rounding_wrap.cpp
    └── src
        ├── cadna_add.py
        ├── cadna_computedzero.py
        ├── cadna_convert.py
        ├── __init__.py
        └── Makefile.am
将两个m4宏放入子目录时,需要将此行添加到trunk/Makefile.am:

ACLOCAL_AMFLAGS = -I m4
现在,让我们看看trunk/configure.ac:

AC_PREREQ([2.69]) # Check autoconf version 
AC_INIT(CADNA_PY, 1.0.0, cadna-team@lip6.fr) # Name of your software
AC_CONFIG_SRCDIR([rounding_swig/rnd_C.cpp]) # Name of the c++ source
AC_CONFIG_MACRO_DIR(m4)     # Indicate where are your m4 macro
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE

AC_DISABLE_STATIC #enable shared libraries

# Checks for programs.
AC_PROG_LIBTOOL  # check libtool
AC_PROG_CXX  # check c++ compiler
AM_PATH_PYTHON(2.3) # check python version
AX_PKG_SWIG(1.3.21) # check swig version
AX_SWIG_ENABLE_CXX # fill some variable usefull later
AX_SWIG_PYTHON # same

# Checks for header files.
AC_CHECK_HEADERS([fenv.h stdlib.h string.h]) # any header needed by your c++ source
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([fesetround memset strstr])

AC_CONFIG_FILES([
        Makefile
    src/Makefile
    rounding_swig/Makefile
        ])

LIBPYTHON="python$PYTHON_VERSION" # define the python interpreter
LDFLAGS="$LDFLAGS -l$LIBPYTHON"
AC_OUTPUT
将SWIG添加到Automake 在trunk/Makefile.am中,您需要执行以下操作:

ACLOCAL_AMFLAGS = -I m4

# Indicate the subdir of c++ file and python file
SUBDIRS = src rounding_swig

# Indicate a list of all the files that are part of the package, but
# are not installed by default and were not specified in any other way
EXTRA_DIST= \
rounding_swig/rounding.i \
rounding_swig/testrounding.py \
rounding_swig/testrounding.cpp
在trunk/src/Makefile.am中:

# Python source files that will be install in prefix/lib/name_of_your_python_interpreter/site-packages/name_of_your_project
pkgpython_PYTHON = cadna_add.py cadna_computedzero.py cadna_convert.py
困难的部分在trunk/rounding_swig/Makefile.am中。它创建一个library.la和一个_your_extension.so,并将其放置在项目的前缀/lib64/python2.7/site packages/name_中

# Name of the cpp source file
BUILT_SOURCES = rounding_wrap.cpp
# Name of the swig source file
SWIG_SOURCES = rounding.i
# Python source files that will be install in prefix/lib/name_of_your_python_interpreter/site-packages/name_of_your_project
pkgpython_PYTHON = rounding.py __init__.py
pkgpyexec_LTLIBRARIES = _rounding.la
_rounding_la_SOURCES = rounding_wrap.cpp $(SWIG_SOURCES) rnd_C.cpp
_rounding_la_CPPFLAGS = $(AX_SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/rounding_swig -I/usr/include/python@PYTHON_VERSION@ -lpython@PYTHON_VERSION@
_rounding_la_LDFLAGS = -module

rounding_wrap.cpp: $(SWIG_SOURCES)
    $(SWIG) $(AX_SWIG_PYTHON_OPT) -I$(top_srcdir)/rounding_swig -I/usr/include/python@PYTHON_VERSION@ -o $@ $<
最后,要安装项目,请执行以下操作:

libtoolize && aclocal && autoheader && autoconf && automake -a -c
./configure --prefix=<install prefix>
make
make install
libtoolize&&aclocal&&autoheader&&autoconf&&automake-a-c
/配置-前缀=
制作
安装

PS:是一个过时但简单的教程,对我有帮助(过时是因为它使用了ac_pkg_swig.m4,但新版本的swig失败)。

谢谢-这很有效,但现在我在最后一个问题上遇到了麻烦。所以二进制,我更新了原始问题。要将不可执行文件复制到目录中,您可能需要类似于
pkgpythondir\u DATA=foo.py
的东西。
# Name of the cpp source file
BUILT_SOURCES = rounding_wrap.cpp
# Name of the swig source file
SWIG_SOURCES = rounding.i
# Python source files that will be install in prefix/lib/name_of_your_python_interpreter/site-packages/name_of_your_project
pkgpython_PYTHON = rounding.py __init__.py
pkgpyexec_LTLIBRARIES = _rounding.la
_rounding_la_SOURCES = rounding_wrap.cpp $(SWIG_SOURCES) rnd_C.cpp
_rounding_la_CPPFLAGS = $(AX_SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/rounding_swig -I/usr/include/python@PYTHON_VERSION@ -lpython@PYTHON_VERSION@
_rounding_la_LDFLAGS = -module

rounding_wrap.cpp: $(SWIG_SOURCES)
    $(SWIG) $(AX_SWIG_PYTHON_OPT) -I$(top_srcdir)/rounding_swig -I/usr/include/python@PYTHON_VERSION@ -o $@ $<
autoreconf -i
libtoolize && aclocal && autoheader && autoconf && automake -a -c
./configure --prefix=<install prefix>
make
make install