使用CMake编译跨平台静态库

 

在开始介绍如何使用CMake编译跨平台的静态库以前,先讲讲我在没有使用CMake以前所趟过的坑。由于不少开源的程序,好比png,都是自带编译脚本的。咱们可使用下列脚原本进行编译:linux

 

. / configure    -- prefix = / xxx / xx -- enable - static = YESandroid

makeios

make installc++

相信手动在类Unix系统上面编译过开源程序的同窗对上面的命令确定很是熟悉。可是,若是不配置编译器和一些编译、连接参数,这样的操做,最后编译出来的静态库只能在本系统上面被连接使用。好比你在mac上面运行上面的命令,编译出来的静态库就只能给mac程序连接使用。若是在Linux上面运行上述命令,则也只能给Linux上面的程序所连接使用。若是咱们想要在Mac上面编译出ios和android的静态库,就必需要用到交叉编译。git

要进行交叉编译,通常来讲要指定目标编译平台的编译器,一般是指定一个CC环境变量,根据编译的是c库仍是c++库,要分别指定C_flags和CXX_flag,固然还须要指定c/c++和系统sdk的头文件包含路径。总之,很是之繁琐,你们能够看一下我以前把png编译到ios和mac上面的静态库所使用的 脚本 。github

为何要使用CMake

为何咱们不使用autoconf?为何咱们不使用QMake,JAM,ANT呢?具体缘由你们能够参考我在本文最后的参考连接里面的《Mastering CMake》一书的第一章。我本身使用CMake的感觉就是:我原来编写bash,配置configure参数,读各个开源库的INSTALL文件(由于不一样库的configure参数有差异),配置各类编译flag,头文件包含等。最后3天时间,折腾了png和jepg两个库的编译。固然,中间我还写了android和linux的编译脚本。而换用CMake之后,我2天时间编译完了Box2D,spine和Chipmunk的编译。而且配置脚本至关简单,添加新的库,基本上只是拷贝脚本,修改一两个参数便可。有了CMake,编译跨平台静态库和生成跨平台可执行程序So Easy!xcode

编写CMakeLists.txt

编写一个静态库的CMake配置文件过程以下:(这里我以Box2D为例)bash

指定头文件和源文件

 

include_directories (app

$ { CMAKE_CURRENT_SOURCE_DIR }iphone

)

file ( GLOB_RECURSE box2d_source _ files "${CMAKE_CURRENT_SOURCE_DIR}/Box2D/*.cpp" )

个人CMakeLists.txt和Box2D的文件结构关系以下图所示:

box2d_cmake

这里的${CMAKE_CURRENT_SOURCE_DIR}表示CMakeLists.txt所在的目录。而GLOB_RECURSE能够递归地去搜索Box2D目录下面全部的.cpp文件来参与静态库的编译。而include_directories和file指令,显而易见,它们是用来指定静态库的头文件和实现文件。

指定库的名字

 

add_library ( Box2D STATIC $ { box2d_source_files } )

这里add_library表示最终编译为一个库,static表示是静态库,若是想编译动态库,能够修改成shared. 至此,一个静态库的配置就完成了。固然,由于这个库没有包括其它外部的头文件,因此会比较简单。但这也远比一个Makefile要简单N倍。

编译linux静态库(含64位和32位)

编译linux的静态库是很是简单的,只须要安装好cmake之后,运行如下命令便可:

 

cmake .

make

注意,若是是64位的系统,那么这样只能生成64位的静态库。想要编译出32位的静态库,则必需要先安装32位系统的编译工具链。

 

sudo apt - get install libx32gcc - 4.8 - dev

sudo apt - get install libc6 - dev - i386

sudo apt - get install lib32stdc ++ 6

sudo apt - get install g ++ - multilib

而后,只须要指定cxx_flags为-m32便可,对应的CMake的写法为:

 

set ( CMAKE_CXX _ FLAGS "${CMAKE_CXX_FLAGS} -m32" )

最后用cmake生成makefile并make便可生成32位的静态库

编译ios静态库

编译ios库,最好先用cmake生成xcode工程。可是cmake默认的写法

 

cmake - GXcode .

只能生成mac平台的xcode工程,而不能生成ios平台的xcode工程。不过咱们能够借助 ios-cmake 开源项目。

下载iOS_32.cmake这个toolchain文件,而后使用下列命令来生成ios工程:

 

cmake - DCMAKE_TOOLCHAIN_FILE = . . / toolchain / iOS_32 . cmake    - DCMAKE_IOS_DEVELOPER_ROOT = / Applications / Xcode . app / Contents / Developer / Platforms / iPhoneOS . platform / Developer /    - GXcode . .

有了ios工程之后,咱们就能够调用xcodebuild来生成静态库了:

 

xcodebuild - project Project . xcodeproj - alltargets - sdk iphonesimulator7 . 1 - configurationRelease

这条命令会生成一个胖包(armv七、armv7s)。可是默认只会生成32位的胖包。所以,我修改了iOS_32.cmake,让它能够生成64位的静态库。这个文件为 iOS_64.cmake .

全部的ios静态库(i386,x86_64,armv7,armv7s,arm64)生成完之后,能够用lipo来生成一个胖包,命令以下:

 

lipo lib / i386 / libBox2D . a lib / x86_64 / libBox2D . a lib / armv7 / libBox2D . a lib / arm64 / libBox2D . a - create - output libBox2D . a

编译mac静态库

这个比较简单,直接Xcode -GXcode,而后用xcodebuild命令便可。

编译Andoird静态库

编译android库咱们一样能够引入一个toolchain文件,这里我是从 android-cmake 里面下载的。

注:这个在$ANDROID_NDK/cmake下找的到

在使用这个toolchain文件以前,咱们先要使用ndk自带的make-standalone-toolchain.sh脚原本生成对应平台的toolchain.这个脚本位于你的NDK的路径下面的buil/tools目录下。

好比要生成arm平台的toolchain,咱们可使用下列命令:

 

sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android- $ ANDROID_API_LEVEL -- install - dir = . / android - toolchain -- system = darwin - x86_64 --ndk - dir = / Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = arm - linux - androideabi - 4.8

这里的$ANDROID_NDK为你的NDK的安装路径。这段命令能够生成arm的toolchain,最终能够编译出armeabi和armeabi-v7a静态库。 若是想生成x86的toolchain,指须要使用下列命令:

 

sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android- $ ANDROID_API_LEVEL -- install - dir = . / android - toolchain - x86 -- system = darwin - x86_64 -- ndk - dir = / Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = x86 - 4.8

最后,咱们要告诉CMake使用外部toolchain文件,可使用参数-DCMAKE_TOOLCHAIN_FILE=xxx。此外,咱们还须要在导出两个环境变量给此toolchain文件:

 

export PATH = $ PATH : . / android - toolchain / bin

export ANDROID_STANDALONE_TOOLCHAIN = . / android - toolchain

cmake - DCMAKE_TOOLCHAIN_FILE = . . / android . toolchain . cmake - DANDROID_ABI ="armeabi" . .

编译Win32,wp8和winrt静态库

这里直接使用cmake-gui生成对应的VS工程,而后再手动编译便可。

关于Box2D完整的跨平台编译脚本能够参考 个人Github

Reference

相关文章
相关标签/搜索