首頁 > 軟體

CMake基礎入門和使用

2020-06-16 16:45:49

1.CMake是什麼?
參照百度的話就是CMake是一個跨平台的安裝(編譯)工具,可以用簡單的語句來描述所有平台的安裝(編譯過程)。他能夠輸出各種各樣的makefile或者project檔案,簡單的說它就是一個可以用根據不同平台生成對應的編譯指令碼的工具。

2.CMake怎麼用?
CMake工具使用一個名為CMakeLists.txt 的檔案來描述構建過程,可以產生標準的構建檔案,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。檔案 CMakeLists.txt 需要手工編寫,也可以通過編寫指令碼進行半自動的生成。CMake 提供了比 autoconfig 更簡潔的語法。在 linux 平台下使用 CMake 生成 Makefile 並編譯的流程如下:
1)編寫 CmakeLists.txt。
2)執行命令“cmake PATH”或者“ccmake PATH”生成 Makefile ( PATH 是 CMakeLists.txt 所在的目錄 )。
3)使用 make 命令進行編譯。

3.CMake具體使用範例
 寫到這,一道閃光,自己沉睡的記憶被喚醒了,欣慰啊,想起自己在安裝opencv的時候用過CMake, 具體就以安裝opencv為例。
1)從官網下載最新opencv原始碼
2)tar解壓opencv
3)

cd ~/opencv-x.x.x
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install

下面在opencv測試用例中繼續使用CMake生成相應的Makefile並驗證opencv安裝成功。
1) 建立工作目錄
mkdir ~/opencv-lena
cd ~/opencv-lena
vim DisplayImage.cpp

2) 拷貝如下程式碼到cpp中
include <stdio.h>
include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv )
{
    if ( argc != 2 )
    {
        printf("usage: DisplayImage.out <Image_Path>n");
        return -1;
    }
    Mat image;
    image = imread( argv[1], 1 );
    if ( !image.data )
    {
        printf("No image data n");
        return -1;
    }
    namedWindow("Display Image", WINDOW_AUTOSIZE );
    imshow("Display Image", image);
    waitKey(0);
    return 0;
}

3) 建立CMake編譯檔案
vim CMakeLists.txt
寫入如下內容
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

4) 編譯
cd ~/opencv-lena
cmake .
make

5) 執行
此時opencv-lena資料夾中已經產生了可執行檔案DisplayImage,下載lena.jpg放在opencv-lena下,執行./DisplayImage lena.jpg即可看到顯示出lena的照片。

CMake使用過程中最核心的東西就是如何編寫CMakeLists.txt,下面再具體分析CMakeLists.txt各種語法及語意。

單個原始檔目錄時編寫CMakeLists.txt的方法

如果要系統學習CMake,最好還是參照官方文件,講的很詳細麵麵俱到,https://cmake.org/Wiki/CMake,因為我是在一個專案中用到CMake,所以最主要還是想快速學習如何編寫CMakeList.txt以及一些具體命令的含義.
CMakeList.txt的語法比較簡單,由命令、注釋和空格組成,其中命令是不區分大小寫的,符號”#”後面的內容被認為是注釋。命令由命令名稱、小括號和引數組成,引數之間使用空格進行間隔。例如上節的例子:
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )

第一行代表CMake解析該指令碼所要求的最低版本
第二行代表該專案名稱
第三行find_package代表首先在預設Modules目錄下搜尋所有名為FindOpenCV.cmake的檔案,如果這個檔案未找到,它將會查詢 OpenCVConfig.cmake 或 OpenCV-config.cmake 檔案。這兩個檔案是庫檔案安裝時自己安裝的,將自己的路徑寫死到其中。在我的專案中,OpenCVConfig.cmake 在/usr/share/OpenCV下,前種查詢成為module模式,後者查詢成為config模式,REQUIRED選項表示如果報沒有找到的話,cmake的過程會終止,並輸出警告資訊。
第四行代表要生成的可執行檔名以及需要編譯的檔案
第五行代表可執行檔案需要連結相關的庫檔案。
-
多個原始檔目錄時編寫CMakeLists.txt的方法

上面的例子由於只有一個原始檔,所以比較簡單,下面介紹下多個原始檔目錄時編寫CMakeLists.txt的方法

多個原始檔目錄

在專案根目錄下建立一個CMakelists.txt檔案,內容如下:
cmake_minimum_required(VERSION 2.8)
project( face_detection )
find_package( OpenCV REQUIRED )
message(STATUS "INC ${OpenCV_INCLUDE_DIRS} OK")

find_package(PkgConfig)
pkg_check_modules(LIBUV REQUIRED libuv)
message(STATUS " ${LIBUV_LIBRARY_DIRS} OK")

set(Root "${CMAKE_CURRENT_SOURCE_DIR}")
set(Base64 ${Root}/lib/libb64/src)

include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${Root})
include_directories(${Root}/lib/libb64/include)
include_directories(${LIBUV_INCLUDE_DIRS})

link_directories(${LIBUV_LIBRARY_DIRS})

add_library(atlas_cv STATIC
            cv_atlas.cpp
            cv_atlas.h
            cv_tool.h
            cv_tool.cpp
            ${Base64}/cencode.c)

set_target_properties(
  atlas_cv
  PROPERTIES
  ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/bin")

其中命令 message 會將引數的內容輸出到終端,如果列印變數,需加上${}。
set表示給Root Base64變數賦值
include_directories表示加入編譯所需的相關標頭檔案路徑
link_directories表示需要連結的庫檔案路徑
add_library表示要生成的庫路徑以及依賴的原始檔名
set_target_properties表示設定庫目標的屬性,如輸出名稱和位置。

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

本文永久更新連結地址https://www.linuxidc.com/Linux/2018-09/154164.htm


IT145.com E-mail:sddin#qq.com