注意:1.本文不保證適合所有mac系統環境也必然不適合所有的開源庫編譯。本人mac os x10.7, xcode4.3環境.
2. 本文作者是完全搞不懂./configure CC是什么東東的菜鳥,所以這不過是菜鳥的分享~
補充知識:Shell編程中的“局部變量”和“導出變量”:http://roclinux.cn/?p=1277
-----------------------------------------------我是YD的分割線-------------------------------------------------
目的:編譯出libjpeg.a庫,for"模擬器"and"真機 ios5.1 armv7".
為了這個目的引申出了一個新目標:成功編譯ios-static-libraries里的某庫,然后整理,對比,搞出libjpeg.a庫.
准備材料:
材料1:去http://ijg.org/files/下載jpegsrc.v8d.tar.gz。mac下解壓出文件夾jpeg-8d,把它放到桌面.
材料2:下載http://code.google.com/p/ios-static-libraries/source/checkout的代碼到桌面:
$ cd ~/Desktop
$ sudo hg clone https://code.google.com/p/ios-static-libraries/
hg命令需要去http://mercurial.selenic.com/下載mac10.7版本的Mercurial。
安裝后執行這個命令。然后桌面多了個ios-static-libraries文件夾。
-----------------------------------------------我是YD的分割線-------------------------------------------------
ios-static-libraries里有很多腳本,分別對應與編出各個ios庫,現在我們以能夠成功編譯出其中一個庫為目標。我選擇了c-ares,對應於build-cares.sh.
現在先試着跑一跑build-all.sh:
$ cd ~/Desktop/ios-static-libraries
$ ./build-all.sh
發現錯誤提示大概是說xcode的選擇路徑不對,執行下面這個命令:
$ sudo xcode-select -switch /Applications/Xcode.app
再次嘗試,發現下載下來的c-ares-*.tar.gz根本無法解壓,已損壞。
因為build-cares.sh腳本里的下載路徑不對,版本也不是最新。所以需要修改腳本了。
然后因為build-all.sh是編譯所有庫的,我目前只需要編好c-ares就行了。
於是,我創建了兩個文件_build_all-of-cares.sh(修改自build-all.sh)和_clear-all-of-cares.sh(用於清除編譯后產生的各文件),並且修改了build-cares.sh
然后刪除了其他所有的文件,只需要這三個腳本就夠了。
$ chmod +x *.sh
這三個腳本清單如下(最好大致上把這三個腳本看完):
file:_build_all-of-cares.sh
#!/bin/sh set -e SDK=$1 if [ "${SDK}" == "" ] then AVAIL_SDKS=`xcodebuild -showsdks | grep "iphoneos"` FIRST_SDK=`echo "$AVAIL_SDKS" | head -n1` if [ "$AVAIL_SDKS" == "$FIRST_SDK" ]; then SDK=`echo "$FIRST_SDK" | cut -d\ -f2` echo "No iOS SDK specified. Using the only one available: $SDK" else echo "Please specify an iOS SDK version number from the following possibilities:" echo "$AVAIL_SDKS" exit 1 fi fi # Project version to use to build c-ares (changing this may break the build) export CARES_VERSION="1.8.0" # Platforms to build for (changing this may break the build) PLATFORMS="iPhoneSimulator iPhoneOS-V7" # Build projects DEVELOPER=`xcode-select --print-path` TOPDIR=`pwd` for PLATFORM in ${PLATFORMS} do ROOTDIR="${TOPDIR}/${PLATFORM}-${SDK}" if [ "${PLATFORM}" == "iPhoneOS-V7" ] then PLATFORM="iPhoneOS" ARCH="armv7" elif [ "${PLATFORM}" == "iPhoneOS-V6" ] then PLATFORM="iPhoneOS" ARCH="armv6" else ARCH="i386" fi rm -rf "${ROOTDIR}" mkdir -p "${ROOTDIR}" export DEVELOPER="${DEVELOPER}" export ROOTDIR="${ROOTDIR}" export PLATFORM="${PLATFORM}" export SDK="${SDK}" export ARCH="${ARCH}" echo --------------------------------------------------------- echo now show the environment varlues: echo DEVELOPER=$DEVELOPER echo ROOTDIR=$ROOTDIR echo SDK=$SDK echo ARCH=$ARCH echo CARES_VERSION=$CARES_VERSION echo --------------------- echo PLATFORM=$PLATFORM echo --------------------------------------------------------- # Build c-ares echo now: ./build-cares.sh.... echo --------------------------------------------------------- ./build-cares.sh > "${ROOTDIR}-cares.txt" done
file:_clear-all-of-cares.sh
mv c-ares-*.tar.gz /tmp/ rm -rf c-ares-* rm -rf iPhone* mv /tmp/c-ares-*.tar.gz ./
file:build-cares.sh
#!/bin/sh set -e # Download source if [ ! -e "c-ares-${CARES_VERSION}.tar.gz" ] then echo download from "http://c-ares.haxx.se/download/c-ares-${CARES_VERSION}.tar.gz" curl -O "http://c-ares.haxx.se/download/c-ares-${CARES_VERSION}.tar.gz" fi # Extract source rm -rf "c-ares-${CARES_VERSION}" tar zxf "c-ares-${CARES_VERSION}.tar.gz" # Build pushd "c-ares-${CARES_VERSION}" export DEVROOT="${DEVELOPER}/Platforms/${PLATFORM}.platform/Developer" export SDKROOT="${DEVROOT}/SDKs/${PLATFORM}${SDK}.sdk" export CC=${DEVROOT}/usr/bin/gcc export LD=${DEVROOT}/usr/bin/ld export CPP=${DEVROOT}/usr/bin/cpp export CXX=${DEVROOT}/usr/bin/g++ unset AR unset AS export AR=${DEVROOT}/usr/bin/ar export AS=${DEVROOT}/usr/bin/as export NM=${DEVROOT}/usr/bin/nm export STRIP="${DEVROOT}/usr/bin/strip" export CXXCPP=$DEVROOT/usr/bin/cpp export RANLIB=$DEVROOT/usr/bin/ranlib export LDFLAGS="-arch ${ARCH} -pipe -no-cpp-precomp -isysroot ${SDKROOT} -L${ROOTDIR}/lib" export CFLAGS="-arch ${ARCH} -pipe -no-cpp-precomp -isysroot ${SDKROOT} -I${ROOTDIR}/include" export CXXFLAGS="-arch ${ARCH} -pipe -no-cpp-precomp -isysroot ${SDKROOT} -I${ROOTDIR}/include" echo $SDKROOT if [ "${SDK}" == "3.2" ] then if [ "${PLATFORM}" == "iPhoneSimulator" ] then # Work around linker error "ld: library not found for -lcrt1.10.6.o" on iPhone Simulator 3.2 export LDFLAGS="${LDFLAGS} -mmacosx-version-min=10.5" export CFLAGS="${CFLAGS} -mmacosx-version-min=10.5" export CXXFLAGS="${CXXFLAGS} -mmacosx-version-min=10.5" fi fi echo ${ARCH} ./configure --host=${ARCH}-apple-darwin --prefix=${ROOTDIR} --enable-static make make install popd # Clean up #rm -rf "c-ares-${CARES_VERSION}"
現在跑_build_all-of-cares.sh腳本:
$ ./_build_all-of-cares.sh
過了會兒,成功編譯出了模擬器版本(如果提示curl: (7) Failed to connect to。。。那說明網絡有問題.),在./iPhoneSimulator-5.1目錄里。
但是通過終端上的輸出日志我們發現真機庫編譯失敗了.
根據終端上的報錯理解為:沒有合適的c編譯器(這個翻譯完全是亂談,原諒我).
解決如下, 修改xcode下真機編譯路徑里增加cpp編譯器的軟鏈接:(這里為了成功編譯出真機版本的cares庫而這么做,這樣做缺點是修改了系統文件——可能有隱患——但我目前沒發現;優點是增大日后成功編譯開源庫的機率, 然而如果我們的目的僅僅是編出libjpeg則無需這么干,可以用下面講編譯libjpeg真機版本的方法二。)
$ cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/
$ sudo ln -s 四個../iPhoneSimulator.platform/Developer/usr/bin/cpp cpp
(上面的"四個../"就是說有四個“../",沒引號)再編譯,成功了,真機庫在./iPhoneOS-V7-5.1下。
-----------------------------------------------我是YD的分割線-------------------------------------------------
現在開始 寫出合適的configure參數,來編譯libjpeg:
模擬器版本:
$ cd ~/Desktop/jpeg-8d/
$ ./configure CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/i686-apple-darwin11-llvm-gcc-4.2" CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk" --prefix=/Users/myName/Desktop/jpeg-8d/libs4Simulator --disable-shared
$ make
$ make install
編完后在jpeg-8d/libs4Simulator目錄下。(順便一提:編完后用文本打開jpeg-8d/libjpeg.la會看到產品信息、依賴、以及產品安裝在哪個地方:最后一行。)
-----------------------------------------------我是YD的分割線-------------------------------------------------
真機版本:
$ ./configure CC="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc" CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk -arch armv7" --host=armv7-apple-darwin --prefix=/Users/myName/Desktop/jpeg-8d/libs4armv7 --disable-shared
$ make
$ make install
方法二:(不修改系統文件——其實這個方法更好,上面的方法只是為了兼容別人開源庫寫的腳本,因為xcode4.3就是用的clang)
$ ./configure CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" CFLAGS="-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk -arch armv7" --host=armv7-apple-darwin --prefix=/Users/myName/Desktop/jpeg-8d/libs4armv7 --disable-shared
$ make
$ make install
編完后在jpeg-8d/libs4armv7目錄下。
-----------------------------------------------我是YD的分割線-------------------------------------------------
編后文:
進過論證得出結論:方法二是正宗的。方法一即使得出了.a文件,可能會出問題。法一依賴於增加了iPhoneOS.platform目錄下的cpp文件,這是個c++編譯器,如果用了它編譯c++,得出的.o二進制文件,用到的是i386的匯編指令集,而不是arm架構的匯編指令集(由clang++編譯器),這就亂套了。
所以,還是
$ cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/
$ sudo rm -rf cpp
然后就用法二吧!至於其他的開源庫腳本跑不動了,只能罵一句蘋果太霸道了,用clang++徹底替換了cpp,完全不考慮兼容。
-----------------------------------------------我是YD的分割線-------------------------------------------------
另外,編譯libjpeg for mac版本的話,這樣:
$ cd jpeg-8d
$ ./configure
$ make
$ make install
$ mkdir libs4mac && cd libs4mac && mkdir headers
$ find /usr/local/lib/ -name "libjpeg*" -exec cp '{}' . \;
$ cp \
../jpeglib.h \
../jerror.h \
../jconfig.h \
../jmorecfg.h \
./headers/
-----------------------------------------------我是YD的分割線-------------------------------------------------
隨便調用個函數測一下libjpeg.a:
#import "jpeglib.h"
struct jpeg_common_struct j_common;
JPP(&j_common);
-----------------------------------------------我是YD的分割線-------------------------------------------------
注意事項:
以上操作過程中可能會遇到一些阻礙,請確保一下幾點:
1.本人mac os x10.7, xcode4.3.2
2.xcode4是個bitch,有時候你需要或清空工程,或刪除DerivedData目錄,或重啟xcode4,或svn revert工程。
3.每次編譯jpeg-8d時,最后刪了再重新解壓jpegsrc.v8d.tar.gz,因為編過的會有影響,終端也要重新cd jpeg-8d,因為貌似刪了以后,終端自己定位到回收站的那目錄了.
4.自己找原因,看懂每一步就一定能成功
-----------------------------------------------我是YD的分割線-------------------------------------------------
補充知識點:
$ ./configure 命令是配置如何編譯,包括編譯后安裝到哪里(lib等產品輸出放到哪個目錄)
$ make就是開始編譯了,會產生.la文件,這個文件是個文本,記錄了lib產品的信息,如安裝到哪里。
$ make install就是把編譯好的二進制文件鏈接成點a等產品,放到哪個目錄下
-----------------------------------------------我是YD的分割線-------------------------------------------------
另外,據說這里有個“傻瓜式”的libjpeg庫,無需搞這些configure命令:
https://github.com/dhoerl/libjpeg-turbo-builder