注意: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