编译可在Android上运行的qemu

本文在ubuntu20.04上对qemu进行交叉编译

注意:NDK编译器工具API级别要在30以后,最好用33

因为只有30以后的版本支持函数memfd_create,详情请看http://t.csdn.cn/465cy

1.下载并安装Android NDK

NDK 下载  |  Android NDK  |  Android Developershttps://developer.android.google.cn/ndk/downloadsNDK下载网址下载linux版本安装包:android-ndk-r25-linux.zip 

vi ~/.bashrc

export API=21
export NDK=/home/dubu/android-ndk-r25
export NDK_CROSS=${NDK}/toolchains/llvm/prebuilt/linux-x86_64/bin
export SYSROOT=${NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot
export PKG_CONFIG_PATH=${SYSROOT}/python3/lib/pkgconfig
export PKG_CONFIG_LIBDIR=${NDK_CROSS}
export PATH=${PATH}:${NDK}:${NDK_CROSS}

source .bashrc

2.安装glib库

下载glib

git clone https://github.com/GNOME/glib.git

cd glib

cat HACKING     /*查看HACKING文件*/

HACKING文件内容如下:

If you want to hack on the GLib project, you'll need to have the
following packages installed:

        - Meson 0.48.0
        - GNU gettext 0.10.40
        - pkg-config 0.16
        - gtk-doc
        - libffi 3.0.0

To compile a Git version of glib on your system, you will need to take
several steps to setup the tree for compilation.  You can do all these
steps at once by running:

        checkout/glib# meson _build

For information about submitting patches see the CONTRIBUTING.md file. For
information about major design decisions, see the docs/README.rationale file.

想要编译glib库,需要如下几个组件:

        - Meson 0.48.0
        - GNU gettext 0.10.40
        - pkg-config 0.16
        - gtk-doc
        - libffi 3.0.0

(1)安装MMeson 0.48.0或以上版本

注意:meson安装前必须确认是否已经安装python3.5及以上版本;因为meson依赖于python3和ninja

sudo apt-get install python3 python3-pip ninja-build

sudo pip3 install --user meson

测试meson是否安装成功,此步骤可以忽略:

创建1.c与meson.build两个文件

vim 1.c
#include <stdio.h>

int main()
{
	printf("hello world\n");
	return 0;
}

vim meson.build
project('tutorial', 'c')      
executable('demo', '1.c')

meson builid

cd build

ninja

./demo

在执行./demo的时候会打印出hello world.

(2)安装GNU gettext 0.10.40或以上版本

官网地址:https://www.gnu.org/software/gettext/

wget https://ftp.gnu.org/pub/gnu/gettext/gettext-0.21.tar.gz

tar -zxvf gettext-0.21.tar.gz

cd gettext-0.21

sudo ./configure

sudo make

sudo make install

(3)安装pkg-config 0.16及以上版本

方法一:

sudo apt-get install pkg-config

方法二:

Linux上,到pkg-config官网https://www.freedesktop.org/wiki/Software/pkg-config/,下载最新安装包

tar -zxvf pkg-config-0.29.2.tar.gz

cd pkg-config-0.29.2/

./configure

make

make check

sudo make install

pkg-config --version

(4)安装gtk-doc

参考网址:

Ubuntu安装GTK+教程 - 一杯清酒邀明月 - 博客园Step 1 修改清华源(修改完可提高下载速度) 先运行 sudo gedit /etc/apt/sources.list 替换文本内容,保存,退出。 # 默认注释了源码镜像以提高 apt updathttps://www.cnblogs.com/ybqjymy/p/12964668.html

(5)安装libffi 3.0.0及以上版本

sudo apt-get install libffi-dev

此前的内容当作废话,真正的交叉编译从这里开始。因为写的太好不想删除。

3.安装libiconv

官网地址:libiconv - GNU Project - Free Software Foundation (FSF)https://www.gnu.org/software/libiconv/?spm=a2c6h.12873639.article-detail.6.5409666ffjh5uO#TOCdownloading

下载地址:https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.17.tar.gz

ln -sf ${NDK_CROSS}/aarch64-linux-android21-clang ${NDK_CROSS}/aarch64-linux-android21-gcc

ln -sf ${NDK_CROSS}/aarch64-linux-android21-clang++ ${NDK_CROSS}/aarch64-linux-android21-g++

tar -zxvf libiconv-1.17.tar.gz

cd libiconv-1.17

mkdir build && cd build

CC="aarch64-linux-android21-gcc" CFLAGS="-I${SYSROOT}/usr/include --sysroot $SYSROOT" ../configure --prefix="${SYSROOT}/usr" --host=arm-linux-android21 --enable-shared=yes --enable-static=no 

make && make install

4.安装gettext

官网地址:

Index of /pub/gnu/gettexthttps://ftp.gnu.org/pub/gnu/gettext/?C=M;O=A下载安装包:gettext-0.21.tar.gz

tar -zxvf gettext-0.21.tar.gz

cd gettext-0.21 && mkdir build && cd build

CC="aarch64-linux-android21-clang" CPP="aarch64-linux-android21-clang -E" CPPFLAGS="-I${SYSROOT}/usr/include" CXX="aarch64-linux-android21-clang++" CXXCPP="aarch64-linux-android21-clang++ -E" ../configure --prefix="${SYSROOT}/usr" --host=arm-linux-android21 CFLAGS="-fPIC" --with-libiconv-prefix=${SYSROOT}/usr --with-sysroot=${SYSROOT}

make

make install

http://t.csdn.cn/NZ7Gfhttp://t.csdn.cn/NZ7Gf若是make install出现问题,可以查看上面的连接进行解决。

5.安装libffi

官网地址:libffihttps://sourceware.org/libffi/

下载安装包:libffi-3.4.2.tar.gz

tar -zxvf libffi-3.4.2.tar.gz

cd libffi-3.4.2 && mkdir build && cd build

../configure --prefix="${SYSROOT}/usr" --host=aarch64-linux-android21 --with-sysroot=${SYSROOT}  CC=${NDK_CROSS}/aarch64-linux-android21-gcc  CFLAGS="-march=armv8-a -DANDROID" CXX=${NDK_CROSS}/aarch64-linux-android21-g++  CXXFLAGS="-march=armv8-a -DANDROID" CPPFLAGS="-I${SYSROOT}/usr/include" LDFLAGS="-L${SYSROOT}/usr/lib" --disable-multi-os-directory --target=aarch64-linux-android21

make 

make install

可以查看如下网址,对gcc 的-march,-mtune,-mcpu作大概了解。

ARM-GCC编译选项解释_superaxi的博客-CSDN博客_arm gcc 编译选项ARM选项-mabi=name为指定的ABI生成代码。允许值为:‘apcs-gnu’, ‘atpcs’, ‘aapcs’, ‘aapcs-linux’ 和 ‘iwmmxt’-mapcs-frame为所有功能生成符合ARM过程调用标准的堆栈框架,即使这对于正确执行代码不是绝对必要的。指定-fomit-frame-pointer 如果使用此选项,则不会为叶函数生成堆栈帧。默认是-mno-apcs-frame。不建议使用此选项。-mapcs这是和 -mapcs-frame选项一样, 并已弃用。-mthttps://blog.csdn.net/luoqingxi000/article/details/110430292

6.安装pcre

官网地址:http://pcre.org/

下载安装包:pcre2-10.40.zip

unzip pcre2-10.40.zip

cd pcre2-10.40 && mkdir build && cd build

CC="aarch64-linux-android21-gcc" LDFLAGS="-L${SYSROOT}/usr/lib" CPPFLAGS="-I${SYSROOT}/usr/include" ../configure --prefix=${SYSROOT}/usr --host=aarch64-linux-android21 --with-sysroot=${SYSROOT}/usr

make

make install

7.安装pixman-0.34

http://t.csdn.cn/ht6t6

8.安装glib

http://t.csdn.cn/wr6mZ

9.编译qemu

编译命令如下:

下面的编译命令只做参考:

PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig" ../configure --prefix=/home/dubu/installtest --target-list=x86_64-softmmu --cpu=aarch64 --cross-prefix=aarch64-linux-android33- --cc=aarch64-linux-android33-clang --cxx=aarch64-linux-android33-clang++ --host-cc=aarch64-linux-android33-gcc --enable-gettext --enable-iconv --enable-kvm --enable-pie --enable-gio --enable-qcow1 --enable-vhost-user

 上面的配置命令只做参考,用下面的配置命令配置:

PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig" ../configure --prefix=/home/dubu/installtest --target-list=x86_64-softmmu --cpu=aarch64 --cross-prefix=aarch64-linux-android33- --python=$NDK_PYTHON --extra-cflags=" --sysroot=$SYSROOT" --extra-cxxflags=" --sysroot=$SYSROOT" --enable-pie         

为什么要加上--enable-pie和--extra-cflags=" --sysroot=$SYSROOT" --extra-cxxflags=" --sysroot=$SYSROOT" 看如下链接:

http://t.csdn.cn/ItOme

http://t.csdn.cn/aK8F1

只交叉编译出可以运行win10的运行程序即可。 

PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig",这个是指定交叉编译好的依赖包的位置。

        --cross-prefix=aarch64-linux-android33- 这个是指定的交叉编译前缀,这个选项用于表明是交叉编译,详情可以去看官网qemu的交叉编译的介绍。

其中会报找不到aarch64-linux-android33-pkg-config

ln -s  /usr/bin/pkg-config  aarch64-linux-android33-pkg-config

make报错:

aarch64-linux-android29-clang  -o subprojects/libvhost-user/link-test subprojects/libvhost-user/link-test.p/link-test.c.o -Wl,--as-needed -Wl,--no-undefined -pie -Wl,--whole-archive -Wl,--start-group subprojects/libvhost-user/libvhost-user.a -Wl,--end-group -Wl,--no-whole-archive -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -pthread
ld: error: undefined symbol: memfd_create
>>> referenced by libvhost-user.c:1670 (../subprojects/libvhost-user/libvhost-user.c:1670)
>>>               libvhost-user.a.p/libvhost-user.c.o:(vu_dispatch) in archive subprojects/libvhost-user/libvhost-user.a
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

可查看如下网址解决:

 http://t.csdn.cn/kl8UT

make 报错:

[69/2776] Linking target subprojects/libvhost-user/link-test
FAILED: subprojects/libvhost-user/link-test 
aarch64-linux-android33-clang  -o subprojects/libvhost-user/link-test subprojects/libvhost-user/link-test.p/link-test.c.o -Wl,--as-needed -Wl,--no-undefined -pie -Wl,--whole-archive -Wl,--start-group subprojects/libvhost-user/libvhost-user.a -Wl,--end-group -Wl,--no-whole-archive -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -pthread
ld: error: undefined symbol: vring_need_event
>>> referenced by libvhost-user.c:2399 (../subprojects/libvhost-user/libvhost-user.c:2399)
>>>               libvhost-user.a.p/libvhost-user.c.o:(_vu_queue_notify) in archive subprojects/libvhost-user/libvhost-user.a
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
make: *** [Makefile:163:run-ninja] 错误 1

其实这里的函数vring_need_event在/usr/include/linux/virtio_ring.h和~/qemu-7.0.0/include/standard-headers/linux/virtio_ring.h中都有定义,而正常编译的时候用的/usr/include/linux/virtio_ring.h文件,而不是~/qemu-7.0.0/include/standard-headers/linux/virtio_ring.h这个文件里面的定义,因为这两文件的开头是都

#ifndef _LINUX_VIRTIO_RING_H
#define _LINUX_VIRTIO_RING_H,所以包含了其中一个就不会包含另外一个。

这里的解决办法是把/usr/include/linux/virtio_ring.h文件里面定义的函数vring_init,vring_size,vring_need_event添加到${SYSROOT}/usr/include/linux/virtio_ring.h文件里面。

并且把~/qemu-7.0.0/include/standard-headers/linux/virtio_ring.h文件里面的_LINUX_VIRTIO_RING_H改成“_UAPI_LINUX_VIRTIO_RING_H”,因为交叉编译用到的是${SYSROOT}/usr/include/linux/virtio_ring.h这个文件。可以参考如下链接:

http://t.csdn.cn/lJbnw

http://t.csdn.cn/HX5Fk

出现qemu:tests/qtest/libqos/libqos.fa.p/pci.c.o报错,查看http://t.csdn.cn/gS8js

出现shm_open和shm_unlink这两个函数未定义的报错,直接在build.ninja里面删除这个目标(在all里面的目标里面删除)就可以了,为什么,因为是在contrib目录下的目标用到了这来两个函数,而且删除这个目录下面的内容对于运行虚拟机没有什么影响,所以就删除了。

具体做法:打开build.ninja文件

在编译目标build all,build build.ninja,以及最后一个build里面,删除带有contrib/的所有目标,并且删除tests/qtest/ivshmem-test目标。这些目标的生成规则可以不用管。

至此编译就可以成功了,如果遇到新问题,欢迎留言。

make install 会报错aarch64-linux-android33-strip文件未找到

ln -sf llvm-strip aarch64-linux-android33-strip即可。

注意:我这边只是说编译成功,没有说可以在android上面运行win10。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值