编译可在Android上运行的qemu user mode

@(Android研究)[android|qemu]

[TOC]

前言

本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编译与qemu user mode有关的代码。

下文中的"NDK"若无特殊说明均指"Android NDK"。

下文中"$NDK"表示的是NDK的根目录。

步骤

1. 下载并安装Android NDK

下载并安装Android NDK的过程在这里不做介绍。

2. 下载qemu

3. 设置NDK工具的环境变量

4. 编译依赖库

glib

libpng12

5. 创建pkg-config的软链接

ln -s /usr/bin/pkg-config $NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-pkg-config

ln命令中的源路径是pkg-config工具的源路径。

如果不创建这个软链接,当执行configure脚本时会报下面的错误:

ERROR: pkg-config binary 'arm-linux-androideabi-pkg-config' not found

6. 修改configure

添加arm的PIE支持

找到下面的代码:

if test "$pie" = ""; then

case "$cpu-$targetos" in

i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)

;;

*)

pie="no"

;;

esac

fi

将"i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD"更改为"i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD|arm-Linux"。

如果不这么做的后果 使用"readelf -S qemu-arm"查看编译出来的qemu-arm可执行文件的段,可以发现所有在运行时可加载段的地址均以0x60000000为基址。

在configure中有这么一段代码:

# Probe for the need for relocating the user-only binary.

if test "$pie" = "no" ; then

textseg_addr=

case "$cpu" in

arm | i386 | ppc* | s390* | sparc* | x86_64 | x32)

# ??? Rationale for choosing this address

textseg_addr=0x60000000

;;

mips)

# A 256M aligned address, high in the address space, with enough

# room for the code_gen_buffer above it before the stack.

textseg_addr=0x60000000

;;

esac

if [ -n "$textseg_addr" ]; then

cat > $TMPC <

int main(void) { return 0; }

EOF

textseg_ldflags="-Wl,-Ttext-segment=$textseg_addr"

......

fi

如果$pie等于"no",textseg_addr的值将为0x60000000,textseg_ldflags将会设置"-Wl,-Ttext-segment=$textseg_addr"这个命令行选项,这个命令行选项指定text段的基址。在脚本的后面textseg_ldflags会被添加到ldflags中。

如果qemu-arm可加载段的基址为0x60000000,当qemu-arm在Android设备上运行时将会发生"Segmentation fault",详情请参考Android上可执行ELF文件中的段不能有基址。

7. 运行configure

PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig" ./configure --prefix="$SYSROOT/usr" --target-list=arm-linux-user --disable-system --disable-bsd-user --disable-tools --disable-zlib-test --cross-prefix="arm-linux-androideabi-" --cc="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc" --host-cc="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc" --cpu="arm" --cxx="$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++" --extra-ldflags="-fPIE -pie --sysroot $SYSROOT -L$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9/ -L$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/ -L$NDK/platforms/android-21/arch-arm/usr/lib/" --extra-cflags="-fPIE -pie --sysroot $SYSROOT -I$NDK/sources/cxx-stl/gnu-libstdc++/4.9/include -I$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include -L$NDK/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/" --disable-guest-agent

命令行解析

configure脚本会在终端输出一些关键的信息,如:用什么编译器,flags等。

PKG_CONFIG_PATH

上面命令中的PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig"是必要的,如果不设置这个宏,configure脚本输出"CFLAGS"的内容见下:

CFLAGS -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g

关注"-I"后的路径,首先说一下这个路径是怎么来的,configure脚本中有下面的代码:

glib_req_ver=2.22

glib_modules=gthread-2.0

if test "$modules" = yes; then

glib_modules="$glib_modules gmodule-2.0"

fi

for i in $glib_modules; do

if $pkg_config --atleast-version=$glib_req_ver $i; then

glib_cflags=`$pkg_config --cflags $i`

glib_libs=`$pkg_config --libs $i`

CFLAGS="$glib_cflags $CFLAGS"

LIBS="$glib_libs $LIBS"

libs_qga="$glib_libs $libs_qga"

else

error_exit "glib-$glib_req_ver $i is required to compile QEMU"

fi

done

"glib_cflags=$pkg_config --cflags $i"语句会获得glib的包含目录,看这篇文章的人如果电脑上安装有glib2.0可以通过这个命令进行查看输出内容:pkg-config --cflags glib-2.0。

然而这个路径并不是我想要的,因为我现在是交叉编译,目标是ARM,所以我在这里将一个新的pkgconfig目录路径设置到PKG_CONFIG_PATH宏,输入下面的命令查看输出内容:

PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig" pkg-config --cflags glib-2.0

输出内容:

-I/home/sowuy/Tools/android-ndk-r11b/platforms/android-21/arch-arm/usr/include/glib-2.0 -I/home/sowuy/Tools/android-ndk-r11b/platforms/android-21/arch-arm/usr/lib/glib-2.0/include -I/home/sowuy/Tools/android-ndk-r11b/platforms/android-21/arch-arm/usr/include

会发现此时"-I"后的路径有了改变。

注意:pkgconfig是一个目录,在这个目录中包含了步骤5中安装的依赖库的信息。

--target-list --cpu

--target-list arm-linux-user 意味着编译出来的qemu程序用于user mode,可以执行arm指令,并且这个arm指令的可执行程序的执行环境基于linux系统。 --cpu=arm 意味着编译出的qemu程序只能在arm机器上执行。

--disable-system --disable-bsd-user

--disable-system:不编译system mode的代码。 --disable-bsd-user:不编译bsd user mode的代码。

--cross-prefix

交叉编译工具的前缀,在当前命令行中它的值为"arm-linux-androideabi-",那么configure脚本会去查找名为arm-linux-androideabi-gcc、arm-linux-androideabi-g++等工具。

--disable-tools

当命令行中有--disable-tools选项时,脚本中的禁用want_tools宏将被设置为"no",这个宏默认为"yes"。当want_tools宏为"yes"时,会对tools宏进行设置,下面是与want_tools有关的设置tools宏的代码:

tools=""

if test "$want_tools" = "yes" ; then

tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools"

if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then

tools="qemu-nbd\$(EXESUF) $tools"

tools="ivshmem-client\$(EXESUF) ivshmem-server\$(EXESUF) $tools"

fi

fi

configure脚本会将tools宏的内容写入config-host.mak文件。

--disable-guest-agent

当没有这个选项时,编译会报下面的错误:

qga/main.c:327: error: undefined reference to 'lockf'

collect2: error: ld returned 1 exit status

make: *** [qemu-ga] Error 1

为PC编译qemu项目没有这个命令选项时不会报这个错误,然而lockf函数在Android上并不存在,所以为Android编译qemu项目时会报这个错误。

编译错误排除

ld: error: cannot find -lutil

将根目录下的Makefile文件中下面的内容注释:

ifneq ($(wildcard config-host.mak),)

include $(SRC_PATH)/tests/Makefile

endif

ifaddrs.h: No such file or directory

错误信息

qga/commands-posix.c:45:21: fatal error: ifaddrs.h: No such file or directory

#include

^

compilation terminated.

make: *** [qga/commands-posix.o] Error 1

修复办法

将这个链接中的源文件都下载下来:android-ifaddrs,将下载下来的文件拷贝到qga/目录下。然后找到qga/Makefile.objs文件,将"ifaddrs.o"插入"qga-obj-$(CONFIG_POSIX)"宏中。

mqueue.h: No such file or directory

错误信息

qemu-2.5.0/linux-user/syscall.c:964:20: fatal error: mqueue.h: No such file or directory

#include

^

compilation terminated.

make[1]: *** [linux-user/syscall.o] Error 1

make: *** [subdir-arm-linux-user] Error 2

修复办法

将"#include "更改为"#include "。

char __unused[128 - sizeof(target_sigset_t)];

错误信息

qemu-2.5.0/linux-user/signal.c:1452:18: error: expected identifier or '(' before '[' token

char __unused[128 - sizeof(target_sigset_t)];

^

make[1]: *** [linux-user/signal.o] Error 1

make: *** [subdir-arm-linux-user] Error 2

修复办法

将__unused更改为_unused。

syscall.c:4108:9: error: dereferencing pointer to incomplete type

错误信息

qemu-2.5.0/linux-user/syscall.c:4108:9: error: dereferencing pointer to incomplete type

host->c_iflag =

^

修复办法

#define termios host_termios

改为

#ifdef __ANDROID__

#define host_termios termios

#else

#define termios host_termios

#endif

disas/arm-a64.cc:67: error: undefined reference to '__cxa_end_cleanup'

错误信息

disas/arm-a64.cc:67: error: undefined reference to '__cxa_end_cleanup'

../disas/arm-a64.o(.ARM.extab+0x0): error: undefined reference to '__gxx_personality_v0'

../disas/arm-a64.o:arm-a64.cc:typeinfo for QEMUDisassembler: error: undefined reference to 'vtable for __cxxabiv1::__si_class_type_info'

/home/sowuy/Tools/android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: the vtable symbol may be undefined because the class is missing its key function (see go/missingkeymethod)

/home/sowuy/Tools/android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/list.tcc:106: error: undefined reference to 'std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

/home/sowuy/Tools/android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/stl_list.h:1681: error: undefined reference to 'std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

/home/sowuy/Tools/android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/stl_list.h:1681: error: undefined reference to 'std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

/home/sowuy/Tools/android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/stl_list.h:1681: error: undefined reference to 'std::__detail::_List_node_base::_M_hook(std::__detail::_List_node_base*)'

/home/sowuy/Tools/android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/stl_list.h:1697: error: undefined reference to 'std::__detail::_List_node_base::_M_unhook()'

/home/sowuy/Tools/android-ndk-r11b/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/stl_list.h:1697: error: undefined reference to 'std::__detail::_List_node_base::_M_unhook()'

../disas/libvixl/a64/disasm-a64.o:disasm-a64.cc:typeinfo for vixl::DecoderVisitor: error: undefined reference to 'vtable for __cxxabiv1::__class_type_info'

/home/sowuy/Tools/android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: the vtable symbol may be undefined because the class is missing its key function (see go/missingkeymethod)

../disas/libvixl/a64/disasm-a64.o:disasm-a64.cc:typeinfo for vixl::Disassembler: error: undefined reference to 'vtable for __cxxabiv1::__si_class_type_info'

/home/sowuy/Tools/android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: the vtable symbol may be undefined because the class is missing its key function (see go/missingkeymethod)

../disas/libvixl/a64/disasm-a64.o:disasm-a64.cc:typeinfo for vixl::PrintDisassembler: error: undefined reference to 'vtable for __cxxabiv1::__si_class_type_info'

/home/sowuy/Tools/android-ndk-r11b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.9/../../../../arm-linux-androideabi/bin/ld: the vtable symbol may be undefined because the class is missing its key function (see go/missingkeymethod)

collect2: error: ld returned 1 exit status

make[1]: *** [qemu-arm] Error 1

make: *** [subdir-arm-linux-user] Error 2

解决办法 在configure中找到下面的代码:

arm)

disas_config "ARM"

if test -n "${cxx}"; then

disas_config "ARM_A64"

fi

;;

将这些代码注释掉:

if test -n "${cxx}"; then

disas_config "ARM_A64"

fi

原因分析 目前在Android NDK中没有64位版本的object。

syscall.c中找不到符号

错误信息

LINK arm-linux-user/qemu-arm

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'setdomainname'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmget'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmdt'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmat'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_timedsend'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_unlink'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_open'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_setattr'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_timedreceive'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgsnd'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semget'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semop'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgget'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgrcv'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'stime'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'sigorset'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'vhangup'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'sigtimedwait'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'sethostname'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmget'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmdt'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgget'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semget'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgrcv'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'semop'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgsnd'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'futimesat'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_send'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_receive'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'mq_getattr'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgctl'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmat'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'msgrcv'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmat'

linux-user/syscall.o:syscall.c:function do_syscall: error: undefined reference to 'shmat'

collect2: error: ld returned 1 exit status

make[1]: *** [qemu-arm] Error 1

make: *** [subdir-arm-linux-user] Error 2

解决办法 在syscall.c文件中写下面的内容:

#ifdef __ANDROID__

int setdomainname(const char *name, size_t len) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int shmget(key_t key, size_t size, int shmflg) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int shmdt(const void *shmaddr) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int shmctl(int shmid, int cmd, struct shmid_ds *buf) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

void *shmat(int shmid, const void *shmaddr, int shmflg) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int msgctl(int msqid, int cmd, struct msqid_ds *buf) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int mq_timedsend(unsigned long mqdes, const char *msg_ptr,

size_t msg_len, unsigned msg_prio,

const struct timespec *abs_timeout) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int mq_unlink(const char *name) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

unsigned long mq_open(const char *name, int oflag, mode_t mode,

struct mq_attr *attr) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int mq_setattr(unsigned long mqdes, const struct mq_attr *newattr,

struct mq_attr *oldattr) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

ssize_t mq_timedreceive(unsigned long mqdes, char *msg_ptr,

size_t msg_len, unsigned *msg_prio,

const struct timespec *abs_timeout) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,

int msgflg) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int semget(key_t key, int nsems, int semflg) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int semop(int semid, struct sembuf *sops, size_t nsops) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int msgget(key_t key, int msgflg) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int stime(const time_t *t) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int sigorset(sigset_t * set, const sigset_t * left, const sigset_t * right) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int vhangup(void) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int sigtimedwait(const sigset_t *set, siginfo_t *info,

const struct timespec *timeout) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int sethostname(const char *name, size_t len) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int semctl(int semid, int semnum, int cmd, ...) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int futimesat(int dirfd, const char *pathname,

const struct timeval times[2]) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int mq_send(unsigned long mqdes, const char *msg_ptr,

size_t msg_len, unsigned int msg_prio) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

ssize_t mq_receive(unsigned long mqdes, char *msg_ptr,

size_t msg_len, unsigned int *msg_prio) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

int mq_getattr(unsigned long mqdes, struct mq_attr *attr) {

printf("[-] %s(%d)-%s\n",__FILE__,__LINE__,__FUNCTION__);

assert(0);

}

#endif

编译清理命令

执行下面两个命令:

make clean

make distclean

编译debug版

调用configure脚本的命令行中添加"--enable-debug"命令选项。

android通过c调用shmat函数,编译可在Android上运行的qemu user mode相关推荐

  1. android通过c调用shmat函数,cmake - 尝试在Chipmunk上运行cmake发生错误,如何修复cmake文件? - 堆栈内存溢出...

    所以基本上我正在尝试在Linux Mint上构建Chipmunk物理库,并且它显然有一个cmake文件,我尝试运行该文件,但由于某些错误而未完成,输出为 cmake .. CMake Error at ...

  2. 编译可在Nexus5上运行的CyanogenMod13.0 ROM(基于Android6.0)

    编译可在Nexus5上运行的CyanogenMod13.0 ROM (基于Android6.0) 作者:寻禹@阿里聚安全 前言 下文中无特殊说明时CM代表CyanogenMod的缩写. 下文中说的&q ...

  3. Android之jni调用java函数总结

    1.先看之前jni的如何实现动态注册 先看我之间的例子 http://blog.csdn.net/u011068702/article/details/71375920 Android之JNI动态注册 ...

  4. 编译可在Android上运行的qemu user mode

    前言 本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编译与qemu user mode有关的代码. 下文中的"NDK"若无特殊说明均指"Android ...

  5. android百度地图调用animateto 会报空指针异常,基于Android的百度地图应系统毕业设计.docx...

    基于Android的百度地图应系统毕业设计 分类号: 学校代码:11460 学 号南京晓庄学院本科生毕业设计 基于Android平台和百度地图的应用系统 Application system base ...

  6. Android项目中使用激光推送时在模拟器上运行时报Fatal signal 11的解决

    本人一直用真机调试极光推送,一直没问题,今天准备在模拟器上运行项目看看,刚运行就爆掉了,感觉有些奇怪,遂查日志: 呵呵,致命错误:Fatal signal 11 (SIGSEGV) at 0x0007 ...

  7. VS2017编译可在Win2000上运行的程序

    微软最后一个可以原生编译Win2000应用程序IDE是Visual Studio 2008,后续版本只能支持到WinXP.那么有什么办法让高版本的VS编译出可以在Win2000上运行的程序呢? 首先我 ...

  8. idea运行android usb调试,android-Intellij Idea不允许在真实设备上运行应...

    我拥有配置了Oracle SDK 1.6和Android SDK的Idea 12, $./adb devices List of devices attached S5830c10eb068 devi ...

  9. android x86 oreo,Android-x86 8.1 RC1发布:PC上运行Android Oreo

    IT之家6月19日消息 在PC上运行Android系统的方式很多,但最可靠的还是Android-x86项目,现在其最新版已经发布,基于Android 8.1 Oreo. Android-x86是在PC ...

最新文章

  1. AD633低成本模拟乘法器
  2. 根证书和中间证书的区别
  3. 剖析 Linux hypervisor
  4. java五子棋代码详解_java打卡9.5 用方法封装循环点菜代码 详解
  5. floatingactionbutton 更改背景颜色_经验分享!Word轻松换掉证件照背景颜色
  6. 前端学习(3188):ant-design的icon图标
  7. (图论)51NOD 1264 线段相交
  8. android listview 只加载显示的图片大小,Android ListView只加载当前屏幕内的图片(解决list滑动时加载卡顿)...
  9. Code Snippets for Windows Mobile 5 in C#
  10. CocoaPods管理第三方
  11. matlab无缝拼接两个图_无色差液晶拼接屏研发商参数
  12. python 面积计算器
  13. 华为连接wifi显示wifi未连接服务器,华为手机连接WIFI但是无法上网怎么解决
  14. RuntimeError: Cannot re-initialize CUDA in forked subprocess解决方法之一
  15. Linux已挂载的硬盘无法访问
  16. Google(谷歌)走了我们该用什么呢?
  17. 【解决方案】STM32L152单片机驱动段码LCD屏,执行HAL_LCD_Init函数失败返回HAL_TIMEOUT,长时间卡在LCD_FLAG_RDY的while循环里面的解决办法
  18. android studio 编译Telegram源码
  19. 司马相如和卓文君——野史+臆想
  20. python星号和双星号的区别

热门文章

  1. C#线程使用(二)全面总结
  2. 深度学习在CTR中的应用
  3. 剑指offer 数值的整次方
  4. elasticsearch5.3安装插件head
  5. 风控特征:时间滑窗统计特征体系
  6. 构建并用 TensorFlow Serving 部署 Wide Deep 模型
  7. 并发工具类(四)两个线程进行数据交换的Exchanger
  8. Tensorflow框架初尝试————搭建卷积神经网络做MNIST问题
  9. 熟知的CRM有哪些功能特点?
  10. MySQL 出现 The table is full 的解决方法