【原】Cmake新手使用日記(1)【C++11下的初體驗】

  第一次使用Cmake,搜索了不少使用教程,包括《Cmake實踐》、《Cmake手冊》等,可是在針對最新的C++11條件下編程仍是會存在一點點問題,須要實驗不少次錯誤並搜索大量文章才能解決問題。這裏用新手日記的方式告訴一個Cmake小白如何在C++11下使用Cmake。ios

  通常狀況下,直接閱讀文檔會不太適應新手,沒有感官的認識,沒有經驗。這裏將本身的學習過程記錄下來,方便本身查閱,也方便其餘新手學習。c++

  首先先聲明一下Cmake腳本,其實就是CMakeLists.txt的基本語法規則:編程

  •  變量使用${}方式取值,可是在 IF 控制語句中是直接使用變量名
  •  指令(參數 1 參數 2...) 參數使用括弧括起,參數之間使用空格或分號分開。   
  •  指令是大小寫無關的,參數和變量是大小寫相關的。但,推薦你所有使用大寫指令。

  1、單文件編譯ubuntu

  (1)操做過程學習

  <1>建立一個目錄t1.  ui

  <2>編寫代碼:spa

  main.cppc++11

 1 #include <iostream>
 2 #include <vector>
 3 int main()
 4 {
 5 
 6         using namespace std;
 7         vector<int> V(5,3);
 8         for(auto e:V)
 9                 cout << e << endl;
10         cout << "OK" << endl;
11         return 0;
12 
13 }

  <3>編寫CMakeLists.txtcode

  【注意】不要忘記「CMakeLists.txt」中「.」前還有一個「s」,若是你很粗心,估計會在這裏抓耳撓腮。blog

  

PROJECT (HELLO)
SET(CMAKE_C_COMPILER g++)
if(CMAKE_COMPILER_IS_GNUCXX) add_compile_options(-std=c++11)
  message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)
SET(SRC_LIST main.cpp)
ADD_EXECUTABLE(hello ${SRC_LIST})

  <4>在t1文件夾下編譯

  先運行,注意Cmake後面的小點點「.」表示當前目錄。

  

Cmake .

  再運行

  

make

  <5>運行程序  

  此時,再t1文件夾下會產生hello文件,運行

./hello

程序就正確運行啦。

  輸出

@ubuntu:~/t1$ ./hello
3
3
3
3
3
OK

 

  (2)過程解釋

  首先,在CMakeLists.txt中,命令能夠使用大寫、小寫、混寫。

  PROJECT (HELLO)是CMakeLists.txt的第一句,告訴編譯器這個工程名叫hello。

  SET(CMAKE_C_COMPILER g++)聲明使用g++編譯器,由於若是是.c文件的話一般使用默認的gcc編譯器。

  add_compile_options(-std=c++11)告訴編譯器使用的是c++11,可是若是不設置g++編譯器,又不判斷一下編譯器的話會出現下面的運行結果:

@ubuntu:~/t1$ make
Scanning dependencies of target hello
[ 50%] Building CXX object CMakeFiles/hello.dir/main.o
c++: error: unrecognized command line option ‘-std=C++11’
CMakeFiles/hello.dir/build.make:62: recipe for target 'CMakeFiles/hello.dir/main.o' failed
make[2]: *** [CMakeFiles/hello.dir/main.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/hello.dir/all' failed
make[1]: *** [CMakeFiles/hello.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2

  有的博客裏說可以編譯完成,可是在這裏有時候就完不成。固然有時候也能完成,這個可能和具體的系統有關吧。

  當出現上述問題時,能夠使用設置編譯器的方式解決,也能夠使用if語句進行判斷,這裏爲了可以將全部狀況都講清楚,就暫時畫蛇添足這個寫了。其中CMAKE_COMPILER_IS_GNUCXX用於判斷編譯器類型。

  可是做者也碰到這樣的問題,若是不設置編譯器爲g++,第一次設置編譯器爲std=c++11屬性時報錯,可是一旦設置完成功運行以後,即便吧編譯器設置的語句去掉,把t1下面除了main.cpp和CMakeLists.txt以外的語句去掉,也能正常編譯。真的有些奇怪。

  message(STATUS "optional:-std=c++11")能夠用於打印一些提示信息,這裏在運行完CMake .以後,就把「」中的文字打印出來了。實際上, 除了用STATUS打印普通標識,message還有一些其餘的打印功能,如用SEND_ERROR,產生錯誤信息,生成過程被跳過。若是使用 FATAL_ERROR,當即終止全部 cmake 過程。

  接着SET(SRC_LIST main.cpp) 和ADD_EXECUTABLE(hello ${SRC_LIST}) 語句。定義了這個工程會生成一個文件名爲 hello 的可執行文件,相關的源文件是 SRC_LIST 中 定義的源文件列表, 本例中也能夠直接寫成 ADD_EXECUTABLE(hello main.c)。

  ${}來引用變量,這是 cmake 的變量應用方式,可是,有一些例外,比 如在 IF 控制語句,變量是直接使用變量名引用(如這裏的CMAKE_COMPILER_IS_GNUCXX),而不須要${}。若是使用了${}去應用變量,其實 IF 會去判斷名爲${}所表明的值的變量,那固然是不存在的了。

  (3)一點注意

  在CMakeLists.txt腳本中,設置編譯選項能夠經過add_compile_options命令,也能夠經過set命令修改CMAKE_CXX_FLAGSCMAKE_C_FLAGS。 

  使用這兩種方式在有的狀況下效果是同樣的,但請注意它們仍是有區別的: 
  add_compile_options命令添加的編譯選項是針對全部編譯器的(包括c和c++編譯器),而set命令設置CMAKE_C_FLAGSCMAKE_CXX_FLAGS變量則是分別只針對c和c++編譯器的。所以,下面的代碼也是同樣的效果哦!

PROJECT (HELLO)

SET(CMAKE_C_COMPILER g++)
if(CMAKE_COMPILER_IS_GNUCXX)
   set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
endif(CMAKE_COMPILER_IS_GNUCXX)

SET(SRC_LIST main.cpp)
ADD_EXECUTABLE(hello ${SRC_LIST})
相關文章
相關標籤/搜索