CMake入门(二)
CMake入門(二)
最后更新日期:2014-04-25 by kagula
閱讀前提:《CMake入門(一)》、Linux的基本操作
環境: Windows 8.1 64bit英文版。Visual Studio 203 Update1英文版。CMake 2.8.12.2、 Cent OS 6.5。
?
內容簡單介紹
???????? 介紹在VisualStudio上現有的項目怎樣移植到Linux上。本文通過列出兩個最簡單、也是最經常使用的樣例來介紹Linux下CMake的使用。
?
CentOS 上安裝CMake 2.8.12.2
???????? 盡管在Cent OS 上直接能夠使用“yuminstall cmake”命令來安裝。可是版本號太低,我們須要在www.cmake.org上直接下載最新的CMake源碼來安裝。
從官網下載cmake-2.8.12.2.tar.gz到“/usr/local”路徑下。輸入“tar -zxvf cmake-2.8.12.2.tar.gz”命令在當前位置解壓縮,如今“/usr/local”路徑下新建了“cmake-2.8.12.2”文件夾,進入文件夾。
安裝C語言和C++語言編譯器
#yum install gcc? gcc-c++??
配置
#./configure
編譯與鏈接
#make
安裝
#make install
CMake會把程序安裝到/local/host/bin下
執行以下的命令查看CMake的當前版本號,能夠看到已經是2.8版本號了。
#cmake --version
?
在Linux上使用CMake的第一個樣例
???????? 在VisualStudio上新建項目CMake_Tutorial2,詳細過程例如以下 [Visual Studio]->[Visual C++]->[Win32]->[Win32 Project]打開向導窗體,選擇[Applicationtype]為console application,選擇[Additional options]為Empty project后[Finish]。
???????? 新建Source.cpp源文件清單例如以下:
#include <stdio.h>extern void HelloWorld();int main(int args, wchar_t* argv[]) {HelloWorld();getchar();return 0; }新建MyLib.cpp源文件清單例如以下: #include <iostream>using namespace std;void HelloWorld() { #ifdef WIN32wcout << L"Hello,World From Windows!" << endl; #elsewcout << L"Hello,World From Cent OS!" << endl; #endif }加入CMakeLists.txt文件,源文件內容例如以下:
#設置項目名稱 project(CMake_Tutorial2)#要求CMake的最低版本號為2.8 cmake_minimum_required(VERSION 2.8)#用于將當前文件夾下的全部源文件的名字保存在變量 DIR_SRCS 中 aux_source_directory(. DIR_SRCS)#用于指定從一組源文件 source1 source2 … sourceN(在變量DIR_SRCS中定義) #編譯出一個可運行文件且命名為CMake_Tutorial1 add_executable(CMake_Tutorial2 ${DIR_SRCS})這次須要的三個文件都齊備了。Source.cpp是我們的主文件。MyLib.cpp文件模擬主文件所須要的函數實如今還有一個文件。畢竟再小的項目也非常少僅僅有一個cpp文件組成,CMakeLists.txt文件寫好后是給Cent OS上的CMake工具使用的。
???????? 如今按[F5],程序在Windows上正確運行。
進入項目的目錄中(...\CMake_Tutorial2\CMake_Tutorial2\)我們能夠看到
CMAKE_TUTORIAL2
│? CMakeLists.txt
│? CMake_Tutorial2.vcxproj
│?CMake_Tutorial2.vcxproj.filters
│? CMake_Tutorial2.vcxproj.user
│? MyLib.cpp
│? Source.cpp
│
└─Debug
六個文件一個Debug目錄,當中僅僅有CMakeLists.txt、MyLib.cpp、Source.cpp三個文件才是我們在Linux上編譯出可運行程序所須要的,可是為了方便我們把“CMake_Tutorial2”整個目錄上傳到linux系統上。
???????? [S1]我把文件夾上傳到CentOS操作系統的/home/kagula/Downloads文件夾下,[S2]在控制臺下輸入“cd? CMake_Tutorial2”命令,在當前文件夾我們能夠看到原來在Windows系統下的六個文件和一個Debug文件夾。
????????
基本操作流程為:
[S3]在當前文件夾下使用“mkdir build”命令建立build文件夾。
[S4]“cd build”。
[S5]“cmake ..”命令在當前文件夾(Build文件夾)生成Makefile文件。“..”參數指示CMake工具,CMakeLists.txt文件在父文件夾中。
[S6]輸入“make”命令后,進行編譯鏈接,在當前文件夾生成CMake_Tutorial2可運行程序,
[S7]輸入“./CMake_Tutorial2”,程序執行并輸出“Hello,WorldFrom Cent OS!”字符串。輸入隨意字符后敲回車,程序結束執行。
?
?
在Linux上使用CMake的第二個樣例
這個樣例相對于上面一個
[1]添加了分布在不同文件夾的源文件。
???????? 現實世界中多個C++源文件會分布在不同的文件夾中,這個樣例模擬了這樣的情況。
[2]宏的定義。
???????? 在Win上跑的程序,不一定在Linux上也能順利跑。所以有時候須要在程序中依據_DEBUG宏的定義輸出程序執行狀態。
這里的難點是CMakeLists.txt文件的編輯
在Visual Studio上建立Win32 控制臺項目CMake_Tutorial2_2, 經調試能夠執行后,再把CMake_Tutorial2_2整個project文件夾上傳到Cent OS上。在Cent OS上做測試的時候我把它放在了/home/kagula/Downloads/CMake_Tutorial2_2/中。
源文件文件夾結構例如以下。
CMAKE_TUTORIAL2_2
│?CMakeLists.txt
│?CMake_Tutorial2_2.vcxproj
│?CMake_Tutorial2_2.vcxproj.filters
│
├─Debug
│? │? CMake_Tutorial2_2.log
│? │? FromMyLib1.obj
│? │? FromMyLib2.obj
│? │? Source.obj
│? │? vc120.idb
│? │? vc120.pdb
│? │
│? └─CMake_Tu.3A7B3807.tlog
│?????????cl.command.1.tlog
│?????????CL.read.1.tlog
│?????????CL.write.1.tlog
│?????????CMake_Tutorial2_2.lastbuildstate
│?????????link.command.1.tlog
│?????????link.read.1.tlog
│?????????link.write.1.tlog
│
├─MyLib1
│?????CMakeLists.txt
│?????FromMyLib1.cpp
│?????FromMyLib1.h
│
└─src
???????CMakeLists.txt
???????Source.cpp
能夠看到每一個含源碼的目錄中必須有一個CMakeLists.txt文件。所以這里共同擁有三個CMakeLists.txt文件。
CMakeLists.txt源文件清單
#指定可運行程序輸出路徑為運行cmake時路徑的bin子路徑 #默認是輸出到運行cmake命令時的路徑 SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)#CMake運行時,打印路徑 MESSAGE(${PROJECT_SOURCE_DIR}/MyLib1) #加入頭文件搜索路徑 INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/MyLib1)#加入庫文件搜索路徑 LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lib)#用于將當前文件夾下的全部源文件的名字保存在變量 APP_SRC 中 AUX_SOURCE_DIRECTORY(. APP_SRC)#假設調用"CMake -D DEBUG_MODE=ON .." #則為C++源文件設置_DEBUG宏 IF(DEBUG_MODE)ADD_DEFINITIONS(-D_DEBUG) ENDIF()#用于指定從一組源文件 source1 source2 … sourceN(在變量APP_SRC中定義) #編譯出一個可運行文件且命名為CMake_Tutorial2_2 ADD_EXECUTABLE(CMake_Tutorial2_2 ${APP_SRC})#加入編譯可運行程序所須要的鏈接庫、假設有多個中間用空格隔開 #第一個參數是可運行程序名稱,第二個開始是依賴庫 #在這里依據名字mylib1去尋找libmylib1.a文件(Linux下的C++靜態庫文件) TARGET_LINK_LIBRARIES(CMake_Tutorial2_2 mylib1)如今進入到Cent OS系統下
使用以下的命令
$pwd
顯示當前路徑為“/home/kagula/Downloads/CMake_Tutorial2_2/”
$mkdir build
$cd build
$cmake ..
調用cmake處理上一級文件夾的CMakeLists.txt文件,生成Makefile文件。
$make
當前文件夾會生成lib子文件夾。存放libmylib1.a靜態庫文件。生成bin子文件夾存放CMake_Tutorial2_2可運行文件,進入bin子文件夾可直接運行CMake_Tutorial2_2可運行程序。
?
假設要啟用_DEBUG宏
使用以下的命令取代“cmake? ..”
$cmake -D DEBUG_MODE=on? ..
?
以下給出當前實例用到的三個C++源文件清單
FromMyLIb1.h源代碼清單
#ifndef _FROMMYLIB1_H_ #define _FROMMYLIB1_H_void FromMyLib1Func();#endifFromMyLIb1.cpp源代碼清單
#include "FromMyLib1.h" #include <iostream>using namespace std;void FromMyLib1Func() {wcout << L"The function from MyLib1 directory!" << endl; }Source.cpp源代碼清單
#include <stdio.h> #include <iostream>#ifdef WIN32 #include "..\MyLib1\FromMyLib1.h" #else #include "../MyLib1/FromMyLib1.h" #endifusing namespace std;int main(int argc, wchar_t** argv) { #ifdef _DEBUGwcout << L"App in Debug Mode" << endl; #elsewcout << L"Release Mode" << endl; #endifFromMyLib1Func();getchar();return 0; }假設。改動了項目的源碼
清除生成的2進制代碼
$make clean
又一次編譯
$make
?
?
假設,改動了CMakeLists.txt文件
須要又一次調用cmake命令
?
???????? boost庫含有編寫C++應用程序所須要的非常多基本API。
???????? 下一篇介紹含boost調用的Win32控制臺項目。怎樣借助cmake工具把依賴boost的項目移植到Cent ?OS系統上執行。???
參考資料
[1]《CMake使用入門》
http://jiyeqian.is-programmer.com/2011/7/4/cmake_tutorial.27813.html
[2]《makefile: CMAKE的使用》-介紹CMake使用過程中的常見問題
http://blog.chinaunix.net/uid-23381466-id-3826931.html
總結
以上是生活随笔為你收集整理的CMake入门(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML5——section,artic
- 下一篇: VMI和JIT