cmake編譯
cmake 的命令列使用方式為cmake -D<variable>="<value>" <CMakeLists.txt path>。
-D 選項可用來指定編譯時需要的變數內容 。
CMakeLists.txt path:頂層CMakeLists.txt 所在位置
EX
cmake -DCMAKE_CXX_COMPILER="clang++” -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" ../source。
cmake 如何除錯:
透過使用 SET 語法, set(CMAKE_VERBOSE_MAKEFILE TRUE),可以在 CMakeLists.txt 中將 CMAKE_VERBOSE_MAKEFILE 屬性設為 TRUE 。一旦 CMAKE_VERBOSE_MAKEFILE 為 True,可以讓 make 在執行時是 verbose output。
在呼叫 cmake 命令時,一併使用 --trace / --trace-expand,這兩個參數會鉅細靡遺的紀錄 cmake 如何被呼叫,和處理 CMakeLists.txt 的設定
變數
CMAKE_SOURCE_DIR 即 CMake 進入 source tree 的起始目錄(頂層CMakeLists.txt)
自定義變數
SET(myVar AAA)
使用的時候直接用${myVar}就可以了
Project command
這類的命令都是屬於 project-scope 的命令,主要提供建立與專案編譯相關的指令。
project(<prjName>)
指定專案的名稱,指定專案名稱最主要的目的在於啟用幾個和環境相關的變數,另外也會在 makefile 增加對應的 target。
Add a library path in cmake
include_directories(${CMAKE_SOURCE_DIR}/inc)
link_directories(${CMAKE_SOURCE_DIR}/lib)
增加一個檔案夾到專案內
add_sub_directories(source code folder)
生成專案目標執行檔
add_executable(<name> SOURCES):
<name> 目標執行檔的名稱,不一定要和前面的<prjName>同名。
SOURCES 可編譯成目標執行檔的來源檔,可以是多個檔案。
ex:
add_executable(example main.cpp main.h),在這個命令 SOURCES 包含兩個檔案“main.cpp main.h" 。
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] <source1> <source2> <...>)
添加一個名為<name>的庫文件
- STATIC:靜態程式庫。
- SHARED:共享程式庫,例如 Unix like 系統上的 so 檔或 Windows 上的 dll 檔。在建置 dll 時也會連帶生成連結用的 .a 檔,例如建置 libcalc.dll 時也會生成 libcalc.dll.a。
- MODULE:動態連結程式庫,不在編譯期進行連結,而是等到執行期才透過 dlopen() 或 LoadLibrary() 方式調用。一般情況下 MODULE 輸出的檔案類型也是 so 或 dll,但建立 dll 時不會順便產生 .a 檔。
如果沒有指定 target 之 STATIC、SHARED、MODULE 類型,則由全域變數 BUILD_SHARED_LIBS 來決定要建構何者,BUILD_SHARED_LIBS 預設為 off,亦即建立靜態程式庫。雖然可以直接在 CMakeLists 當中用 set() 指令指派 BUILD_SHARED_LIBS 的值,不過等到執行 CMake 再用 -D 指定通常會比較有彈性。
add_library(TARGET_NAME [STATIC | SHARED | MODULE | OBJECT| UNKNOWN] IMPORTED [GLOBAL])
導入已有的庫
利用 IMPORTED 關鍵字假設另外一個專案或 framework 編譯了一個 library,可以供此專案引用。
EX:
add_library(torch UNKNOWN IMPORTED)
引用 TorchConfig.cmake 增加名為 torch 的 target
target_link_libraries(<TARGET_NAME> [PRIVATE|PUBLIC|INTERFACE] <LIBRARY1><LIBRARY2><...>)
將若干庫鏈接到目標庫文件
LIBRARY 可以是一個或多個 library 的名字,絕對路徑,library 名稱(也就是 lib<library_name>.so 中的 <library_name)或 -l<library_name>這樣的形式。例子:target_link_libraries(<name> lib1 lib2 lib3)。
target_include_directories(<TARGET_NAME> [INTERFACE|PUBLIC|PRIVATE] <DIR>)
編譯名為 TARGET_NAME 的 target 時,會增加 DIR 目錄到標頭檔的搜尋路徑中。
Scripting command:
OPTION(OPTION_NAME HELP_MESSAGE DEFAULT_VALUE):建立使用者選項參數,在例子中會建立一個使用者參數,名為 DOWNLOAD_MNIST,預設為 ON。
message([MODE] "message to display"):message 可以看做是 CMake 的 print。MODE 必須填入 CMake 提供的常數選項,比較常用的包括了 none(未給定), STATUS, WARNING 和 FATAL_ERROR。模式的不同會決定輸出的目的地,若是 STATUS 則會輸出於 stdout,其他則會輸出於 stderr。
find_package()
top-level 的 CMakeLists.txt,可以使用 find_package 載入在子資料內的CMakeLists.txt上所定義的 function 或執行結果。
CMake 所產生出來的 makefile 無法獨立運作,建置過程仍然必須依賴 CMake,因此無法直接將 makefile 搬移到沒有 CMake 的環境中使用。事實上,只要更換環境就應該重新執行 CMake,針對目前環境配置產生 makefile。
Macro
定義:
MACRO(HEADER_DIRECTORIES return_list dataFilter)
FILE(GLOB_RECURSE new_list ${dataFilter})
SET(dir_list "")
FOREACH(file_path ${new_list})
GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
SET(dir_list ${dir_list} ${dir_path})
ENDFOREACH()
LIST(REMOVE_DUPLICATES dir_list)
SET(${return_list} ${dir_list})
ENDMACRO()
使用:
SET(search_filter "/home/user/Project/android/GStreamerSDK/x86_64/lib/glib-2.0/*.h")
HEADER_DIRECTORIES(glibcfg_include_dir ${search_filter})
cmake后make时若想打印编译过程,命令为: make VERBOSE=1
沒有留言:
張貼留言