在开始介绍如何使用CMake编译跨平台的静态库之前,先讲讲我在没有使用CMake之前所趟过的坑。因为很多开源的程序,比如png,都是自带编译脚本的。我们可以使用下列脚本来进行编译:

 

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

make

make install

相信手动在类Unix系统上面编译过开源程序的同学对上面的命令肯定非常熟悉。但是,如果不配置编译器和一些编译、链接参数,这样的操作,最后编译出来的静态库只能在本系统上面被链接使用。比如你在mac上面运行上面的命令,编译出来的静态库就只能给mac程序链接使用。如果在Linux上面运行上述命令,则也只能给Linux上面的程序所链接使用。如果我们想要在Mac上面编译出ios和android的静态库,就必须要用到交叉编译。

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

为什么要使用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!

编写CMakeLists.txt

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

指定头文件和源文件

 

include_directories (

$ { CMAKE_CURRENT_SOURCE_DIR }

)

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

我的CMakeLists.txt和Box2D的文件结构关系如下图所示:

这里的${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

这条命令会生成一个胖包(armv7、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

使用CMake编译跨平台静态库的更多相关文章

  1. Cmake编译成静态库

    To build OpenCV as static library you need to set BUILD_SHARED_LIBS flag to false/off: cmake -DBUILD ...

  2. opencv+ linux + cmake 生成 opencv静态库

    您可以省去如下步骤,直接下载我编译好的: http://download.csdn.net/detail/u011258240/9710331 一.编译opencv2.4  不带contrib 1. ...

  3. dlib编译成静态库及被其它程序调用

    一.git下载:https://github.com/davisking/dlib 官网:http://dlib.net/ 二.vs中编译成静态库 1.在vs2015中创建静态库工程(vs2015以上 ...

  4. 【转】iOS编译OpenSSL静态库(使用脚本自动编译)

    原文网址:https://www.jianshu.com/p/651513cab181 本篇文章为大家推荐两个脚本,用来iOS系统下编译OpenSSL通用库,如果想了解编译具体过程,请参看<iO ...

  5. 编译skia静态库时,图片解码库无法注册的问题

    转载:http://www.cnblogs.com/imlucky/archive/2012/08/01/2617851.html 今天编译skia库,增加图片解码库时总是无效.按照此博客的方法修改后 ...

  6. C++开发新版本vs使用旧版本vs编译的静态库动态库

    关于vs潜在的升级问题概述 (Visual C++)查看官网的介绍:潜在的升级问题概述 (Visual C++).主要问题: 1. 如果使用 /GL(全程序优化)进行编译,则生成的对象文件只能使用生成 ...

  7. vs2015编译zlib静态库步骤

    ZLIB静态库的编译 下载ZLIB源码 ZLib官网下载或者GitHub上直接 clone 下来即可 www.zlib.net 截至目前最新版本1.2.1.1本 如下图我选择从官网下载 下载完以后解压 ...

  8. 为iOS编译FFmpeg静态库

    为iOS编译FFmpeg静态库 
 环境:OS X Yosemite (版本10.10.5) Xcode (Version 7.1.1 (7B1005)) 
 
 一.资料准备: (1)ffmpeg源 ...

  9. (转)HelloWorld CMake CMake中构建静态库与动态库及其使用

    继续完善Hello World,建立它的共享库, 包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc 向终端输出Hello ...

随机推荐

  1. linux下怎么用tree命令以树形结构显示文件目录结构?

    tree命令以树状图列出文件目录结构.不过某些Linux上(Centos 6.4)没有tree命令,本文将介绍安装方法. 常用参数: ? 1 2 3 4 5 6 tree -d 只显示目录.   tr ...

  2. 每天一个linux命令:pwd命令

    Linux中用 pwd 命令来查看”当前工作目录“的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置. ...

  3. JQuery $.each遍历JSON字符串报Uncaught TypeError:Cannot use 'in' operator to search for

    查看一个简单的jQuery的例子来遍历一个JavaScript数组对象. [js] view plaincopy   var json = [ {"id":"1" ...

  4. vue form表单绑定事件与方法

    使用v-on绑定事件 <button @click="hello">Hello</button><br /> <button @click ...

  5. 安卓开发笔记——Gallery组件+ImageSwitcher组件

    什么是Gallery? Gallery是一个水平的列表选择框,它允许用户通过拖动来查看上一个.下一个列表选项. 下图是今天要实现的最终效果: 利用Gallery组件实现的一个横向显示图像列表,可以通过 ...

  6. SharePoint 2013 页面中window/document.onload/ready 事件不能触发的解决方案

    问题1:在SharePoint 2013页面中使用Javascript 事件window/document.onload/ready时,你会发现处理onload/ready事件的代码根本不能执行. 问 ...

  7. char与TCHAR相互转换(拒绝中文乱码,好用!)

    C++编程中屡屡要遇到宽窄字符转换的问题,尤其是字符串中有中文,稍有不慎就会中文乱码,程序运行出错. 下面为char*.char[]与TCHAR*.TCHAR[]互转的用法,不求花哨,只求好用!请参考 ...

  8. logback.xml常用配置详解

    <?xml version="1.0" encoding="UTF-8"?><configuration debug="false& ...

  9. Cookie 和 Session机制具体解释

    原文地址:http://blog.csdn.net/fangaoxin/article/details/6952954     会话(Session)跟踪是Web程序中经常使用的技术,用来跟踪用户的整 ...

  10. HDOJ 4276 The Ghost Blows Light(树形DP)

    Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The tomb consists of N room ...