From: http://thesoftwarerogue.blogspot.com/2010/05/porting-of-libcurl-to-android-os-using.html
Tuesday, May 11, 2010
Porting of cURL to Android OS using NDK
In continuing my journey into Android territory, I decided it would be useful to understand the NDK development kit. Given I want to transfer some files and possibly do a couple of other projects requiring low level work, I selected the cURL kit to port. I've used cURL for a number of projects and it is my hope it runs well under Android. The project, curltest, was run under Android 2.1 but it should work for other versions as well. Given that most Android phones will be getting upgrades rolled out over the next couple of months to version 2.1, seems like a reasonable target. I will be added HTTPS capability as soon as I port openssl, for now, this is strictly unsecured transfers.
I did see some examples of partial porting and even in the curl library source there is an Android.mk which describes how to set it up although not in enough detail. Both work helpful but didn't actually get me to the holy land of a usable test applications. (http://www.mail-archive.com/curl-library@cool.haxx.se/msg03433.html was helpful but didn't work for me.)
I found it worth the exercise of downloading the full android sources and building them. Look at the build process, the bionic library, and well as whats in external. The external directory is where you would add repositories to do things like run configure, etc
You won't actually need Linux since I have included the config file here but in case you want to follow way it was created, I've included it.
Summary of the steps to take for this port:
- Lots of searches and view the current state of curl porting
- Setup source repository (I used Linux, you could try windows using cygwin)
- Create curl_config.h under the full android source tree
- Untar curltest.tar.gz under $NDKROOT or Create NDK JNI App on Windows
- Cross-link or add to eclipse project to build Java front-end
- Unpack cURL into $NDKROOT/apps/curltest/jni/curl
- Copy curltest/jni/curlbuild.h to curltest/jni/curl/include/curl
- Copy curltest/jni/curl_config.h to curltest/jni/curl/lib
- Build and test
Setup source repository on Linux
It's one thing to describe doing X, quite another to actually do it. Anyway, I ended up creating my own android repository to start the process. While I was using Windows 7 for my NDK development, I switched to Linux to create the curl_config.h file needed in the build. What this means it that you run a couple of scripts. First up, repo. Created a directory and cd to it. Download the repo script 'wget https://android.git.kernel.org/repo'. Move repo script to somewhere in your path and issue 'repo init -u git://android.git.kernel.org/platform/manifest.git' then after run 'repo sync'. These two should get you all the goodies. I had some stalls where I had to restart the sync process but after a long while it completed successfully.
Create curl_config.h under the full android source tree
Next, I created a script to call the configure command to generated the curl_config.h. CD to $ANDROID_ROOT/external. Untar curl libraries, I renamed my from curl-7.20.1 to just curl. cURL has an Android.mk inside of it. In the file were some instructions for generating the curl_config.h. I found them helpful as a start but ultimately I had to fiddle with a number of things to get this to actually work. Here is the script I used:
#!/bin/sh
ANDROID_ROOT="$HOME/android_src" && \
TOOLCHAIN_VER="4.4.0" \
PLATFORM_VER="5" \
CROSS_COMPILE=arm-eabi- \
PATH=$ANDROID_ROOT/prebuilt/linux-x86/toolchain/arm-eabi-$TOOLCHAIN_VER/bin:$PATH && \
CPPFLAGS="-I $ANDROID_ROOT/system/core/include -I$ANDROID_ROOT/bionic/libc/include -I$ANDROID_ROOT/ndk/build/platforms/android-5/arch-arm/usr/include -I$ANDROID_ROOT/bionic/libc/kernel/arch-arm -L $ANDROID_ROOT/prebuilt/linux-x86/toolchain/arm-eabi-$TOOLCHAIN_VER/lib/gcc/arm-eabi/$TOOLCHAIN_VER/interwork -L$ANDROID_ROOT/ndk/build/platforms/android-$PLATFORM_VER/arch-arm/usr/lib -L$ANDROID_ROOT/out/target/product/generic/system/lib " \
CFLAGS="-fno-exceptions -Wno-multichar -mthumb -mthumb-interwork -nostdlib -lc -ldl -lm " \
./configure CC=arm-eabi-gcc --host=arm-linux --disable-tftp --disable-sspi --disable-ipv6 --disable-ldaps --disable-ldap --disable-telnet --disable-pop3 --disable-ftp --without-ssl --disable-imap --disable-smtp --disable-pop3 --disable-rtsp --disable-ares --without-ca-bundle --disable-warnings --disable-manual --without-nss --enable-shared --without-zlib --without-random
# openssl/zlib version
#./configure CC=arm-eabi-gcc --host=arm-linux --disable-tftp --disable-sspi --disable-ipv6 --disable-ldaps --disable-ldap --disable-telnet --disable-pop3 --disable-ftp --with-ssl=$ANDROID_ROOT/external/openssl --disable-imap --disable-smtp --disable-pop3 --disable-rtsp --disable-ares --without-ca-bundle --disable-warnings --disable-manual --without-nss --enable-shared --with-zlib=$ANDROID_ROOT/external/zlib --without-random
Run the script in the top curl directory (where configure resides) and it should go through many tests before ultimately creating the lib/curl_config.h file.
Create NDK JNI App on Windows
Untar curltest.tar.gz under $NDKROOT. This has the Java side application already created. Or you can simply create a new Application under Eclipse which will generated the src & res directories that will need to be modified. I'm not going into App generation except that you will target $NDKROOT/apps/curltest/project as your directory tree.
Create library name under $NDKROOT/apps/, I used curltest.
CD to curltest and create the Application.mk file.
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := curltest libcurl
Once that is done, cd to project and create your standard Java AndroidManifest.xml file. If you created an App from Eclipse you'll need to modify this file. Make sure to give it INTERNET permissions. The rest depends on what's in your Java code.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0" package="com.mtterra.curltest">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".curltest"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="5"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Then cd to jni and create the Android.mk file. This is where the one from cURL would go. However, I didn't use it as anything more than a reference.
Now for the actual JNI interfacing. There are lots of complaints here because everything needs to be specified up front and you need different packages for different hardware. Except for some dynamic registration mechanism, I'm not sure you can get away with writing to hardware AND getting independence from it. Actually, I am sure, you can't.
Here is my curltest.c interface:
typedef struct pageInfo_t {
char *data;
int len;
} pageInfo_t;
static size_t
HTTPData(void *buffer, size_t size, size_t nmemb, void *userData) {
int len = size * nmemb;
pageInfo_t *page = (pageInfo_t *)userData;
if (buffer && page->data && (page->len + len < (16 * 1024)) ) { memcpy(&page->data[page->len], buffer, len);
page->len += len;
}
return len;
}
//Interface function that will receive web page from Java
jstring
Java_com_mtterra_curltest_curltest_JNIGetWebpage( JNIEnv* env,
jobject entryObject,
jstring webpageJStr )
{
pageInfo_t page;
CURL *curl;
CURLcode res;
char *buffer;
const jbyte *webpage;
webpage = (*env)->GetStringUTFChars(env, webpageJStr, NULL);
if (webpage == NULL) {
return NULL; /* OutOfMemoryError already thrown */
}
page.data = (char *)malloc(16 * 1024);
page.len = 0;
if (page.data)
memset(page.data, 32, 16 * 1024);
buffer = (char *)malloc(1024);
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, webpage);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HTTPData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &page);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
(*env)->ReleaseStringUTFChars(env, webpageJStr, webpage);
if(res == 0) {
if (buffer) {
page.data[page.len < 256 ? page.len : 256] = '\0'; sprintf(buffer, "pagedata(%d): %s. done.\n", page.len, page.data); return (*env)->NewStringUTF(env, buffer);
}
}
sprintf(buffer, "Result %d", res);
return (*env)->NewStringUTF(env, buffer);
} else {
return (*env)->NewStringUTF(env, "Unable to init cURL");
}
}
Finally, it's time to setup Eclipse to build. There are some assumptions here, like having a functioning Eclipse build environment. In order to get your environment over to Eclipse, you can use File->Import then select 'Existing Projects into Workspace' function.
Unpack cURL into $NDKROOT/apps/curltest/jni/curl. Move the curl_config.h file created above to $NDKROOT/apps/curltest/jni/curl/lib.
Finally, we create the Android.mk file in curltest/jni and build it. The Android.mk use is as follows:
LOCAL_PATH:= $(call my-dir)
CFLAGS := -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 -DHAVE_CONFIG_H
include $(CLEAR_VARS)
include $(LOCAL_PATH)/curl/lib/Makefile.inc
LOCAL_SRC_FILES := $(addprefix curl/lib/,$(CSOURCES))
LOCAL_CFLAGS += $(CFLAGS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/curl/include/
LOCAL_COPY_HEADERS_TO := libcurl
LOCAL_COPY_HEADERS := $(addprefix curl/include/curl/,$(HHEADERS))
LOCAL_MODULE:= libcurl
include $(BUILD_STATIC_LIBRARY)
# Build shared library now
# curltest
include $(CLEAR_VARS)
LOCAL_MODULE := curltest
LOCAL_SRC_FILES := curltest.c
LOCAL_STATIC_LIBRARIES := libcurl
LOCAL_C_INCLUDES += $(LOCAL_PATH)/curl/include
include $(BUILD_SHARED_LIBRARY)
Going back to your $NDKROOT you should be able to build the library with 'make APP=curltest -B V=1'. The -B means rebuilt it all and V=1 makes it verbose.
After this, you should be able to build the application. When I get back to Eclipse I'll hit F5 to refresh the files as a habit although likely not necessary. Another interesting thing is that some people have indicated that you need to do an 'adb push' to the emulator so the library is there. I haven't found this is the case. Basically, if it doesn't find your library the interface name or some other part is broken and you need to find the issue.
相关推荐
curl库源码添加了curl_config.h和mk文件,可以直接跳转到目录使用ndk-build编译出so库.
./configure --prefix=/usr/local/android --host aarch64-linux-android --with-pic --disable-shared make -j4;make install 在wsl下面用ndk20编译的, aarch64-linux-android29-clang++ aarch64-linux-android-...
使用ndk编译android环境下使用的curl、openssl、iconv库 详细使用方法见http://www.soskp.com
ndk https://www.androiddevtools.cn/#
该库是 ,因此您需要在项目中启用它(Android Gradle Plugin 4.1+): android { .. . buildFeatures { .. . prefab true } } 用法 ndk构建 您可以在Android.mk使用curl_static 。 例如,如果您的应用程序...
openssl-curl-android 编译适用于Android的openssl和curl先决条件确保您已安装Android NDK 。 您可能还需要安装autoconf和libtool工具链以及构建基础。下载如果您不想自己编译它们,则可以从下载预编译的静态库。 ...
使用适用于Android的OpenSSL编译的Curl(支持Android L) 支持的架构 手臂 指示 编辑settings.sh并根据您的NDK根路径设置ANDROID_NDK_ROOT_PATH 运行以下命令以编译curl git子模块更新--init ./android_build.sh...
独立的aar module,可以直接引入项目使用,结合app中的封装demo,可以快速集成进入项目中。 更多请见文档: keywords: android curl jni ndk https http openssl http2.0 libnghttp2 nghttp2 关键字:安卓 curl jni ...
由于项目需要在NDK中使用网络开发,对于c语言网络开发来说,libcurl库是个很不错的选择,但android系统中并没有自带该库,所以就得自己移植了。下面是移植步骤:1. 下载curl源码 我这里下载的是curl-7.22.0,源码...
已在Android NDK r21d上测试 ./build_android_openssl.sh -a android-arm64 && ./build_android_openssl.sh -a android-arm && \ ./build_android_curl.sh -a android-arm64 -o ./build/openssl-android-arm64 && \...
libcurl.a静态库(.a文件) android可用,包含(armeabi、x86、arm64-v8a、x86_64) 。基于 curl-7.61.1编译。
android下ndk编译的libcurl库,基于curl-7.78.0编译,包含头文件和.a文件,可以直接引用。
当前最新版 curl 是 7.85.0 包含了openssl 3.0.5 zlib 1.2.12 APP_PLATFORM android-23 包含 armeabi-v7a arm64-v8a x86 x86_64 动态库(so) 与静态库(a) 及头文件 用 android-ndk-r21e 编译
Unity打安卓包 Android 所有错误解决方案大全(几乎囊括所有打包错误 )-附件资源
开源通信库openssl,主要用于安卓的底层通信,支持https
:vertical_traffic_light:先决条件agent_dart/pubspec.yaml中的Flutter版本CMake v3.2.0 或更高版本Xcode (10.12) 或更高版本(在 macOS 或 iOS 上运行)Android NDK版本21.4.7075529 (在 Android 上运行)Rust版本...
Android开发文档,整理中... :hourglass_done: NDK NDK开发,简单的讲解 :cooking: 其他 临时筹用 :page_with_curl: 保卫者 Android改进及加密 :locked_with_key: Uiautomator 自动化测试 初始化文件 发布sh init....
那真是各种坑啊,软链接无法识别,x86和86_64的so文件无法编译出来等等,我折腾了几天还是没有在cygwin中完美编译ijkplayer,今天我用了一下同事的ubuntu的电脑,变异ijkplayer-android真的是很快,很快的。...
JavaMy Build EnvironmentCommonMac OS X 10.10.5Xcode 7.2 (7C68)flex 2.5.35 Apple(flex-31)bison (GNU Bison) 3.0.4ruby -e "$(curl -fsSL )"brew install gitbrew install flexbrew install bisonBuildgit clone ...
Android JNI연동> CMake照片 ndk-build照片 함수> size_t responseWriter(char *,size_t,size_t,std :: string *) :cURL을이용하여http통신후response를받는回调받는 bool isCorrectKeyHash(const char...