使用cmake构建跨平台工程想知道的那些事

来源:互联网 发布:2016中国经济数据公布 编辑:程序博客网 时间:2024/05/16 14:04
   从2015年5月开始,代码大部分是用在windows下,当需要linux、android、ios等平台下时,需要写繁琐的Makefile文件,对于不是很熟悉Makefile语法格式的人,写Makefile文件是很费力的。从那时开始,决定采用一个跨平台的工具来构建代码,减少多平台工作需要所增加的工作量。经过比较感觉cmake这个开源工具非常满足我们的需要,从而开始了cmake的应用。   工欲善其事必先利其器,cmake 就是我们构建跨平台工程的有效利器,其可以很大成程度上减轻我们代码移植的工作量。对于程序员来接触一个新东西的时候,往往首先需要了解它的语法,而cmake的语法非常简单,可以从其官网下载它的语法说明和简单的例程,我想任何一个东西的学习其最好方式就是实践。对cmake的语法及使用有了初步的了解后,可以通过构建自己的跨平台工程来逐步熟悉cmake的使用。   下面记录下在使用cmake 过程中自己所遇到的一些问题,方便以后自己查阅。   1、目录的相对关系   cmake 用两种编译方式即in source编译 和out of source编译,通常我选择out of source编译   即单独建立一个文件加存放工程文件和源文件分开。文件的目录可以以PROJECT_SOURCE_DIR 目录为基础,PROJECT_SOURCE_DIR为顶层cmake文件所在的目录,其他文件可以根据PROJECT_SOURCE_DIR的相对目录进行设定和查找。   2、平台的判断   有windows平台、linux平台、android平台怎么区分呢,cmake中有变量来识别这些平台。例如可以通过如下方式判断   if(WIN32 AND NOT MINGW)      message("WIN32 编译设置")   elseif(WIN32 AND MINGW)     message("MINGW 编译设置")   elseif(UNIX AND NOT ANDROID)     message("UNIX 编译设置")   elseif(ANDROID)    message("ANDROID 编译设置")   endif()

还可以通过其他变量进行更精细的控制选择,所以对于平台的选择还是很方便的
3、编译器的设置
可以通过如下两个变量指定要使用的编译器
CMAKE_C_COMPILER:指定C编译器
CMAKE_CXX_COMPILER:指定C++编译器
4、怎么判断64位平台和32位平台
CMAKE_SIZEOF_VOID_P 表示 void* 的大小(例如为 4 或者 8),可以使用其来判断当前构建为 32 位还是 64 位
5、添加依赖项
定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。
ADD_DEPENDENCIES(target-name depend-target1 depend-target2 …)
6、怎么通过命令行批处理生成多个版本的库文件
REM 当前SVN工程的本地目录, TODO: 按需设置
SET SVN_PROJECT_PATH=./

REM VC安装目录, TODO: 按需设置
SET VC_ROOT_08=”F:\Program Files (x86)\Microsoft Visual Studio 9.0”
SET VC_ROOT_10=”F:\Program Files (x86)\Microsoft Visual Studio 10.0”
SET VC_ROOT_13=”F:\Program Files (x86)\Microsoft Visual Studio 12.0”

REM CMake安装目录, TODO: 按需设置
SET CMAKE_ROOT=”F:\Program Files (x86)\CMake\bin”
SET PATH=”%CMAKE_ROOT%”;%PATH%

REM SVN 安装目录 TODO: 按需设置
SET SVN_ROOT=”F:\Program Files\TortoiseSVN\bin”

REM Update from SVN
%SVN_ROOT%\TortoiseProc.exe /command:update /path:”%SVN_PROJECT_PATH%” /closeonend:0

REM AutoVersion %SVN_PROJECT_PATH% version_files/
%SVN_ROOT%\subwcrev.exe %SVN_PROJECT_PATH% version_files/version.template version_files/version.ver

REM 编译08 Win64版本
mkdir build_vs08_64 & cd build_vs08_64
CALL %VC_ROOT_08%\VC\vcvarsall.bat x64
%CMAKE_ROOT%\cmake.exe .. -DCMAKE_BUILD_TYPE=Release -G”NMake Makefiles”
nmake clean & nmake
lib /OUT:THIDFaceHelper_static.lib THIDFaceHelper_static.lib G:\Work\UniversalSDK\sdk_src\license\lib\x64\Release\THIDLicenseLib.lib G:\Work\UniversalSDK\sdk_src\license\3rdparty\openssl_install\lib\x64\windows\libeay32.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x64\ET199_64S.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x64\Release\ETKeyCheckLib.lib
copy /Y *.lib ..\lib\x64\windows\VC08
copy /Y *.dll ..\lib\x64\windows\VC08
cd ..

REM 编译08 Win32版本
mkdir build_vs08_32 & cd build_vs08_32
CALL %VC_ROOT_08%\VC\vcvarsall.bat x86
%CMAKE_ROOT%\cmake.exe .. -DCMAKE_BUILD_TYPE=Release -G”NMake Makefiles”
nmake clean & nmake
lib /OUT:THIDFaceHelper_static.lib THIDFaceHelper_static.lib G:\Work\UniversalSDK\sdk_src\license\lib\x32\Release\THIDLicenseLib.lib G:\Work\UniversalSDK\sdk_src\license\3rdparty\openssl_install\lib\x32\windows\libeay32.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x86\ET199_32S.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x86\Release\ETKeyCheckLib.lib
copy /Y *.lib ..\lib\x32\windows\VC08
copy /Y *.dll ..\lib\x32\windows\VC08
cd ..

REM 编译10 Win64版本
mkdir build_vs10_64 & cd build_vs10_64
CALL %VC_ROOT_10%\VC\vcvarsall.bat x64
%CMAKE_ROOT%\cmake.exe .. -DCMAKE_BUILD_TYPE=Release -G”NMake Makefiles”
nmake clean & nmake
lib /OUT:THIDFaceHelper_static.lib THIDFaceHelper_static.lib G:\Work\UniversalSDK\sdk_src\license\lib\x64\Release\THIDLicenseLib.lib G:\Work\UniversalSDK\sdk_src\license\3rdparty\openssl_install\lib\x64\windows\libeay32.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x64\ET199_64S.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x64\Release\ETKeyCheckLib.lib
copy /Y *.lib ..\lib\x64\windows\VC10
copy /Y *.dll ..\lib\x64\windows\VC10
cd ..

REM 编译10 Win32版本
mkdir build_vs10_32 & cd build_vs10_32
CALL %VC_ROOT_10%\VC\vcvarsall.bat x86
%CMAKE_ROOT%\cmake.exe .. -DCMAKE_BUILD_TYPE=Release -G”NMake Makefiles”
nmake clean & nmake
lib /OUT:THIDFaceHelper_static.lib THIDFaceHelper_static.lib G:\Work\UniversalSDK\sdk_src\license\lib\x32\Release\THIDLicenseLib.lib G:\Work\UniversalSDK\sdk_src\license\3rdparty\openssl_install\lib\x32\windows\libeay32.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x86\ET199_32S.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x86\Release\ETKeyCheckLib.lib
copy /Y *.lib ..\lib\x32\windows\VC10
copy /Y *.dll ..\lib\x32\windows\VC10
cd ..

REM 编译13 Win32版本
mkdir build_vs13_32 & cd build_vs13_32
CALL %VC_ROOT_13%\VC\vcvarsall.bat x86
%CMAKE_ROOT%\cmake.exe .. -DCMAKE_BUILD_TYPE=Release -D_MSC_VER=1800 -G”NMake Makefiles”
nmake clean & nmake
lib /OUT:THIDFaceHelper_static.lib THIDFaceHelper_static.lib G:\Work\UniversalSDK\sdk_src\license\lib\x32\VC13_32\THIDLicenseLib.lib G:\Work\UniversalSDK\sdk_src\license\3rdparty\openssl_install\lib\x32\windows\libeay32.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x86\ET199_32S.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x86\Release\ETKeyCheckLib.lib
copy /Y *.lib ..\lib\x32\windows\VC13
copy /Y *.dll ..\lib\x32\windows\VC13
cd ..

REM 编译13 Win64版本
mkdir build_vs13_64 & cd build_vs13_64
CALL %VC_ROOT_13%\VC\vcvarsall.bat x64
%CMAKE_ROOT%\cmake.exe .. -DCMAKE_BUILD_TYPE=Release -G”NMake Makefiles”
nmake clean & nmake
lib /OUT:THIDFaceHelper_static.lib THIDFaceHelper_static.lib G:\Work\UniversalSDK\sdk_src\license\lib\x64\VC13_64\THIDLicenseLib.lib G:\Work\UniversalSDK\sdk_src\license\3rdparty\openssl_install\lib\x64\windows\libeay32.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x64\ET199_64S.lib G:\Work\UniversalSDK\sdk_src\common\libs\windows\ET199Keylib\x64\Release\ETKeyCheckLib.lib
copy /Y *.lib ..\lib\x64\windows\VC13
copy /Y *.dll ..\lib\x64\windows\VC13
cd ..
7、怎么使用cmake构建android的库,这个可以采用Google的一个android脚本android.toolchain.cmake 可以在网上搜索一下,生成android的so及静态库还是很方便的
8、cmake中一些源文件中或这变量里移除某一项
list(REMOVE_ITEM [ …])
9、怎么使用用cmake构建生成的第三方库,以opencv为例

A:如果第三方库支持CMake方式,只需添加以下命令:
#引用第三方库,例如OpenCV,可以手工选择目录
find_package( OpenCV REQUIRED )
target_link_libraries( MyOpenCVTest ${OpenCV_LIBS} )
如果想要静态链接OpenCV,可以在find_package前面关闭OpenCV_SHARED等变量: set(OpenCV_SHARED OFF)
注意:在Linux上静态库会存在链接顺序的限制,容易出问题。建议使用

10、vs版本的控制可以采用如下变量
if(MSVC_VERSION EQUAL 1800)
link_directories(“PROJECTSOURCEDIR/../../license/lib/x64/VC1364/)else()linkdirectories({PROJECT_SOURCE_DIR}/../../license/lib/x64/Release/”)
endif(MSVC_VERSION EQUAL 1800)
这样就可以控制vs的版本使用的库或者生成的库等版本啦,尤其是容易出问题的静态库。
总之我相信,在使用过程中会有各种需求,这些问题仅仅是我遇到的一部分问题,如果碰到不好解决的需要可以参考opencv、现在的深度学习框架caffe 等用cmake构建的比较大的开源库,可能能找到我们所需要的。

1 0
原创粉丝点击