【cmake 優點】:
開放源代碼,使用 bsd 許可證釋出。
跨平台,可以生成 native 編譯配置檔案。在 linux/unix 平台可以生成 makefile,在 mac 平台可以生成 xcode,在 windows 平台可以生成 msvc 工程的配置檔案。
能夠管理大型項目。
簡化編譯建構過程和編譯過程,隻需要 cmake + make 就可以。
高效率。
可擴充,可以為 cmake 編寫特定功能的子產品,擴充 cmake 功能。
【如何安裝 cmake】:
1. cmake 的安裝可以使用 autotools 進行安裝,點選cmake-2.8.6.tar.gz連結,可以對軟體進行下
2. 執行 ./configure; make; make install
【cmake的原理】
準備main.cpp檔案
<a href="http://my.oschina.net/moooofly/blog/89722#">?</a>
1
2
3
4
5
6
7
8
9
<code>//main.cpp</code>
<code>#include<cstdio></code>
<code>int</code> <code>main()</code>
<code>{</code>
<code> </code><code>printf</code><code>(</code><code>"hello world from main\n"</code><code>);</code>
<code> </code><code>return</code> <code>0;</code>
<code>}</code>
a.建立 cmakelists.txt(注意:此檔案名大小寫必須如此命名),向該檔案中加入以下幾行(内容中指令的大小寫無所謂):
<code>project (hello)</code>
<code>set(src_list main.cpp)</code>
<code>message(status</code><code>"this is binary dir "</code> <code>${hello_binary_dir})</code>
<code>message(status</code><code>"this is source dir "</code><code>${hello_source_dir})</code>
<code>add_executable(hello ${src_list})</code>
b.運作以下指令(linux下):
<code>$ cmake . (别忘記加上這個點,表示目前目錄)</code>
執行完該指令後執行ls可以看到:
生成了cmakefiles(目錄)、cmakecache.txt、cmake_install.cmake以及makefile檔案。
c.執行make。
這時目前目錄下就會生成可執行檔案:
【例子解釋】:
上面cmakelists.txt的内容重新列出如下:
project指令的文法:
project(projectname [cxx] [c] [java])
該指令用來定義工程名稱和工程支援的語言。這個指令也同時隐式定義了兩個cmake變量:<projectname>_binary_dir以及<projectname>_source_dir。
在該例子中就是hello_binary_dir和hello_source_dir,兩個變量指的都是目前工程的路徑。
set指令的文法:
set(var[value] [cache type docstring [force]])
set指令是用來顯式的定義變量的,我們之前用到的是set(src_list main.cpp),如果有多個源檔案,也可以定義成set(src_list main.cpp t1.cpp t2.cpp)。
message指令的文法是:
message([send_error | status | fatal_error] "message to display" ...)
這個指令用于向終端輸出使用者資訊,包含三種類型:
send_error,産生錯誤,生成過程被跳過。
satus,輸出字首為-的資訊。
fatal_error,立即終止所有cmake過程。
上例使用的是status類型進行資訊輸出,用于顯示由project指令隐式定義的兩個變量hello_binary_dir和hello_source_dir的值。
add_executable(hello ${src_list})
定義了這個,工程會生成一個檔案名為hello的可執行檔案,相關的源檔案是src_list中定義的源檔案清單,本例中你可以直接寫成add_executable(hello main.c)。
本例cmakelists.txt的最簡化形式:
<code>project(hello)</code>
<code>add_executable(hello main.c)</code>
=== 我是分割線 ===
下面我們介紹一個比較實用的例子,既包含生成靜态庫又包含引入外部頭檔案和連結庫的cmake demo。
先按照工程規範建立工程目錄并編寫代碼,以下面的工程目錄為例進行解釋這個例子,工程的目錄結構為:
編譯工程要實作的目标:
添加子目錄doc,用以放置這個工程的文檔hello.txt。
生成hello的靜态庫,并在main可執行程式連結hello靜态庫。
在這個工程中添加copyright和readme檔案。
在工程目錄中添加一個run.sh的腳本,用以調用生成的二進制可執行檔案。
将生成的二進制檔案生成到bin子目錄中。
編寫安裝程式。
1. 編寫cmakelists.txt
由于一個工程目錄中包含多個項目,其中在此項目中包含util項目和main項目,其中util項目是用以生成main程式需要的靜态庫,main是用以生成可執行檔案。
在整個工程項目的根目錄下的cmakelists.txt是用來定義工程需要的cmake設定以及子目錄src,用以遞歸調用src中的makelists.txt。該cmakelists.txt的内容定義如下:
<code>add_subdirectory(src)</code>
目錄src中的cmakelists.txt用以定義src目錄下包含的兩個工程(main和util)的依賴關系。
目錄util裡面的cmakelists.txt是用以定義生成util靜态庫的規則,其中内容如下:
<code>set(library_output_path ${hello_source_dir}</code><code>/lib</code><code>)</code>
<code>set(cmake_c_compiler g++)</code>
<code>set(src_list hello.c)</code>
<code>include_directories(${hello_source_dir}</code><code>/include</code><code>)</code>
<code>add_library(util static ${src_list})</code>
set(library_output_path ${hello_source_dir}/lib) -- 定義了庫生成的路徑,内部變量library_output_path用于存放庫的生成路徑。
set(cmake_c_compiler g++) -- 定義c的編譯器為g++,防止出現c和c++代碼在不指定c編譯器的情況下預設使用gcc,導緻系統編譯混亂。
set(src_list hello.c) -- 定義庫檔案需要的源檔案。
include_directories(${hello_source_dir}/include) -- 定義非标準庫頭檔案要搜尋的路徑。
其中include_directories指令的格式為:
include_directories([after|before] [system] dir1 dir2 ...)
add_library(util static ${src_list}) -- 定義生成庫的名字、類型和庫所需要的源檔案,
其中add_library指令格式為:
add_library(libname [shared|static|module] [exclude_from_all]
source1 source2 ... sourcen)
目錄main裡面的cmakelists.txt是用來定義可執行程式編譯和連結時所需要的一些指令或環境。内容如下:
<code>set(executable_output_path ${hello_source_dir}</code><code>/bin</code><code>)</code>
<code>link_directories(${hello_source_dir}</code><code>/lib</code><code>)</code>
<code>target_link_libraries(hello util)</code>
include_directories(${hello_source_dir}/include) -- 定義工程引用的include檔案夾位置,其中存放使用到的庫的頭檔案。
link_directories(${hello_source_dir}/lib) -- 定義工程引用的庫檔案位置,其中存放着庫檔案。
add_executable(hello ${src_list}) -- 定義生成的可執行檔案。
target_link_libraries(hello util) -- 用以定義連結時需要的庫檔案。
2.在工程目錄下建立build目錄,并采用out-of-source方式編譯項目。執行指令
<code>$ cmake ..</code>
執行結果如下
執行tree指令,這時在build目錄下生成了中間編譯檔案:
<code>$ tree .</code>
執行make指令,結果如下:
可以看到工程建立和編譯成功了。
3. 安裝
在工程目錄下添加copyright、readme和run.sh,重新編輯工程目錄下的cmakelists.txt。在cmakelists.txt中添加如下指令:
<code>install(files copyright readme destination share</code><code>/doc/cmake_demo</code><code>)</code>
<code>install(programs run.sh destination bin)</code>
<code>install(programs bin</code><code>/hello</code> <code>destination bin)</code>
<code>install(directory doc/ destination share</code><code>/doc/cmake_demo</code><code>)</code>
這些指令表示在執行make install指令時,安裝程式會拷貝相應的檔案、目錄或程式到指定的字首開始的目錄中,cmake執行指令如下:
<code>cmake -dcmake_install_prefix=~</code><code>/data/cmake_demo</code> <code>..</code>
這時将工程目錄安裝到~/data/cmake_demo目錄下。執行結果如下:
其中cmake編譯c、c++工程完畢。