CMakeList 編寫規則,cmakelist編寫規則

來源:互聯網
上載者:User

CMakeList 編寫規則,cmakelist編寫規則

 

Makefilen內容
1. 顯示規則:顯示規則說明了,如何產生一個或多個目標。這是由Makefile指出要產生的檔案和檔案依賴的檔案。
2. 隱晦規則:基於Makefile的自動推導功能
3. 變數的定義:一般是字串
4. 檔案指示:一般是在Makefile中引用另外一個makefile檔案;根據某些規則指定Makefile中有效部分;多行
5. 注釋:#指示注釋

 

#常用變數
$@ ---目標檔案
$^ ---所有依賴檔案
$< ---第一個依賴檔案
.PHONY ---偽目標檔案

 

#常見指令

CMAKE_MINIMUM_REQUIRED(VERSION major[.minor[.patch[.tweak]]] [FATAL_ERROR]) 聲明Cmake版本,如果低於指定版本則會停止處理工程檔案,並報告錯誤

PROJECT(PROJECTNAME [CXX] [C] [指定工程支援的語言,如果忽略,表示支援所有語言])

ADD_EXECUTABLE([WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 ...)引入一個名為的可執行目標,該目標會由調用該命令時在源檔案清單中指定的源檔案來構建。對應於邏輯目標名字,並且在工程範圍內必須是全域唯一的

如果構成可執行檔的源檔案很多,則最好在MakeFiles中一樣指定一個源檔案清單

CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
PROJECT(Hello)

SET (SRC_LIST main.cpp v4l2_util.cpp tran_data.cpp)
MESSAGE(${SRC_LIST})
ADD_EXECUTABLE(Hello ${SRC_LIST})

ADD_EXECUTABLE:可執行程式由哪些.o檔案產生

#編譯靜態庫,並讓主程式調用靜態庫最終產生一個可執行程式

即先產生一個hello.a,再讓主程式main.cpp使用libhello.a,最終產生Hello

CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
PROJECT(Hello)

SET(LIB_SRC_LIST source1.cpp  source2.cpp)

SET(EXEC_SRC_LIST main.cpp)

ADD_LIBRARY(LIB STATIC ${LIB_SRC_LIST})

ADD_EXECUTABLE(Test_Hello ${EXEC_SRC_LIST})

TARGET_LINK_LIBRARIES(Test_Hello LIB)

ADD_LIBRARY(NAME [STATIC| SHARED|MODULE] [EXCLUDE_FROM_ALL] source1, source2,...)

建立一個名字name的庫檔案,SHARED STATIC 制定產生庫的類型

TARGET_LINK_LIBRARIES(target [item1 [item2] [ ...] ]),將給定的庫連結到target上

#指定include路徑

一般情況下,src和include為同級目錄,需要指定include路徑src才可以正確定位標頭檔

SET(INCLUDE_DIRECTORIES " ../include")

INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})

#添加第三方庫,不需要編譯,將他放在resource目錄下,需要指定搜尋庫路徑

SET(LINK_DIR "../../resource")

LINK_DIRECTORIES(${LINK_DIR })

LINK_DIRECTORIES(${LINK_DIR }): 指定連接器尋找庫路徑

#建立Release和Debug版本

SET(CMAKE_BUILD_TYPE Release)

SET(CMAKE_BUILD_TYPE Debug)

指定二者模式區別在於

Release: -O3 -DNDEBUG

Debug: -g

也可不加在MakeFiles.txt裡面,在產生Makefiles時候才加入

cmake -DCMAKE_BUILD_TYPE=Release

#增加編譯和連結選項

CMAKE_C_FLAGS

CMAKE_CXX_FLAGS

CMAKE_EXE_LINKER_FLAGS

分別相當於:CFLAGS, CXXFLAGS, LDFLAGS。

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEMBED")這種寫法的好處是,不會覆蓋CMAKE_CXX_FLAGS本來的資訊。只是把需要添加的內容添加進去

 

Debug和Release版本:

關鍵在於三個CMake設定:

CMAKE_BUILD_TYPE

CMAKE_CXX_FLAGS_DEBUG

CMAKE_CXX_FLAGS_RELEASE

 

當CMAKE_BUILD_TYPE設定為Debug。 則編譯時間採用CMAKE_CXX_FLAGS_DEBUG。

當CMAKE_BUILD_TYPE設定為Release。 則編譯時間採用CMAKE_CXX_FLAGS_RELEASE

 

cmake_minimum_required (VERSION 2.6)

project (CMAKE_Test)

add_executable(CMAKE_Test src/banchmark.cpp)

 

#set(CMAKE_BUILD_TYPE Debug)

set(CMAKE_BUILD_TYPE Release)

set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -Wno-unused-but-set-variable")

set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -Wno-unused-but-set-variable")

#多目錄結構的cmake使用

Hello 實際的目錄結構其實並不是所有源碼都存放在src目錄內。

它的目錄結構是:

src: 存放產生庫的源碼。source1.cpp, source2.cpp

test:存放使用庫的測 試程式: main.cpp

include: 存放標頭檔: source1.h

resource: 存放第三方庫

build:存放編譯過程的檔案

build/lib: 存放產生的libv4l2_utils.so

build/bin:存放main.cpp所產生的測試程式可執行檔。

 

此時,可以採用頂層目錄和每個有源碼的目錄中均建立CMakeLists.txt的方式來處理(和Makefile處理方式類似)

頂層目錄的CMakeLists.txt 內容如下:

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

PROJECT(Hello)

ADD_SUBDIRECTORIES(src lib)

ADD_SUBDIRECTORIES(test bin)

ADD_SUBDIRECTORIES([source dir] [bin dir] [exclude_from_all])構建添加一個子路徑。source_dir選項指定了CMakeLists.txt源檔案和代碼檔案的位置。如果source_dir是一個相對路徑,那麼source_dir選項會被解釋為相對於當前的目錄,但是它也可以是一個絕對路徑。binary_dir選項指定了輸出檔案的路徑。如果binary_dir是相對路徑,它將會被解釋為相對於當前輸出路徑。

source_dir算相對路徑時,是從CMakeLists.txt算起。

所以src指的是當前 CMakeLists.txt所在路徑下的src. 而bin, lib 指的是當前輸出路徑下的bin,lib. 也就是build/bin build/lib

src CMakeLists.txt :

SET(LIB_SRC_LIST source1.cpp)

SET(CMAKE_BUILD_TYPE Release)

INCLUDE_DIRECTORIES(../include)

ADD_LIBRARY(SOURCE1 SHARED ${LIB_SRC_LIST})

 

test CMakeLists.txt :

SET(EXEC_SRC_LIST main.cpp)

SET(INCLUDE_DIRECTORIES ../include)

SET(LINK_DIR ../../resource)

SET(LINK_DIR "${LINK_DIR} ../../libs/")

SET(CMAKE_BUILD_TYPE Release)

 

INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})

LINK_DIRECTORIES(${LINK_DIR})

ADD_EXECUTABLE(Test_Hello ${EXEC_SRC_LIST})

TARGET_LINK_LIBRARIES(Test_Hello SOURCE1 )

 

#顯示編譯細節

SET(CMAKE_VERBOSE_MAKEFILE ON)

如果不希望改變CMakeLists.txt,可以在建立Makefile時候加入

cmake -DCMAKE_VERBOSE_MAKEFILE=ON

如果連Makefile都不希望修改可以

make VERBOSE=1

 

#相對路徑問題:

set (LIBRARY_DIRECTORIES ../resource)
link_directories(${LIBRARY_DIRECTORIES})

這裡會出警告:

This command specifies the relative path

../resource

可以做如下處理:

set (LIBRARY_DIRECTORIES ../resource)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/${LIBRARY_DIRECTORIES})

#FIND_PACKAGE()功能


可以被用來在系統中自動尋找配置構建工程所需的程式庫。在linux和unix類系統下這個命令尤其有用。CMake內建的模組檔案裡有大半是對各種常見開源庫的find_package支援,支援庫的種類非常多.

FIND_PACKAGE(Qt5Widgets)
FIND_PACKAGE( [version] [EXACT] [QUIET] [[REQUIRED|COMPONENTS] [components...]] [NO_POLICY_SCOPE])

尋找並載入外來工程的設定。該命令會設定_FOUND變數,用來指示要找的包是否被找到了。如果這個包被找到了,與它相關的資訊可以通過包自身記載的變數中得到。REQUIRED選項表示如果報沒有找到的話,cmake的過程會終止,並輸出警告資訊

在REQUIRED選項之後,或者如果沒有指定REQUIRED選項但是指定了COMPONENTS選項,在它們的後面可以列出一些與包相關的組件清單(components list)。

FIND_PACKAGE

每一個模組都會產生如下變數,_FOUND _INCLUDE_DIR _LIBRARY或者_LILBRARIES

如果_FOUND為真,_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中

就會有相應的變數Qt5Widgets_FOUND,Qt5Widgets_INCLUDE_DIRS等相應的變數生效。

 

PKG_CHECK_MODULES講解 

PKG_CHECK_MODULES(<PREFIX> [REQUIRED] [QUIET] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] <MODULE> [<MODULE>]*)

檢測所有給出的modules

PKG_CHECK_MODULES(PC_OPENNI2 libopenni2)

if (NOT PC_OPENNI2_FOUND)

PKG_CHECK_MODULES(PC_OPENNI2 REQUIRED openni2)

endif()

PC_OPENNI2_INCLUDE_DIRS, PC_OPENNI2_LIBRARY_DIRS 等被設定。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.