天天看點

CMake常見指令總結

PROJECT(工程名字)

    這條指令會自動建立兩個變量:

<projectname>_BINARY_DIR(二進制檔案儲存路徑)    <projectname>_SOURCE_DIR(源代碼路徑)

cmake系統也幫助我們預定義了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR其值與上述對應相等

SET(變量名 變量值)

    SET(VAR [VALUE] [CACHE TYPEDOCSTRING [FORCE]])

    SET(SRC_LIST main.c t1.ct2.c)

    SET(SRC_LIST main.c)

MESSAGE(消息類型 消息内容)

    MESSAGE([SEND_ERROR | STATUS| FATAL_ERROR] "message to display")

  ADD_EXECUTABLE(可執行檔案名 生成該可執行檔案的源檔案)

    ADD_EXECUTABLE(hello${SRC_LIST})

ADD_SUBDIRECTORY(子目錄名字)

    ADD_SUBDIRECTORY(source_dir[binary_dir] [EXCLUDE_FROM_ALL])

SET(EXECUTABLE_OUTPUT_PATH${PROJECT_BINARY_DIR}/bin)更改生成的可執行檔案路徑

SET(LIBRARY_OUTPUT_PATH${PROJECT_BINARY_DIR}/lib)更改生成的庫檔案路徑

ADD_LIBRARY(hello SHARED${LIBHELLO_SRC})生成動态靜态庫

    ADD_LIBRARY(libname[SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL]

source1source2 ... sourceN)

 SET_TARGET_PROPERTIES

SET_TARGET_PROPERTIES(hello_staticPROPERTIES OUTPUT_NAME "hello")

同時生成動态靜态庫

    ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

    ADD_LIBRARY(hello_staticSTATIC ${LIBHELLO_SRC})

    SET_TARGET_PROPERTIES(hello_staticPROPERTIES OUTPUT_NAME "hello")

        SET_TARGET_PROPERTIES(hello PROPERTIESCLEAN_DIRECT_OUTPUT 1)

SET_TARGET_PROPERTIES(hello_staticPROPERTIES CLEAN_DIRECT_OUTPUT 1)

控制版本

        SET_TARGET_PROPERTIES(hello PROPERTIESVERSION 1.2 SOVERSION 1)

VERSION指代動态庫版本,SOVERSION指代API版本。

INSTALL(TARGETS hellohello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

INSTALL(FILES hello.h DESTINATIONinclude/hello)

注意,靜态庫要使用ARCHIVE關鍵字

cmake -DCMAKE_INSTALL_PREFIX=/usr ..[路徑]

INCLUDE_DIRECTORIES(追加标志 頭檔案路徑)

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

LINK_DIRECTORIES(庫檔案路徑)

LINK_DIRECTORIES(directory1 directory2 ...)

TARGET_LINK_LIBRARIES 設定要連接配接庫檔案的名稱

    TARGET_LINK_LIBRARIES(targetlibrary1 <debug | optimized> library2 ..)

    TARGET_LINK_LIBRARIES(main hello),連接配接libhello.so庫

    TARGET_LINK_LIBRARIES(mainlibhello.a)

    TARGET_LINK_LIBRARIES(mainlibhello.so) 

使用$ENV{NAME}指令就可以調用系統的環境變量

系統資訊

1,CMAKE_MAJOR_VERSION,CMAKE主版本号,比如2.4.6中的2

2,CMAKE_MINOR_VERSION,CMAKE次版本号,比如2.4.6中的4

3,CMAKE_PATCH_VERSION,CMAKE更新檔等級,比如2.4.6 中的6

4,CMAKE_SYSTEM,系統名稱,比如Linux-2.6.22

5,CMAKE_SYSTEM_NAME,不包含版本的系統名,比如Linux

6,CMAKE_SYSTEM_VERSION,系統版本,比如2.6.22

7,CMAKE_SYSTEM_PROCESSOR,處理器名稱,比如i686.

8,UNIX,在所有的類UNIX平台為TRUE,包括OS X和cygwin

9,WIN32,在所有的win32平台為TRUE,包括cygwin

主要的開關選項:

1,CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS,用來控制IF ELSE語句的書寫方式,在

下一節文法部分會講到。

2,BUILD_SHARED_LIBS

這個開關用來控制預設的庫編譯方式,如果不進行設定,使用ADD_LIBRARY并沒有指定庫類型的情況下,預設編譯生成的庫都是靜态庫。

如果SET(BUILD_SHARED_LIBS ON)後,預設生成的為動态庫。

3,CMAKE_C_FLAGS

設定C編譯選項,也可以通過指令ADD_DEFINITIONS()添加。

4,CMAKE_CXX_FLAGS

設定C++編譯選項,也可以通過指令ADD_DEFINITIONS()添加。

ADD_DEFINITIONS(-DENABLE_DEBUG-DABC),定義宏

ADD_DEPENDENCIES

定義target依賴的其他target,確定在編譯本target之前,其他的target已經被建構。

ADD_DEPENDENCIES(target-name depend-target1depend-target2 ...)

ADD_TEST與ENABLE_TESTING指令

ADD_TEST(testname Exenamearg1 arg2 ...)

如果沒有在同一個CMakeLists.txt中打開ENABLE_TESTING()指令,任何ADD_TEST都是無效的。

ADD_TEST(mytest${PROJECT_BINARY_DIR}/bin/main)

ENABLE_TESTING()

生成Makefile後,就可以運作make test來執行測試了。

 AUX_SOURCE_DIRECTORY

    AUX_SOURCE_DIRECTORY(dir VARIABLE)

    作用是發現一個目錄下所有的源代碼檔案并将清單存儲在一個變量中

    AUX_SOURCE_DIRECTORY(. SRC_LIST)

ADD_EXECUTABLE(main ${SRC_LIST})

CMAKE_MINIMUM_REQUIRED(VERSION2.5 FATAL_ERROR)最低版本CMAKE要求

EXEC_PROGRAM(Executable[directory in which to run]

[ARGS <arguments to executable>]

[OUTPUT_VARIABLE <var>]

[RETURN_VALUE <var>])

用于在指定的目錄運作某個程式,通過ARGS添加參數,如果要擷取輸出和傳回值,可通過OUTPUT_VARIABLE和RETURN_VALUE分别定義兩個變量.

    舉個簡單的例子,我們要在src目錄執行ls指令,并把結果和傳回值存下來。

可以直接在src/CMakeLists.txt中添加:

EXEC_PROGRAM(ls ARGS "*.c" OUTPUT_VARIABLE LS_OUTPUT RETURN_VALUE LS_RVALUE)

IF(not LS_RVALUE)

MESSAGE(STATUS "ls result: "${LS_OUTPUT})

ENDIF(not LS_RVALUE)

FILE指令

檔案操作指令,基本文法為:

FILE(WRITE filename "message towrite"... )

FILE(APPEND filename "message towrite"... )

FILE(READ filename variable)

FILE(GLOB variable [RELATIVE path][globbing expressions]...)

FILE(GLOB_RECURSE variable [RELATIVE path] [globbingexpressions]...)

FILE(REMOVE [directory]...)

FILE(REMOVE_RECURSE [directory]...)

FILE(MAKE_DIRECTORY [directory]...)

FILE(RELATIVE_PATH variable directory file)

FILE(TO_CMAKE_PATH path result)

FILE(TO_NATIVE_PATH path result)

INCLUDE指令,用來載入CMakeLists.txt檔案,也用于載入預定義的cmake子產品.

INCLUDE(file1 [OPTIONAL])

INCLUDE(module [OPTIONAL])

OPTIONAL參數的作用是檔案不存在也不會産生錯誤。

你可以指定載入一個檔案,如果定義的是一個子產品,那麼将在CMAKE_MODULE_PATH中搜尋這個子產品并載入。

FIND_系列指令主要包含一下指令:

FIND_FILE(<VAR> name1 path1 path2 ...)

VAR變量代表找到的檔案全路徑,包含檔案名

FIND_LIBRARY(<VAR> name1 path1 path2 ...)

VAR變量表示找到的庫全路徑,包含庫檔案名

FIND_PATH(<VAR> name1 path1 path2 ...)

VAR變量代表包含這個檔案的路徑。

FIND_PROGRAM(<VAR> name1 path1 path2 ...)

VAR變量代表包含這個程式的全路徑。

FIND_PACKAGE(<name> [major.minor] [QUIET][NO_MODULE] [[REQUIRED|COMPONENTS] [componets...]])

用來調用預定義在CMAKE_MODULE_PATH下的Find<name>.cmake子產品,你也可以自己

定義Find<name>子產品,通過SET(CMAKE_MODULE_PATH dir)将其放入工程的某個目錄

中供工程使用

FIND_LIBRARY示例:

FIND_LIBRARY(libX X11 /usr/lib)

IF(NOT libX)

MESSAGE(FATAL_ERROR “libX not found”)

ENDIF(NOT libX)

原本的條件語句

IF(WIN32)

MESSAGE(STATUS “This is windows.”)

#作一些Windows相關的操作

ELSE(WIN32)

MESSAGE(STATUS “This is not windows”)

#作一些非Windows相關的操作

ENDIF(WIN32)

通過設定SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)

上述代碼可寫為

IF(WIN32)

ELSE()

ENDIF()

還可以

IF(WIN32)

#do something related to WIN32

ELSEIF(UNIX)

#do something related to UNIX

ELSEIF(APPLE)

#do something related to APPLE

ENDIF(WIN32)

WHILE指令的文法是:

WHILE(condition)

COMMAND1(ARGS ...)

COMMAND2(ARGS ...)

...

ENDWHILE(condition)

FOREACH指令的使用方法有三種形式:

清單

FOREACH(loop_var arg1 arg2...)

COMMAND1(ARGS ...)

COMMAND2(ARGS ...)

...

ENDFOREACH(loop_var)

像我們前面使用的AUX_SOURCE_DIRECTORY的例子

AUX_SOURCE_DIRECTORY(. SRC_LIST)

FOREACH(F ${SRC_LIST})

MESSAGE(${F})

ENDFOREACH(F)

範圍

FOREACH(loop_var RANGE total)

ENDFOREACH(loop_var)

從0到total以1為步進舉例如下:

FOREACH(VAR RANGE 10)

MESSAGE(${VAR})

ENDFOREACH(VAR)

最終得到的輸出是:0-10

範圍和步進

FOREACH(loop_var RANGE start stop [step])

ENDFOREACH(loop_var)

從start開始到stop結束,以step為步進,舉例如下

FOREACH(A RANGE 5 15 3)

MESSAGE(${A})

ENDFOREACH(A)

最終得到的結果是:

5

8

11

14

這個指令需要注意的是,直到遇到ENDFOREACH指令,整個語句塊才會得到真正的執行。

FIND_PACKAGE(CURL)

IF(CURL_FOUND)

INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})

TARGET_LINK_LIBRARIES(curltest${CURL_LIBRARY})

ELSE(CURL_FOUND)

MESSAGE(FATAL_ERROR ”CURL library not found”)

ENDIF(CURL_FOUND)

可以自己定義一些FIND_PACKAGE包,比如

定義cmake/FindHELLO.cmake子產品

FIND_PATH(HELLO_INCLUDE_DIR hello.h /usr/include/hello /usr/local/include/hello)

FIND_LIBRARY(HELLO_LIBRARY NAMES hello PATH /usr/lib /usr/local/lib)

IF (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)

SET(HELLO_FOUND TRUE)

ENDIF (HELLO_INCLUDE_DIR AND HELLO_LIBRARY)

IF (HELLO_FOUND)

IF (NOT HELLO_FIND_QUIETLY)

MESSAGE(STATUS "FoundHello: ${HELLO_LIBRARY}")

ENDIF (NOT HELLO_FIND_QUIETLY)

ELSE (HELLO_FOUND)

IF (HELLO_FIND_REQUIRED)

MESSAGE(FATAL_ERROR"Could not find hello library")

ENDIF (HELLO_FIND_REQUIRED)

ENDIF (HELLO_FOUND)

那麼可以使用

FIND_PACKAGE(HELLO)

IF(HELLO_FOUND)

ADD_EXECUTABLE(hello main.c)

INCLUDE_DIRECTORIES(${HELLO_INCLUDE_DIR})

TARGET_LINK_LIBRARIES(hello${HELLO_LIBRARY})

ENDIF(HELLO_FOUND)

來操作,不過操作之前需要設定cmake搜尋路徑

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

轉載于:https://my.oschina.net/fuyajun1983cn/blog/263812

繼續閱讀