CMakeLists.txt編寫和使用方法

一、使用方法 
一般把CMakeLists.txt文件放在工程目錄下,使用時,先創建一個叫build的文件夾(這個並非必須,只是生成的Makefile等文件放在build裏比較整齊),然後執行下列操作: 
cd build 
cmake .. 
make 
其中cmake .. 在build裏生成Makefile,make應當在有Makefile的目錄下,根據Makefile生成可執行文件。

二、編寫方法

  1. # 聲明要求的cmake最低版本
  2. cmake_minimum_required( VERSION 2.8 )
  3. # 添加c++11標準支持
  4. set( CMAKE_CXX_FLAGS "-std=c++11" )
  5. # 聲明一個cmake工程
  6. project( 工程名 )
  7. MESSAGE(STATUS "Project: SERVER") #打印相關消息消息
  8. # 找到後面需要庫和頭文件的包
  9. find_package(包的名稱及最低版本)
  10. # 例如find_package(OpenCV 2.4.3 REQUIRED)
  11. # 頭文件
  12. include_directories("路徑")
  13. # 例如
  14. #include_directories(
  15. # ${PROJECT_SOURCE_DIR}
  16. # ${PROJECT_SOURCE_DIR}/include
  17. # ${EIGEN3_INCLUDE_DIR}
  18. )
  19. # 設置路徑(下面生成共享庫的路徑)
  20. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
  21. # 即生成的共享庫在工程文件夾下的lib文件夾中
  22. # 創建共享庫(把工程內的cpp文件都創建成共享庫文件,方便通過頭文件來調用)
  23. add_library(${PROJECT_NAME} SHARED
  24. src/cpp文件名
  25. ……
  26. # 這時候只需要cpp,不需要有主函數
  27. # ${PROJECT_NAME}是生成的庫名 表示生成的共享庫文件就叫做 lib工程名.so
  28. # 也可以專門寫cmakelists來編譯一個沒有主函數的程序來生成共享庫,供其它程序使用
  29. # 鏈接庫
  30. # 把剛剛生成的${PROJECT_NAME}庫和所需的其它庫鏈接起來
  31. target_link_libraries(${PROJECT_NAME}
  32. /usr/lib/i386-linux-gnu/libboost_system.so
  33. )
  34. # 編譯主函數,生成可執行文件
  35. # 先設置路徑
  36. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
  37. # 可執行文件生成
  38. add_executable(要生成的可執行文件名 從工程目錄下寫起的主函數文件名)
  39. # 這個可執行文件所需的庫(一般就是剛剛生成的工程的庫咯)
  40. target_link_libraries(可執行文件名 ${PROJECT_NAME})

cmake中一些預定義變量

  • PROJECT_SOURCE_DIR 工程的根目錄
  • PROJECT_BINARY_DIR 運行cmake命令的目錄,通常是${PROJECT_SOURCE_DIR}/build
  • CMAKE_INCLUDE_PATH 環境變量,非cmake變量
  • CMAKE_LIBRARY_PATH 環境變量
  • CMAKE_CURRENT_SOURCE_DIR 當前處理的CMakeLists.txt所在的路徑
  • CMAKE_CURRENT_BINARY_DIR target編譯目錄
    使用ADD_SURDIRECTORY(src bin)可以更改此變量的值
    SET(EXECUTABLE_OUTPUT_PATH <新路徑>)並不會對此變量有影響,只是改變了最終目標文件的存儲路徑
  • CMAKE_CURRENT_LIST_FILE 輸出調用這個變量的CMakeLists.txt的完整路徑
  • CMAKE_CURRENT_LIST_LINE 輸出這個變量所在的行
  • CMAKE_MODULE_PATH 定義自己的cmake模塊所在的路徑
    SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然後可以用INCLUDE命令來調用自己的模塊
  • EXECUTABLE_OUTPUT_PATH 重新定義目標二進制可執行文件的存放位置
  • LIBRARY_OUTPUT_PATH 重新定義目標鏈接庫文件的存放位置
  • PROJECT_NAME 返回通過PROJECT指令定義的項目名稱
  • CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 用來控制IF ELSE語句的書寫方式

 假設當前的項目代碼在src 目錄。 src 下有子目錄:server, utility, lib, bin, build

      server -----  存放項目的主功能類文件

      utility  -----  存放項目要用到相關庫文件,便已成爲庫文件存放到子目錄lib 中

      lib       -----  存放utility 生成的庫

      bin      -----  存放association 生成的二進制文件

      build   -----  編譯目錄,存放編譯生成的中間文件   

      cmake 要求工程主目錄和所有存放源代碼子目錄下都要編寫CMakeLists.txt 文件,注意大小寫(cm 大寫,list中l 大寫且落下s).

      src/CMakeLists.txt 文件如下:

  1. #cmake file for project association #表示註釋
  2. #author:>---double__song
  3. #created:>--2011/03/01
  4. CMAKE_MINIMUM_REQUIRED(VERSION 2.8) #cmake 最低版本要求,低於2.6 構建過程會被終止。
  5. PROJECT(server_project) #定義工程名稱
  6. MESSAGE(STATUS "Project: SERVER") #打印相關消息消息
  7. MESSAGE(STATUS "Project Directory: ${PROJECT_SOURCE_DIR}")
  8. SET(CMAKE_BUILE_TYPE DEBUG) #指定編譯類型
  9. SET(CMAKE_C_FLAGS_DEBUG "-g -Wall") #指定編譯器
  10. ADD_SUBDIRECTORY(utility) #添加子目錄
  11. ADD_SUBDIRECTORY(server)

 

      相關解釋:

      1. CMakeLists.txt 文件中不區分大小寫

      2. PROJECT(project_name)    定義工程名稱

          語法:project(projectname [cxx] [c] [java])

          可以指定工程採用的語言,選項分別表示:C++, C, java, 如不指定默認支持所有語言

      3. MESSAGE(STATUS, "Content")  打印相關消息

          輸出消息,供調試CMakeLists.txt 文件使用。

      4. SET(CMAKE_BUILE_TYPE DEBUG)  設置編譯類型debug 或者release。 debug 版會生成相關調試信息,可以使用GDB 進行 

          調試;release不會生成調試信息。當無法進行調試時查看此處是否設置爲debug.

      5. SET(CMAKE_C_FLAGS_DEBUG "-g -Wall") 設置編譯器的類型

          CMAKE_C_FLAGS_DEBUG            ----  C 編譯器

          CMAKE_CXX_FLAGS_DEBUG        ----  C++ 編譯器

       6. ADD_SUBDIRECTORY(utility) 添加要編譯的子目錄

           爲工程主目錄下的存放源代碼的子目錄使用該命令,各子目錄出現的順序隨意。

       如上便是工程server_project 主目錄src 下的CMakeLists.txt 文件,下一篇我們解釋子目錄utiltiy中的CMakeLists.txt 文件。

 

子目錄utility 下的CMakeLists.txt 文件如下:

  1. #Cmake file for library utility.a
  2. #Author: double__song
  3. #Created: 2011/3/3
  4. SET(SOURCE_FILES #設置變量,表示所有的源文件
  5. ConfigParser.cpp
  6. StrUtility.cpp
  7. )
  8. INCLUDE_DIRECTORIES( #相關頭文件的目錄
  9. /usr/local/include
  10. ${PROJET_SOURCE_DIR}/utility
  11. )
  12. LINK_DIRECTORIES( #相關庫文件的目錄
  13. /usr/local/lib
  14. )
  15. ADD_LIBRARY(association ${SOURCE_FILES}) #生成靜態鏈接庫libassociation.a
  16. TARGET_LINK_LIBRARY(association core) #依賴的庫文件
  17. SET_TARGET_PROPERTIES(utility PROPERTIES #表示生成的執行文件所在路徑
  18. RUNTIME_OUTPUT_DIRECTORY> "${PROJECT_SOURCE_DIR}/lib")

 

    相關解釋:

    1. SET(SOURCE_FILES .....)  

    表示要編譯的源文件,所有的源文件都要羅列到此處。set 設置變量,變量名SOURCE_FILES自定義。

    2. INCLUDE_DIRECTORY(...)  

    include頭文件時搜索的所有目錄

    變量PROJECT_SOURCE_DIR 表示工程所在的路徑,系統默認的變量

    3. LINK_DIRECTORIES(...)

     庫文件存放的目錄,在程序連接庫文件的時候要再這些目錄下尋找對應的庫文件

    4. ADD_LIBRARY(...) 

     表示生成靜態鏈接庫libassociaiton.a,由${PROJECT_SOURCE_DIR}代表的文件生成。

     語法:ADD_LIBRARY(libname [SHARED|STATIC]

     SHARED 表示生成動態庫, STATIC表示生成靜態庫。

    5. TARGET_LINK_LIBRARY(association core) 

     表示庫association 依賴core庫文件

     6. SET_TARGET_PROPERTIES

     設置編譯的庫文件存放的目錄,還可用於其他屬性的設置。如不指定,

     生成的執行文件在當前編譯目錄下的各子目錄下的build目錄下,好拗口!簡單一點:

     如指定在: ./src/lib 下

     不指定在: ./src/build/utility/build 目錄下

     生成的中間文件在./src/build/utilty/build 目錄下,不受該命令額影響

 

     子目錄server 下的CMakeLists.txt 文件:

  1. --------------------------------------------------------------------------------------------
  2. SET(SOURCE_FILES
  3. Gassociation.cpp
  4. ConfigurationHandler.cpp
  5. )
  6. INCLUDE_DIRECTORIES(
  7. /usr/local/include
  8. ${PROJECT_SOURCE_DIR}/utility
  9. ${PROJECT_SOURCE_DIR}/association
  10. )
  11. LINK_LIBRARIES(
  12. /usr/local/lib
  13. ${PROJECT_SOURCE_DIR}/lib
  14. )
  15. ADD_EXECUTABLE(server ${SOURCE_FILES})
  16. TARGET_LINK_LIBRARIES(server
  17. utility
  18. SET_TARGET_PROPERTIES(server PROPERTIES #表示生成的執行文件所在路徑
  19. RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")

     相關解釋:

     1. ADD_EXECUTABLE()     #指定要生成的執行文件的名稱server

      其他用法同utilty/CMakeLists.txt

     2. SET_TARGET_PROPERTIES

      設置生成的執行文件存放的路徑,

      注意:

      執行文件server 依賴的子目錄utility 子目錄生成的靜態庫libutility.a,在指定的時候要寫成:
      TARGET_LINK_LIBRARIES(server   utility)

      而不能寫成:

      TARGET_LINK_LIBRARIES(server   libutility.a)

      否則編譯總會提示找不到libutility庫文件。

      但使用第三方的庫卻要指定成具體的庫名,如:libACE-6.0.0.so

      這一點很詭異,暫時還沒找到原因。

      完成對應的CMakeLists.txt 文件編寫後,便可以進行編譯了。

      編譯:

            進入 ./src/build

            執行cmake ..

            make

 configure --prefix=/:作用:

 

指定安裝路徑
不指定prefix,則可執行文件默認放在/usr /local/bin,庫文件默認放在/usr/local/lib,配置文件默認放在/usr/local/etc。其它的資源文件放在/usr /local/share。你要卸載這個程序,要麼在原來的make目錄下用一次make uninstall(前提是make文件指定過uninstall),要麼去上述目錄裏面把相關的文件一個個手工刪掉。
指定prefix,直接刪掉一個文件夾就夠了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章