(原)Mac下编译开源库libjpeg的ios模拟器版本和真机armv7版本

时间:2022-03-16 04:02:20

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