固然,最原始的方法是把你的程序编成静态的,即编译时加参数-static便可。但这不符合咱们通常的习惯,也是我没法容忍的。linux
方法仍是有的:android
一、compilec++
arm-unknown-linux-gnueabi-gcc -o hello hello.c -Wl,-dynamic-linker=/data/app/ld-linux.so.3shell
这样,编出来的hello就会使用/data/app/ld-linux.so.3看成动态库加载器app
qj@king:~/test$ readelf -a hello|grep ld-linux
[Requesting program interpreter: /data/app/ld-linux.so.3]this
二、run, 因为Android上并无因此须要咱们本身拷贝ld-linux.so.3上去。google
copy ld-linux.so.3 to /data/app.net
copy libc.so.6 to /data/appip
修改LD_LIBRARY_PATH以把咱们的程序所依赖的其它动态库加入搜索路径,在adb shell下执行:get
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/app
注意,在android下只有data目录是可写的,其它目录都是只读的,因此只能用data目录了。
more info:
-Wl,option
Pass option as an option to the linker. If option contains commas, it is split into
multiple options at the commas. You can use this syntax to pass an argument
to the option. For example, ‘-Wl,-Map,output.map’ passes ‘-Map output.map’
to the linker. When using the GNU linker, you can also get the same effect
with ‘-Wl,-Map=output.map’.
即-dynamic-linker 传递给了linker。注意,上面介绍的两种写法,一种是等号传递;另外一种是逗号传递。效果是同样的。
下面是对链接器ld中参数--dynamic-linker的解释:
#ld --help
-I PROGRAM, --dynamic-linker PROGRAM
Set PROGRAM as the dynamic linker to use
ld-linux.so.三、libc.so.6等是从toolchains下面拷来的。
实际上ld-linux.so.3是指向ld-2.9.so的连接,因此实际上须要把ld-2.9.so拷贝到/data/app目录下,而后作一个连接:
ln -s ld-2.9.so ld-linux.so.3
虽然ld-2.9.so看上去是个动态库,但实际上它是可执行的。加载它会被执行,因此须要给它增长可执行权限,不然执行时会提示说not found 之类的,总之android shell下的这个提示很难让人理解:
chmod 777 ld-2.9.so
chmod 777 ld-linux.so.3
若是你的代码是C++写的,编译须要使用arm-...linux...-g++,并且运行时还须要把libstdc++.so.6拷贝到/data/app目录下去。
另外,还有一个关键点:
必定要把/data/app加入到LD_LIBRARY_PATH环境变量中。
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/app
以上步骤完成后,基本能够保证能成功运行,已经通过了个人屡次验证。
参考资料:https://groups.google.com/forum/?fromgroups=#!topic/android-internals/fHKKNkdPvAU