CMake详细的指令

所需文件名:CmakeLists.txt,在需要操作的每个目录下都需要

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(dirVARIABLE)

    作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中

    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_OUTPUTRETURN_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)


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cmake提供了一些常用的编译指令,包括但不限于以下几个指令PROJECT,ADD_EXECUTABLE,INSTALL,ADD_SUBDIRECTORY,SUBDIRS,INCLUDE_DIRECTORIES,LINK_DIRECTORIES,TARGET_LINK_LIBRARIES和SET。其中,PROJECT指令用于定义项目名称,ADD_EXECUTABLE指令用于添加可执行文件,INSTALL指令用于安装文件,ADD_SUBDIRECTORY指令用于添加子目录,SUBDIRS指令用于指定子目录,INCLUDE_DIRECTORIES指令用于指定头文件搜索路径,LINK_DIRECTORIES指令用于指定库文件搜索路径,TARGET_LINK_LIBRARIES指令用于链接库文件,SET指令用于设置变量的值。这些指令可以帮助我们管理和构建复杂的程序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [CMake常用指令](https://blog.csdn.net/Long_xu/article/details/129179618)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [CMake 的常用命令](https://blog.csdn.net/LearnLHC/article/details/125515650)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值