欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

解析libcurl在android下的移植、编译与测试

程序员文章站 2023-11-29 22:50:40
由于项目需要在ndk中使用网络开发,对于c语言网络开发来说,libcurl库是个很不错的选择,但android系统中并没有自带该库,所以就得自己移植了。下面是移植步骤:1....

由于项目需要在ndk中使用网络开发,对于c语言网络开发来说,libcurl库是个很不错的选择,但android系统中并没有自带该库,所以就得自己移植了。
下面是移植步骤:
1.  下载curl源码
我这里下载的是curl-7.22.0,源码下载地址为:http://curl.haxx.se/download.html

2. 准备android源码编译环境,
android源码应已全部编译过,具体细节这里不详述,我这里使用的是android2.2 froyo源码树。

3.  在android中编译curl
在最新的curl源码里其实已经带有android.mk这个编译文件了,而且在这文件的开头注释部分比较详细地介绍编译方法。
1)拷贝curl源码至android源码树下的external/curl
2)cd 到 external/curl目录下,输入(红色字部分根据自己的环境做相应的更改):

复制代码 代码如下:

android_home=/home/braincol/workspace/android/froyo && \
ndk_home=/home/braincol/workspace/android/froyo/ndk && \
path="$android_home/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin:$path" \
./configure --host=arm-linux cc=arm-eabi-gcc --with-random=/dev/urandom \
cppflags="-i$ndk_home/platforms/android-8/arch-arm/usr/include \
-i $android_home/external/curl/include/  \
-i $android_home/external/curl/3rd/include   \
-i $android_home/external/curl   \
-i $android_home/out/target/product/generic/obj/static_libraries/libcurl_intermediates   \
-i $android_home/dalvik/libnativehelper/include/nativehelper   \
-i $android_home/system/core/include   \
-i $android_home/hardware/libhardware/include   \
-i $android_home/hardware/libhardware_legacy/include   \
-i $android_home/hardware/ril/include   \
-i $android_home/dalvik/libnativehelper/include   \
-i $android_home/frameworks/base/include   \
-i $android_home/frameworks/base/opengl/include   \
-i $android_home/frameworks/base/native/include   \
-i $android_home/external/skia/include   \
-i $android_home/out/target/product/generic/obj/include   \
-i $android_home/bionic/libc/arch-arm/include   \
-i $android_home/bionic/libc/include   \
-i $android_home/bionic/libstdc++/include   \
-i $android_home/bionic/libc/kernel/common   \
-i $android_home/bionic/libc/kernel/arch-arm   \
-i $android_home/bionic/libm/include   \
-i $android_home/bionic/libm/include/arch/arm   \
-i $android_home/bionic/libthread_db/include \
-include $android_home/system/core/include/arch/linux-arm/androidconfig.h \
-i $android_home/system/core/include/arch/linux-arm/ \
-d__arm_arch_5__ -d__arm_arch_5t__ -d__arm_arch_5e__ -d__arm_arch_5te__ -dandroid -dndebug -dndebug -dhave_config_h" \
cflags="-fno-exceptions -wno-multichar -msoft-float -fpic -ffunction-sections \
-funwind-tables -fstack-protector -wa,--noexecstack -werror=format-security \
-fno-short-enums -march=armv5te -mtune=xscale  -wno-psabi -mthumb-interwork  \
-fmessage-length=0 -w -wall -wno-unused -winit-self -wpointer-arith \
-werror=return-type -werror=non-virtual-dtor -werror=address -werror=sequence-point  \
-g -wstrict-aliasing=2 -finline-functions -fno-inline-functions-called-once \
-fgcse-after-reload -frerun-cse-after-loop -frename-registers  -udebug \
-mthumb -os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64   \
-wpointer-arith -wwrite-strings -wunused -winline -wnested-externs \
-wmissing-declarations -wmissing-prototypes -wno-long-long -wfloat-equal \
-wno-multichar -wsign-compare -wno-format-nonliteral -wendif-labels \
-wstrict-prototypes -wdeclaration-after-statement -wno-system-headers"  \
libs="-nostdlib -bdynamic -wl,-t,$android_home/build/core/armelf.x \
-wl,-dynamic-linker,/system/bin/linker -wl,--gc-sections -wl,-z,nocopyreloc \
-l$android_home/out/target/product/generic/obj/lib -wl,-z,noexecstack \
-wl,-rpath-link=$android_home/out/target/product/generic/obj/lib \
-lc -llog -lcutils -lstdc++ \
-wl,--no-undefined $android_home/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/libgcc.a  \
$android_home/out/target/product/generic/obj/lib/crtend_android.o \
-lm $android_home/out/target/product/generic/obj/lib/crtbegin_dynamic.o \
-l$android_home/external/curl/3rd/libs"

如果$android_home目录下没有ndk的开发包,那么到google的官网上下载一个放进去就行了。

3)cd 到源码根目录 mmm extern/libcurl:
编译完成之后,会生成静态库:out/target/product/generic/obj/static_libraries/libcurl_intermediates/libcurl.a  。

4)如果要生成动态库需要修改curl下的android.mk :
复制代码 代码如下:

local_prelink_module := false
local_module:= libcurl
local_module_tags := optional
# copy the licence to a place where android will find it.
# actually, this doesn't quite work because the build system searches
# for notice files before it gets to this point, so it will only be seen
# on subsequent builds.
all_prebuilt += $(local_path)/notice
$(local_path)/notice: $(local_path)/copying | $(acp)
$(copy-file-to-target)
#include $(build_static_library)
include $(build_shared_library)

4.  在android中测试curl
1)在android froyo源码树中下建立一个mytest目录,该目录下再建立一个curltest目录。
2)在目录curtest下创建curl-test.cpp:
复制代码 代码如下:

#include
 "curl/curl.h"#include
 <stdio.h>;int
main() {     curl
 *curl;     curlcode
 res;     curl_global_init(curl_global_all);     curl
 = curl_easy_init();    if
(curl) {             curl_easy_setopt(curl,
 curlopt_url, "http://www.cnblogs.com/hibraincol/");
        res
 = curl_easy_perform(curl);         if
(0!=res) {                  printf("curl
 error: %d\n",
 res);                 }                 curl_easy_cleanup(curl);   
    } 
     curl_global_cleanup();    return
0;}

3)在目录curtest下创建android.mk:
复制代码 代码如下:

#
 curl test executable#local_path
 := $(call my-dir)include
 $(clear_vars) local_c_includes
 += \    $(local_path)/3rd/include local_src_files:=
 curl-test.cpp #
 no shared libraries.local_shared_libraries
 := #
 no static libraries.local_static_libraries
 := libcurl local_module
 := curl-testinclude
 $(build_executable)

4)把libcurl的头文件拷贝到curtest目录下的3rd/include目录下:
cp -rf out/target/product/generic/obj/include/libcurl/curl  mytest/curltest/3rd/include
5)到android源码树的根目录下:mmm /mytest/curltest/
复制代码 代码如下:

braincol@ubuntu:~/workspace/android/froyo$ mmm mytest/curltest/
============================================
platform_version_codename=rel
platform_version=2.2
target_product=generic
target_build_variant=eng
target_simulator=
target_build_type=release
target_build_apps=
target_arch=arm
host_arch=x86
host_os=linux
host_build_type=release
build_id=master
============================================
make: entering directory `/home/braincol/workspace/android/froyo'
target thumb c++: curl-test <= mytest/curltest/curl-test.cpp
mytest/curltest/curl-test.cpp:2:19: warning: extra tokens at end of #include directive
target executable: curl-test (out/target/product/generic/obj/executables/curl-test_intermediates/linked/curl-test)
target non-prelinked: curl-test (out/target/product/generic/symbols/system/bin/curl-test)
target strip: curl-test (out/target/product/generic/obj/executables/curl-test_intermediates/curl-test)
install: out/target/product/generic/system/bin/curl-test
make: leaving directory `/home/braincol/workspace/android/froyo'

可以看到在out/target/product/generic/system/bin/下生成了curl-test这个测试程序。
6)将curl-test拷贝到真机或者模拟器中运行。
  a.我这里是在android真机的根目录下建立了一个test目录.
  b.然后通过adb push将curl-test拷贝到该目录下,并更改curl-test为可执行权限:chmod 777 curl-test.
  c. adb shell 进入shell控制台,然后cd到test目录下, ./curl-test  执行,可以看到打印出的网页源码,移植成功。
 
这样在之后的android app开发中,如果需要用到libcurl的库,就可以直接out/target/product/generic/obj/include/libcurl/curl里的头文件和out/target/product/generic/obj/static_libraries/libcurl_intermediates/libcurl.a拿到app工程中去用就行了。