使用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

相關文章
相關標籤/搜索