2

我正在尝试使用 kivy 创建一个使用 astropy 的 android 应用程序。困难在于 astropy 在安装过程中使用了 numpy,我无法让它成功加载 numpy 库。我认为问题在于它正在查找为 ARM 架构编译的库 - 我如何才能找到正确的库以在构建时使用?

我使用的是kivy提供的linux虚拟机。numpy 配方本身工作正常。对于 astropy,我创建了一个recipe.sh脚本,其中除了标准设置之外,还有这个构建函数:

function build_astropy() {
    cd $BUILD_astropy
    export BUILDLIB_PATH="$BUILD_hostpython/build/lib.linux-`uname -m`-2.7/"
    export PYTHONPATH=$SITEPACKAGES_PATH:$BUILDLIB_PATH
    push_arm
    try $HOSTPYTHON setup.py install
    pop_arm
}

这些BUILDLIB_PATH行允许它成功地找到并导入_io.so模块 - 我从另一个处理类似架构问题的配方中复制了它。但是当我尝试运行分发脚本时:

./distribute.sh -f -m "astropy kivy" -d astropy

它尝试导入 numpy,但出现此错误:

ImportError: /home/kivy/android/python-for-android/build/python-install/lib/python2.7/site-packages/numpy/core/multiarray.so: cannot open shared object file: No such file or directory

该文件确实存在,但可能是为 ARM 编译的。我尝试添加本地 numpy 安装:

/usr/lib/python2.7/dist-packages/numpy/core/

到了,BUILDLIB_PATH但它没有任何区别。有没有人有任何关于在构建时让 kivy 找到合适的库的提示?

4

1 回答 1

1

失败导入的回溯包含get_numpy_include_path()在其中,来自astropy_helpers/astropy_helpers/setup_helpers.py. 查看 numpy's 的源代码get_include(),它在交叉编译时无法在系统上运行,因此即使您设法为主机 Python 构建 numpy,它也会得到不正确的值。

修补 astropy 以允许通过环境提供 numpy 包含路径(在哪里可以找到文件,例如numpyconfig.h)将解决此问题,因此创建recipes/patches/add_numpy_include.patch包含以下内容:

--- astropy-0.4.4.orig/astropy_helpers/astropy_helpers/setup_helpers.py 2015-02-15 18:16:02.135642283 -0600
+++ astropy-0.4.4/astropy_helpers/astropy_helpers/setup_helpers.py  2015-02-15 18:15:10.985674250 -0600
@@ -1307,6 +1307,11 @@
     # install, since Numpy may still think it's in "setup mode", when
     # in fact we're ready to use it to build astropy now.

+    # Allow the environment to override the include path, to allow
+    # cross-compilation
+    if 'NUMPY_INCLUDE_PATH' in os.environ:
+        return os.environ['NUMPY_INCLUDE_PATH']
+
     if sys.version_info[0] >= 3:
         import builtins
         if hasattr(builtins, '__NUMPY_SETUP__'):

如果您尝试仅使用此补丁进行构建,则会导致构建错误,struct lconv因此请创建第二个补丁文件,recipes/patches/lconv_fix.patch其中包含以下内容:

--- astropy-0.4.4.orig/cextern/wcslib/C/wcsutil.c   2015-02-15 18:07:46.549935299 -0600
+++ astropy-0.4.4/cextern/wcslib/C/wcsutil.c    2015-02-15 18:36:07.062452345 -0600
@@ -247,7 +247,7 @@

 {
   struct lconv *locale_data = localeconv();
-  const char *decimal_point = locale_data->decimal_point;
+  const char *decimal_point = ".";

   if (decimal_point[0] != '.' || decimal_point[1] != 0) {
     size_t decimal_point_len = strlen(decimal_point);
@@ -311,7 +311,7 @@

 {
   struct lconv *locale_data = localeconv();
-  const char *decimal_point = locale_data->decimal_point;
+  const char *decimal_point = ".";

   if (decimal_point[0] != '.' || decimal_point[1] != 0) {
     char *out = outbuf;
--- astropy-0.4.4.orig/cextern/cfitsio/fitscore.c   2015-02-15 18:07:46.553935299 -0600
+++ astropy-0.4.4/cextern/cfitsio/fitscore.c    2015-02-15 18:41:16.626440539 -0600
@@ -9226,7 +9226,7 @@

     if (!decimalpt) { /* only do this once for efficiency */
        lcc = localeconv();   /* set structure containing local decimal point symbol */
-       decimalpt = *(lcc->decimal_point);
+       decimalpt = '.';
     }

     errno = 0;
@@ -9296,7 +9296,7 @@

     if (!decimalpt) { /* only do this once for efficiency */
        lcc = localeconv();   /* set structure containing local decimal point symbol */
-       decimalpt = *(lcc->decimal_point);
+       decimalpt = '.';
     }

     errno = 0;

lconv 修复并不是一个很好的修复,因为它假定 Android 设备上的语言环境具有 '.' 作为小数点分隔符,但官方存储库中numpy 的补丁会这样做,因此 astropy 在与 numpy 相同的情况下会失败。

根据官方存储库prebuild_astropy()使用 numpy 1.7.1和配方,以下build_astropy()功能适用于 astropy 0.4.4,调用./distribute.sh -m "numpy astropy kivy" -d astropy

function prebuild_astropy() {
    cd $BUILD_astropy

    if [ -f .patched ]; then
        return
    fi

    try patch -p1 < $RECIPE_astropy/patches/add_numpy_include.patch
    try patch -p1 < $RECIPE_astropy/patches/lconv_fix.patch
    touch .patched
    true
}

function build_astropy() {
    cd $BUILD_astropy
    export BUILDLIB_PATH="$BUILD_hostpython/build/lib.linux-`uname -m`-2.7/"
    export PYTHONPATH=$SITEPACKAGES_PATH:$BUILDLIB_PATH
    export NUMPY_INCLUDE_PATH="$BUILD_PATH/python-install/lib/python2.7/site-packages/numpy/core/include"
    push_arm
    try $BUILD_PATH/python-install/bin/python.host setup.py install
    pop_arm
    unset BUILDLIB_PATH
    unset PYTHONPATH
    unset NUMPY_INCLUDE_PATH
}
于 2015-02-16T00:58:20.490 回答