【问题标题】:How can I compile astropy (which uses numpy) for a kivy android installation?如何为 kivy android 安装编译 astropy(使用 numpy)?
【发布时间】:2015-01-26 00:36:10
【问题描述】:

我正在尝试使用 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 找到合适的库的任何提示?

【问题讨论】:

  • 之前没有关于为android 编译numpy 的问题吗?正常的 linux 安装使用许多额外的 C 库(甚至是 Fortran 编译器)。
  • 我对 kivy 一无所知,但听起来你的 $PYTHONPATH 上可能有一些愚蠢的东西
  • @hpaulj 为 android 编译 numpy 的步骤工作正常。我的问题是 astropy 需要导入 linux 编译的 numpy 才能构建,我不知道如何让它找到正确的库。
  • 那么你能在你的安卓设备上运行numpy吗? numpy .so 文件必须链接到 Android 代码,而不是 linux 代码。
  • 是的,当我进行单独的 numpy 分发时:./distribute.sh -f -m "numpy kivy" -d numpy 它工作正常,并且 numpy 在 android 设备上运行。

标签: android python numpy kivy astropy


【解决方案1】:

失败导入的回溯包含get_numpy_include_path(),它来自astropy_helpers/astropy_helpers/setup_helpers.py。查看 numpy 的 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 设备上的语言环境具有 '.'作为小数点分隔符,但官方存储库中的 patch for numpy 会这样做,因此 astropy 在与 numpy 相同的情况下会失败。

使用 numpy 1.7.1 和 official repository 的配方,以下 prebuild_astropy()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
}

【讨论】:

  • 奇怪的是lcc-&gt;decimal_point; 在那个平台上不起作用。这是为什么?我想知道这些补丁中的某些形式是否值得包含在 Astropy 中(后者不那么重要,除非它使用某种 ifdef)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 2014-12-12
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
相关资源
最近更新 更多