(原)Mac下編譯開源庫libjpeg的ios模擬器版本和真機armv7版本


注意: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.gzmac下解壓出文件夾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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM