cmake自學

本文的對應代碼可在此處下載
http://download.csdn.net/detail/gh_home/9633641

cmake 命令與visual studio的對應

cmake visual studio
PROJECT(name) 解決方案名稱 name
ADD_EXECUTABLE(name ${SRC_LIST}) 工程名稱 生成exe名稱 name

設置cmake的編譯器

  1. 首先使用 cmake -help獲取cmake支持的編譯器
    這裏寫圖片描述
  2. 運行 cmake -G “Visual Studio 12 2013 Win64” 設定好

外部構建

如果cpp文件和CmakeLists.txt文件在同一文件夾下,在此文件夾下運行

cmake .

這樣所有cmake產生的編譯文件都在此文件夾下,和我們的源文件混在一起,爲了避免這種情況,我們需要在CmakeList文件夾下新建一個build文件夾,進入此文件夾,運行

cmake ..

這樣,所有編譯產生的文件都會在build文件夾下了


正規的源代碼目錄

這裏寫圖片描述

  1. 所有的源代碼文件放入src文件夾
  2. 生成的目標文件exe 放入bin文件夾
  3. 對於工程項目的接口及說明文件放入doc文件夾
  4. 對於項目所調用的外部lib文件放入lib文件夾
  5. 對於項目的功能性描述放入README.md
  6. 對於項目的exe的示例調用寫一個.bat或者.sh文件放出來
  7. 寫明CopyRight文件
  8. 對於項目的構建,文件結構,調用關係放在CmakeLists.txt中,以方便之後調用
  9. 附加: 其實還可以建立一個文件夾爲build用於存放編譯工程產生的中間文件,但是這個文件夾在發佈的時候是要刪除的

關於生成的visual studio項目結構

這裏寫圖片描述

  1. 首先要配置管理器,要求這三個項目都生成
  2. 在我們的executable工程即OPENCV_CMAKE_EXE工程上右鍵,選擇設爲啓動項目,這樣ctr+F5就可以運行我們生成的exe了
  3. 以上三個項目的作用:我們可以通過點擊解決方案OPENCV_CMAKE,查看項目依賴項,會發現:
    • 所有的項目都會依賴於ZERO_CHECK這個項目
    • ALL_BUILD會依賴所有的項目,這是爲了我們在每一個execuable後都會生成一個項目,有時候我們更改了某幾個項目,但是又不方便每次都記住是哪些項目發生了更改,這樣我們就可以直接通過生成ALL_BUILD來更新所有的更改項目以及與更改有關的(附加依賴)的項目

將源碼文件放在src文件夾編譯怎麼做?

首先,所有要編譯的文件夾下都需要有一個CMakeLists.txt,因此我們這裏會寫兩個CMakeLists.txt,一個用於CMake的工程,這個相當於所有cmake編譯的入口,這個CMakeLists的標誌就在於其會出現

PROJECT(NAME)

之後,主CMakeLists會調用各個子文件夾的CMakeLists,這些CMakeLists是怎麼關聯起來的呢?我認爲是通過以主CMakeLists的相對路徑通過ADD_SUBDIRECTORY命令來關聯

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

其中source_dir 爲存放你要加入的CMakeLists的所在文件夾,binary_dir是可選的,這裏指定source_dir 中的CMakeLists 編譯輸出(包含編譯中間結果)路徑爲binary_dir。如果不進行 binary_dir目錄的指定,那麼編譯結果(包括中間結果)都將存放在build/source_dir 目錄(這個目錄跟原有的 source_dir 目錄對應),指定 binary_dir目錄後,相當於在編譯時將 source_dir 重命名爲 binary_dir,所有的中間結果和目標二進制都將存放在 binary_dir目錄。

以上是主CMakeLists中該寫的內容,那麼在source_dir 中用於編譯源代碼的CMakeLists該怎麼寫呢?事實上我們需要將source_dir 中的源代碼編譯成一個lib以便主CMakeLists的PROJECT調用。使用以下命令編譯lib

SET(LIBHELLO_SRC hello.c)
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

這樣,我們就會在source_dir 中得到一個名爲libhello.so的文件,如果我們想指定這個文件的生成位置,可以使用以下命令

SET(LIBRARY_OUTPUT_PATH <路徑>)來指定一個新的位置

如果我們想要使用靜態庫,調用

ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})

將源文件編譯爲靜態庫是不夠的,因爲生成的文件可能與動態庫文件重名,所以要不更改生成靜態庫的名字爲hello_static,或者使用下述命令

ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

SET_TARGET_PROPERTIES,其基本語法是:

SET_TARGET_PROPERTIES(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)

這個函數就是設置一些固有的property,其中還包括改變生成.so的版本號


我們如何調用src下編譯好的lib來生成exe

1. 鏈接頭文件

src文件夾下的.cpp文件和.h文件之間互相關聯也是通過相對路徑的,如果.cpp和.h都在src文件夾下,在.cpp中使用

#include"hello.h"

在cmake中是可以編譯通過的,意味着在搜尋hello.h時,.cpp所在文件夾是默認的搜索路徑
但是如果.h文件在另外一個文件夾,我們就需要增加尋找頭文件的路徑了,通過以下命令

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)

其中[AFTER|BEFORE]缺省,意味着後面添加的路徑追加在已有路徑之前還是之後。
使用示例

INCLUDE_DIRECTORIES(/usr/include/hello)

當然,如果頭文件距離我們的源文件相對路徑不遠,我們也可以通過以下方式,上面那種方式很適合絕對路徑,就是調用一個類似於OPENCV的庫的時候

#include "include/hello.h"

2. 鏈接庫文件

之前我們編譯生成了libhello.so,現在我們要把這個庫鏈入exe文件,我們使用TARGET_LINK_LIBRARIES

TARGET_LINK_LIBRARIES(target library1
<debug | optimized> library2
...)

鏈接動態庫

TARGET_LINK_LIBRARIES(main libhello.so)

鏈接靜態庫

TARGET_LINK_LIBRARIES(main libhello.a)

這裏的目標文件main爲一個可執行文件


下面是一個使用cmake編譯帶有opencv庫的示例
CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
PROJECT(OPENCV_CMAKE)
SET(SRC_LIST main.cpp)
set (OpenCV_DIR D:/OpenCV/opencv2410/opencv/build) #這一句設置了OPENCV的目錄地址
FIND_PACKAGE(OpenCV REQUIRED)
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
ADD_EXECUTABLE(OPENCV_CMAKE_EXE ${SRC_LIST})
TARGET_LINK_LIBRARIES(OPENCV_CMAKE_EXE ${OpenCV_LIBS})

main.cpp

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    cv::Mat image = imread("test.jpg");
    imshow("GH_HOME", image);
    cv::waitKey();
}

編譯結果如下

-- OpenCV ARCH: x64
-- OpenCV RUNTIME: vc12
-- OpenCV STATIC: OFF
-- Found OpenCV 2.4.10 in D:/OpenCV/opencv2410/opencv/build/x64/vc12/lib
-- You might need to add D:\OpenCV\opencv2410\opencv\build\x64\vc12\bin to your PATH to be able to run your applications.
-- Configuring done
-- Generating done
-- Build files have been written to: D:/MyDesign/code/CMake/OpenCVTemp/BUILD

這樣的話直接運行生成的exe會出現確實OpenCV相關的DLL文件,所以設置上可以補充兩點:
1. 在系統的環境變量Path中添加OpenCV的DLL所在目錄
2. 在項目的屬性-調試-環境 中添加OpenCV的DLL所在目錄

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