編譯iOS上的libevent庫

來源:互聯網
上載者:User

前言:昨天正好在Android上把libevent跑通了,就是用了之前一篇文章中提到的流程方案。今天索性把iOS上的libevent也編譯了下。iOS上的交叉編譯比NDK的要順利許多,大概是找到了對應比較好的文章做參考吧。

準備工作有OS X系統,我這裡裝的是10.8 64-bit。Xcode是4.5.2,對應的SDK版本為6.0下載libevent版本,可是是官方最新的2.0.21或者是git上對應的那個for Android的版本,都可以。git上那份我記得是2.0.20的,差距應該不大。下載openssl庫,目前最新是1.0.1e的版本編譯產生configure檔案如果是官方的2.0.21-stable版本,則檔案中已經有configure檔案產生了,這步驟可以跳過。如果沒有,則執行目錄下的autogen.sh指令碼,產生configure。其間可能需要安裝autoconf、automake和libtool等工具,直接下載對應的源碼,然後編譯安裝即可。至於如何安裝,我給個命令列表,有需要的看下即可:
./configure && makesudo make install

經過以上的步驟,libevent源碼目錄下應該已經有configure等檔案產生了。編輯build_libevent.sh指令碼接下來就是編寫編譯指令碼了,實際上就是使用configure工具,指定對應的組建目錄。這裡可以給一個洋蔥瀏覽器的開源指令碼,很強大,幫你直接在MAC OS X上下載編譯libevent庫。https://github.com/mtigas/iOS-OnionBrowser/blob/master/build-libevent.sh我的配置基本都是抄裡面的,當然,如果直接用也沒什麼問題,他會幫你下載libevent和openssl庫,然後編譯,產生對應的靜態庫檔案。值得一提的是,Mac上可以直接用lipo命令把多份靜態庫整合到一起,比如i386、armv7和armv7s三種CPU架構的靜態庫整合成一份,這實在讓人很興奮。如果Android上也能這麼搞,那該多好,當然我還沒去查閱過資料,不知道linux上是否支援lipo。編譯libevent的庫有個要注意的地方(這個坑了我很久),就是如果需要openssl支援,那要先編譯openssl庫,否則是不會帶libevent_openssl.a這個靜態庫的。下面我索性把那兩個bash指令碼放上來,首先是libevent的

#!/bin/bash#  Builds libevent for all three current iPhone targets: iPhoneSimulator-i386,#  iPhoneOS-armv6, iPhoneOS-armv7.##  Copyright 2012 Mike Tigas <mike@tig.as>##  Based on work by Felix Schulze on 16.12.10.#  Copyright 2010 Felix Schulze. All rights reserved.##  Licensed under the Apache License, Version 2.0 (the "License");#  you may not use this file except in compliance with the License.#  You may obtain a copy of the License at##  http://www.apache.org/licenses/LICENSE-2.0##  Unless required by applicable law or agreed to in writing, software#  distributed under the License is distributed on an "AS IS" BASIS,#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.#  See the License for the specific language governing permissions and#  limitations under the License.#############################################################################  Choose your libevent version and your currently-installed iOS SDK version:#VERSION="2.0.21-stable"SDKVERSION="6.1"############################################################################### Don't change anything under this line!############################################################################# No need to change this since xcode build will only compile in the# necessary bits from the libraries we createARCHS="i386 armv7 armv7s"DEVELOPER=`xcode-select -print-path`cd "`dirname \"$0\"`"REPOROOT=$(pwd)# Where we'll end up storing things in the endOUTPUTDIR="${REPOROOT}/dependencies"mkdir -p ${OUTPUTDIR}/includemkdir -p ${OUTPUTDIR}/libBUILDDIR="${REPOROOT}/build"# where we will keep our sources and build from.SRCDIR="${BUILDDIR}/src"mkdir -p $SRCDIR# where we will store intermediary buildsINTERDIR="${BUILDDIR}/built"mkdir -p $INTERDIR########################################cd $SRCDIR# Exit the script if an error happensset -eif [ ! -e "${SRCDIR}/libevent-${VERSION}.tar.gz" ]; thenecho "Downloading libevent-${VERSION}.tar.gz"    curl -LO https://github.com/downloads/libevent/libevent/libevent-${VERSION}.tar.gzelseecho "Using libevent-${VERSION}.tar.gz"fitar zxf libevent-${VERSION}.tar.gz -C $SRCDIRcd "${SRCDIR}/libevent-${VERSION}"set +e # don't bail out of bash script if ccache doesn't existCCACHE=`which ccache`if [ $? == "0" ]; then    echo "Building with ccache: $CCACHE"    CCACHE="${CCACHE} "else    echo "Building without ccache"    CCACHE=""fiset -e # back to regular "bail out on error" modefor ARCH in ${ARCHS}doif [ "${ARCH}" == "i386" ];thenPLATFORM="iPhoneSimulator"        EXTRA_CONFIG=""elsePLATFORM="iPhoneOS"        EXTRA_CONFIG="--host=arm-apple-darwin11"fimkdir -p "${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk"./configure --disable-shared --enable-static --disable-debug-mode ${EXTRA_CONFIG} \    --prefix="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk" \    CC="${CCACHE}${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer/usr/bin/gcc -arch ${ARCH}" \    LDFLAGS="$LDFLAGS -L${OUTPUTDIR}/lib" \    CFLAGS="$CFLAGS -I${OUTPUTDIR}/include -isysroot ${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDKVERSION}.sdk" \    CPPFLAGS="$CPPFLAGS -I${OUTPUTDIR}/include -isysroot ${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDKVERSION}.sdk"    # Build the application and install it to the fake SDK intermediary dir    # we have set up. Make sure to clean up afterward because we will re-use    # this source tree to cross-compile other targets.make -j4make installmake cleandone########################################echo "Build library..."# These are the libs that comprise libevent. `libevent_openssl` and `libevent_pthreads`# may not be compiled if those dependencies aren't available.OUTPUT_LIBS="libevent.a libevent_core.a libevent_extra.a libevent_openssl.a libevent_pthreads.a"for OUTPUT_LIB in ${OUTPUT_LIBS}; do    INPUT_LIBS=""    for ARCH in ${ARCHS}; do        if [ "${ARCH}" == "i386" ];        then            PLATFORM="iPhoneSimulator"        else            PLATFORM="iPhoneOS"        fi        INPUT_ARCH_LIB="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/lib/${OUTPUT_LIB}"        if [ -e $INPUT_ARCH_LIB ]; then            INPUT_LIBS="${INPUT_LIBS} ${INPUT_ARCH_LIB}"        fi    done    # Combine the three architectures into a universal library.    if [ -n "$INPUT_LIBS"  ]; then        lipo -create $INPUT_LIBS \        -output "${OUTPUTDIR}/lib/${OUTPUT_LIB}"    else        echo "$OUTPUT_LIB does not exist, skipping (are the dependencies installed?)"    fidonefor ARCH in ${ARCHS}; do    if [ "${ARCH}" == "i386" ];    then        PLATFORM="iPhoneSimulator"    else        PLATFORM="iPhoneOS"    fi    cp -R ${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/include/* ${OUTPUTDIR}/include/    if [ $? == "0" ]; then        # We only need to copy the headers over once. (So break out of forloop        # once we get first success.)        break    fidone####################echo "Building done."echo "Cleaning up..."rm -fr ${INTERDIR}rm -fr "${SRCDIR}/libevent-${VERSION}"echo "Done."

這裡要注意的地方有兩個:

  1. 最上面的庫的版本和對應SDK的版本了(執行openssl編譯的時候也一樣),請根據你的需要去設定,特別是SDK的版本,預設這裡是6.1的,我是用Xcode4.5.2,翻看了目錄裡面,只有6.0的SDK,所以這裡要根據你自己的Xcode中SDK的版本設定,否則會找不到編譯器
  2. 設定DEVELOPER變數的地方要注意,我的機器上通過xcode-select -print-path得到的路徑是/Volumne/Xcode.app/Contents/Developer,但其實我是放在案頭的,如果這個目錄不對可能會同樣找不到編譯器,這裡可以寫絕對路徑(不要用相對路徑,會報錯的)
直接在你的目錄下運行這個bash即可。如果沒有openssl的庫,經過上面的編譯,libevent_openssl.a 這個庫是沒有的,在configure過程中就會檢測到openssl無效,Makefile中會把對應的代碼注釋掉。所以如果需要openssl的支援,那就要先運行build_ssl.sh這個指令碼,同樣,注意事項和build_libevent.sh一致。其實這兩個指令碼放到同一個libevent目錄下即可。
#!/bin/bash#  Builds openssl for all three current iPhone targets: iPhoneSimulator-i386,#  iPhoneOS-armv6, iPhoneOS-armv7.##  Copyright 2012 Mike Tigas <mike@tig.as>##  Based on work by Felix Schulze on 16.12.10.#  Copyright 2010 Felix Schulze. All rights reserved.##  Licensed under the Apache License, Version 2.0 (the "License");#  you may not use this file except in compliance with the License.#  You may obtain a copy of the License at##  http://www.apache.org/licenses/LICENSE-2.0##  Unless required by applicable law or agreed to in writing, software#  distributed under the License is distributed on an "AS IS" BASIS,#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.#  See the License for the specific language governing permissions and#  limitations under the License.#############################################################################  Choose your openssl version and your currently-installed iOS SDK version:#VERSION="1.0.1e"SDKVERSION="6.1"############################################################################### Don't change anything under this line!############################################################################# No need to change this since xcode build will only compile in the# necessary bits from the libraries we createARCHS="i386 armv7 armv7s"DEVELOPER=`xcode-select -print-path`cd "`dirname \"$0\"`"REPOROOT=$(pwd)# Where we'll end up storing things in the endOUTPUTDIR="${REPOROOT}/dependencies"mkdir -p ${OUTPUTDIR}/includemkdir -p ${OUTPUTDIR}/libBUILDDIR="${REPOROOT}/build"# where we will keep our sources and build from.SRCDIR="${BUILDDIR}/src"mkdir -p $SRCDIR# where we will store intermediary buildsINTERDIR="${BUILDDIR}/built"mkdir -p $INTERDIR########################################cd $SRCDIR# Exit the script if an error happensset -eif [ ! -e "${SRCDIR}/openssl-${VERSION}.tar.gz" ]; thenecho "Downloading openssl-${VERSION}.tar.gz"    curl -O http://www.openssl.org/source/openssl-${VERSION}.tar.gzelseecho "Using openssl-${VERSION}.tar.gz"fitar zxf openssl-${VERSION}.tar.gz -C $SRCDIRcd "${SRCDIR}/openssl-${VERSION}"set +e # don't bail out of bash script if ccache doesn't existCCACHE=`which ccache`if [ $? == "0" ]; then    echo "Building with ccache: $CCACHE"    CCACHE="${CCACHE} "else    echo "Building without ccache"    CCACHE=""fiset -e # back to regular "bail out on error" modefor ARCH in ${ARCHS}doif [ "${ARCH}" == "i386" ];thenPLATFORM="iPhoneSimulator"elsesed -ie "s!static volatile sig_atomic_t intr_signal;!static volatile intr_signal;!" "crypto/ui/ui_openssl.c"PLATFORM="iPhoneOS"fiecho "Building openssl-${VERSION} for ${PLATFORM} ${SDKVERSION} ${ARCH}"echo "Please stand by..."mkdir -p "${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk"#LOG="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/build-openssl-${VERSION}.log"    export CC="${CCACHE}${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer/usr/bin/gcc -arch ${ARCH}"./configure BSD-generic32 \    --openssldir="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk" #> "${LOG}" 2>&1# add -isysroot to configure-generated CFLAGSsed -ie "s!^CFLAG=!CFLAG=-isysroot ${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer/SDKs/${PLATFORM}${SDKVERSION}.sdk !" "Makefile"    # Build the application and install it to the fake SDK intermediary dir    # we have set up. Make sure to clean up afterward because we will re-use    # this source tree to cross-compile other targets.make #>> "${LOG}" 2>&1make install #>> "${LOG}" 2>&1make clean #>> "${LOG}" 2>&1done########################################echo "Build library..."OUTPUT_LIBS="libssl.a libcrypto.a"for OUTPUT_LIB in ${OUTPUT_LIBS}; do    INPUT_LIBS=""    for ARCH in ${ARCHS}; do        if [ "${ARCH}" == "i386" ];        then            PLATFORM="iPhoneSimulator"        else            PLATFORM="iPhoneOS"        fi        INPUT_ARCH_LIB="${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/lib/${OUTPUT_LIB}"        if [ -e $INPUT_ARCH_LIB ]; then            INPUT_LIBS="${INPUT_LIBS} ${INPUT_ARCH_LIB}"        fi    done    # Combine the three architectures into a universal library.    if [ -n "$INPUT_LIBS"  ]; then        lipo -create $INPUT_LIBS \        -output "${OUTPUTDIR}/lib/${OUTPUT_LIB}"    else        echo "$OUTPUT_LIB does not exist, skipping (are the dependencies installed?)"    fidonefor ARCH in ${ARCHS}; do    if [ "${ARCH}" == "i386" ];    then        PLATFORM="iPhoneSimulator"    else        PLATFORM="iPhoneOS"    fi    cp -R ${INTERDIR}/${PLATFORM}${SDKVERSION}-${ARCH}.sdk/include/* ${OUTPUTDIR}/include/    if [ $? == "0" ]; then        # We only need to copy the headers over once. (So break out of forloop        # once we get first success.)        break    fidoneecho "Building done."echo "Cleaning up..."rm -fr ${INTERDIR}rm -fr "${SRCDIR}/openssl-${VERSION}"echo "Done."

再次感謝洋蔥瀏覽器的作者,好強大的指令碼啊,呵呵。編譯完成後,對應的庫檔案存放在dependencies目錄的lib目錄中,外層的include是對應調用庫時需要用到的標頭檔。好了,iOS上的libevent庫就這樣搞定了。順便丟個編譯好的庫檔案:下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.