安装OpenNAO的编译环境

总述

本文主要解决在OpenNAO虚拟机中成功运行NAOqi Python SDK的问题,以便不依赖实体机器人成进行测试与代码编译工作。

因为我们的AXMService代码必须在pepper本体中运行,导致需要打包编译的时候,必须找一个机器人来操作,而且编译过程还不能在pepper里面,因为没有root权限,缺乏一些依赖包,只能在NAO的机器系统里面。

这一点大大限制了我们打包部署的过程。所以一直希望,去掉这个硬件依赖,让我们直接在电脑的虚拟里面就能打包。

下面先重现在OpenNAO中运行代码遇到的报错,然后给出相应的解决办法。

整个步骤完成后的OpenNAO系统,我已经通过VirtuaBox导出了一个镜像系统文件,放到公司的共享上面,文件名为 opennao-vm-2.1.2.17-axm0311.ova

以后大家具体使用,直接导入我制作好的系统镜像,然后直接使用,并不需要进行以下这些步骤。

问题重现

安装好 pynaoqi-python2.7-2.4.3.28-linux32

wget -c https://community-static.aldebaran.com/resources/2.4.3.28/sdk-python/pynaoqi-python2.7-2.4.3.28-linux32.tar.gz
tar vxzf pynaoqi-python2.7-2.4.3.28-linux32.tar.gz
rm pynaoqi-python2.7-2.4.3.28-linux32.tar.gz
export PYTHONPATH=/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/
export LD_LIBRARY_PATH=/home/nao/.local/AXMService/lib:/home/nao/.local/lib:/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/

测试naoqi sdk是否能正常运行,只需要打开python shell,尝试import qi:

virtual-nao [err 1] ~/.local/AXMService $ python
Python 2.7.8 (default, Sep 10 2014, 15:09:52) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import qi
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/qi/__init__.py", line 66, in <module>
    from _qi import Application as _Application
ImportError: /usr/lib/gcc/i686-pc-linux-gnu/4.5.3/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by /home/nao/pynaoqi-python2.7-2.4.3.28-linux32/libqi.so)

这个错原因为gcc版本太低,naoqi sdk用的较高版本的gcc编译的,本系统没有对应的高版本库,解决办法为升级gcc,见下面。

解决gcc版本问题后继续。

virtual-nao [0] ~/gcc-4.8.5/build $ python
Python 2.7.8 (default, Sep 10 2014, 15:09:52) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import qi
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/qi/__init__.py", line 66, in <module>
    from _qi import Application as _Application
ImportError: /lib/libc.so.6: version `GLIBC_2.15' not found (required by /home/nao/pynaoqi-python2.7-2.4.3.28-linux32/libqi.so) 

这个错误原因为glibc库版本太低,升级glibc到2.15后解决,步骤见下面。

解决glibc版本后继续。需要把安装路径加到环境变量中去:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/nao/.local/glibc2.15/lib

这时候再尝试import qi

virtual-nao [0] ~ $ python
Python 2.7.8 (default, Sep 10 2014, 15:09:52) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import qi
>>> 

发现已经没有报错,说明naoqi sdk已经安装好了,下面我们来运行下axmservice看看。

运行 AXMService/run.py 报错:

virtual-nao [0] ~/.local/AXMService $ python run.py 
Traceback (most recent call last):
  File "run.py", line 50, in <module>
    from axmservice.config import ConfigCommon
  File "/home/nao/.local/AXMService/axmservice/config.py", line 4, in <module>
    from axmservice.helper.config_helper import ConfigHelper
  File "/home/nao/.local/AXMService/axmservice/helper/config_helper.py", line 2, in <module>
    import requests
  File "/usr/lib/python2.7/site-packages/requests/__init__.py", line 58, in <module>
    from . import utils
  File "/usr/lib/python2.7/site-packages/requests/utils.py", line 12, in <module>
    import cgi
  File "/usr/lib/python2.7/cgi.py", line 51, in <module>
    import mimetools
  File "/usr/lib/python2.7/mimetools.py", line 6, in <module>
    import tempfile
  File "/usr/lib/python2.7/tempfile.py", line 34, in <module>
    from random import Random as _Random
  File "/usr/lib/python2.7/random.py", line 45, in <module>
    from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
ImportError: /usr/lib/python2.7/lib-dynload/math.so: undefined symbol: PyFPE_jbuf

需要重新用gcc 编译python 2.8.7,得到新的math.so,见下面步骤。

之后就能顺利运行axmservice的代码:

virtual-nao [0] ~/.local/AXMService $ python run.py 
[I 170311 13:09:51 functions:59] Start cover config
[I 170311 13:09:51 functions:106] cover ConfigASR.use_alitts from False into False
[I 170311 13:09:51 functions:106] cover ConfigASR.use_aliasr from False into False
[W] 17176 qimessaging.transportsocket: connect: Connection refused
Traceback (most recent call last):
  File "run.py", line 96, in <module>
    qi_helper.connect()
  File "/home/nao/.local/AXMService/axmservice/helper/qi_helper.py", line 22, in connect
    app.start()
RuntimeError: System error: Connection refused

这里的 Connection refused 不是因为环境问题,而是本地没有开启naoqi-bin服务,拿不到service。

然后运行pyinstaller尝试编译,就可以成功。

升级gcc到4.8.5

wget -c "http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.5/gcc-4.8.5.tar.gz"
tar vxzf gcc-4.8.5.tar.gz
cd gcc-4.8.5
./contrib/download_prerequisites
mkdir build
cd build
../configure --prefix=/home/nao/.local/ --enable-checking=release --enable-languages=c,c++ --disable-multilib
make
make install

编译可能需要几个小时时间,需耐心等待。我用我的Macbook Pro,开了8G内存4核cpu给虚拟机,用 make -j4 火力全开编译,也花了 45 分钟。

参考:https://itbilu.com/linux/management/V1vdnt9ll.html

升级glibc到2.15

wget -c http://ftp.gnu.org/gnu/glibc/glibc-2.15.tar.gz
tar vxzf glibc-2.15.tar.gz 
wget http://ftp.gnu.org/gnu/glibc/glibc-ports-2.15.tar.gz
tar vxzf glibc-ports-2.15.tar.gz
mv glibc-ports-2.15 glibc-2.15/ports
cd glibc-2.15
mkdir build
cd build
../configure --prefix=/home/nao/.local/glibc2.15/ --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin CC='gcc -U__i686'
make
sudo make install 

注意这里一定要安装到 .local/glibc2.15 ,不要覆盖系统全局的,不然非常危险,glibc是linux系统非常底层的库,覆盖后连ls等基础的linux命令都会出现 segment fault。

如果上面在configure的时候不加参数 CC=’gcc -U__i686′ ,make的时候会报如下的错:

../sysdeps/i386/fpu/s_frexp.S: Assembler messages:
../sysdeps/i386/fpu/s_frexp.S:66: Error: invalid identifier for ".ifdef"
../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1'
../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1'
../sysdeps/i386/fpu/s_frexp.S:66: Error: Missing symbol name in directive
../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1'
../sysdeps/i386/fpu/s_frexp.S:66: Error: Missing symbol name in directive
../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `.'
../sysdeps/i386/fpu/s_frexp.S:66: Error: junk at end of line, first unrecognized character is `1'
../sysdeps/i386/fpu/s_frexp.S:66: Error: expected comma after name `' in .size directive
../sysdeps/i386/fpu/s_frexp.S:66: Error: ".endif" without ".if"
../sysdeps/i386/fpu/s_frexp.S:66: Error: junk `.get_pc_thunk.dx' after expression
make[2]: *** [/home/nao/glibc-2.15/build/math/s_frexp.os] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory `/home/nao/glibc-2.15/math'
make[1]: *** [math/subdir_lib] Error 2
make[1]: Leaving directory `/home/nao/glibc-2.15'
make: *** [all] Error 2

make install的时候会报错:

  /home/nao/glibc-2.15/build/elf/ldconfig  \
             /home/nao/.local/glibc2.15/lib /home/nao/.local/glibc2.15/lib
/home/nao/glibc-2.15/build/elf/ldconfig: Can't open configuration file /home/nao/.local/glibc2.15/etc/ld.so.conf: No such file or directory
make[1]: Leaving directory `/home/nao/glibc-2.15'

解决办法:

sudo cp /etc/ld.so.conf /home/nao/.local/glibc2.15/etc/

参考:http://love.junzimu.com/archives/2269

解决 python中math.so的版本问题

下载python 2.7.8,重新编译,得到新的 math.so,覆盖原来的就行了。

重新开一个全新的OpenNAO虚拟机编译python,因为我们只需要math.so,全部编译Python覆盖系统的话,会出现问题,我尝试过。

wget -c https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
tar vxzf Python-2.7.8.tgz
cd Python-2.7.8
./configure
make
sudo make install

把得到的 /usr/lib/python2.7/lib-dynload/math.so 复制到我们的系统中去。

环境变量

需要添加两个环境变量

export LD_LIBRARY_PATH=/home/nao/.local/AXMService/lib:/home/nao/.local/lib:/home/nao/.local/glibc2.15/lib:/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/
export PYTHONPATH=/home/nao/pynaoqi-python2.7-2.4.3.28-linux32/

pyinstaller

在执行pyinstaller的时候,可能会报错,说找不到 ~/.local/bin/lddlibc4 ,这时从系统路径中复制过去即可:

cp /usr/bin/lddlibc4 ~/.local/bin/