Pull to refresh

Самостоятельная сборка cURL для iOS и Android

Reading time 5 min
Views 13K
Добрый день!
Я занимаюсь разработкой приложения под iOS/Android, в котором используется библиотека cURL.
До недавнего времени мы использовали готовую сборку libcurl:
  • для iOS с официального сайта
  • для Android с пространств Интернета

При этом версии библиотеки были разные, а заголовочные файлы одни.
С целью наведения порядка было решено собрать библиотеку самостоятельно.


Предполагается поддержка следующих версий мобильных платформ:
  • iOS5.0 и выше
  • Android4.0 и выше

Сборка под iOS

На странице загрузок cURL имеется ссылка на версию библиотеки для iOS.
Перейдя по ней мы оказываемся на странице, где автор детально описывает как можно собрать cURL для iOS.
Сборка под iOS сводится к простым шагам:
export CC="путь_до_llvm-gcc"
export CFLAGS="-arch armv7 -arch armv7s -pipe -Os -gdwarf-2 -isysroot путь_до_iPhoneOS.sdk"
export LDFLAGS="-arch armv7 -arch armv7s -isysroot путь_до_iPhoneOS.sdk"

curl -O http://curl.haxx.se/download/curl-7.31.0.tar.gz
tar -xzf curl-7.31.0.tar.gz
cd curl-7.31.0

./configure --disable-shared --enable-static --disable-dependency-tracking --host=armv7-apple-darwin
make

Для поддержки HTTPS на iOS достаточно сконфигурировать cURL с ключем --with-darwinssl (только для iOS5 и выше).
Для более ранних версий прийдется использовать OpenSSL.

Сборка под Android

В документации cURL предлагается два способа сборки под Android:
  • используя сценарий Android.mk, но в этом случае прийдется использовать исходники Android;
  • используя «standalone toolchain» из Android NDK.

Собирать под Android было решено вторым способом.
Для этого сначала нужно сгенерировать toolchain, запустив сценарий make-standalone-toolchain.sh
Более подробно об этом можно прочитать в документации Android NDK STANDALONE-TOOLCHAIN.html
В моем случае сборка тулчейна выглядела так (MAC OS X, Android NDK r8e, android-14, gcc4.7):
$NDK_ROOT/build/tools/make-standalone-toolchain.sh \
    --platform=android-14 \
    --install-dir=android-toolchain-gcc4.7 \
    --toolchain=arm-linux-androideabi-4.7 \
    --system=darwin-x86_64

# в переменной NDK_ROOT содержится полный путь до корневой папки Android NDK

В результате будет содан каталог android-toolchain-gcc4.7, содержащий копию sysroot для arm android-14 и toolchain gcc4.7.
Данным тулчейном можно собирать под Android проекты с системой сборки Autotools.
Примерно так будет выглядеть сборка cURL:
$NDK_ROOT/build/tools/make-standalone-toolchain.sh --install-dir=toolchain bla-bla-bla

export PATH=`pwd`/toolchain/bin:$PATH
export CC=arm-linux-androideabi-gcc

curl -O http://curl.haxx.se/download/curl-7.31.0.tar.gz
tar -xzf curl-7.31.0.tar.gz
cd curl-7.31.0

./configure --disable-shared --enable-static --host=arm-linux-androideabi
make

Для поддержки HTTPS прийдется дополнительно собрать из исходников OpenSSL.

Здесь мой скрипт для сборки libcurl под iOS и Android с поддержкой протоколов HTTP, HTTPS (MAC OS X, Xcode 4.6.3, iOS SDK 6.1):
build.sh
#!/bin/bash

mkdir -p include
mkdir -p prebuilt/ios/device
mkdir -p prebuilt/ios/simulator
mkdir -p prebuilt/android/armeabi-v7a

# 0. Make "standalone toolchain" for android
if [ ! -d android-toolchain-gcc4.7 ]
then
	$NDK_ROOT/build/tools/make-standalone-toolchain.sh --platform=android-14 --install-dir=android-toolchain-gcc4.7 --toolchain=arm-linux-androideabi-4.7 --system=darwin-x86_64
fi

# 1. Get sources
LIBCURL_SRC=curl-7.31.0
OPENSSL_SRC=openssl-1.0.1e
LIBCURL_PAGE=http://curl.haxx.se/download
OPENSSL_PAGE=http://www.openssl.org/source
LIBCURL_ROOT=curl
OPENSSL_ROOT=openssl

# param 1: lib name
# param 2: download page
# param 3: symlink to source dir
# exit with status 1 if downloading failed
function download_and_unpack() {
    TARBALL=$1.tar.gz
    echo $TARBALL
    if [ ! -f $TARBALL ]
    then
	curl -O $2/$TARBALL || exit 1
	rm -rf $1
        tar -xzf $TARBALL
        rm $3
        ln -s $1 $3
    fi
}

download_and_unpack $LIBCURL_SRC $LIBCURL_PAGE $LIBCURL_ROOT
download_and_unpack $OPENSSL_SRC $OPENSSL_PAGE $OPENSSL_ROOT

# 2. Build sources
CURL_EXTRA="--enable-ipv6 --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smtp --disable-gopher --disable-sspi --disable-manual"
LIBCURL_BINARY=lib/.libs/libcurl.a
CPU_COUNT=`sysctl -n hw.logicalcpu_max`
export IPHONEOS_DEPLOYMENT_TARGET="5.0"

# 2.1 Build cURL for iOS device (armv7, armv7s)
pushd $LIBCURL_ROOT
export CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/llvm-gcc-4.2"
export CFLAGS="-arch armv7 -arch armv7s -pipe -Os -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk"
export LDFLAGS="-arch armv7 -arch armv7s -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk"
./configure --disable-shared --enable-static --disable-dependency-tracking --host=armv7-apple-darwin --with-darwinssl $CURL_EXTRA || exit 1
make clean && make -j $CPU_COUNT || exit 1
cp -f $LIBCURL_BINARY ../prebuilt/ios/device
popd

# 2.2 Build cURL for iOS simulator (i386)
pushd $LIBCURL_ROOT
export CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2"
export CFLAGS="-arch i386 -pipe -Os -gdwarf-2 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk"
export CPPFLAGS="-D__IPHONE_OS_VERSION_MIN_REQUIRED=${IPHONEOS_DEPLOYMENT_TARGET%%.*}0000"
export LDFLAGS="-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk"
./configure --disable-shared --enable-static --disable-dependency-tracking --host=i386-apple-darwin --with-darwinssl $CURL_EXTRA || exit 1
make clean && make -j $CPU_COUNT || exit 1
cp -f $LIBCURL_BINARY ../prebuilt/ios/simulator
popd

# 2.3.1 Build OpenSSL for Android
pushd $OPENSSL_ROOT
# See 0 above
export PATH=`pwd`/../android-toolchain-gcc4.7/bin:$PATH
export CC=arm-linux-androideabi-gcc
export CXX=arm-linux-androideabi-g++
export AR=arm-linux-androideabi-ar
export RANLIB=arm-linux-androideabi-ranlib
./Configure android-armv7 no-shared || exit 1
make clean && make build_crypto build_ssl -j $CPU_COUNT || exit 1
cp -f libcrypto.a ../prebuilt/android/armeabi-v7a
cp -f libssl.a ../prebuilt/android/armeabi-v7a
popd

# 2.3.2 Build CURL for Android
pushd $LIBCURL_ROOT
OPENSSL=`pwd`/../openssl
export CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
export CPPFLAGS=-DANDROID
export LDFLAGS="-march=armv7-a -Wl,--fix-cortex-a8 -L$OPENSSL"
./configure --disable-shared --enable-static --host=arm-linux-androideabi --with-random=/dev/urandom --with-ssl=$OPENSSL --without-ca-bundle --without-ca-path --with-zlib $CURL_EXTRA || exit 1
make clean && make -j $CPU_COUNT || exit 1
cp -f $LIBCURL_BINARY ../prebuilt/android/armeabi-v7a
popd

# 3 Copy headers
cp -f ./curl/include/curl/*.h ./include


Основные шаги:
  • Сгенерировать Standalone toolchain
  • Скачать и распаковать исходники cURL и OpenSSL
  • Собрать cURL для iOS device (armv7, armv7s)
  • Собрать cURL для iOS simulator (i386)
  • Собрать OpenSSL для Android (armv7)
  • Собрать cURL для Android (armv7)

Собранные библиотеки копируются в директорию prebuilt, заголовочные файлы в include.
Для поддержки более ранних версий Android нужно будет собрать соответствующий standalone toolchain.

Ссылки по теме:
Офциальная документаци по сборке cURL
Инструкция по сборке cURL для iOS
Android NDK Standalone toolchain
Tags:
Hubs:
+1
Comments 6
Comments Comments 6

Articles