开发环境搭建GNU toolchain

CMAKE语法摘要

2017-10-11  本文已影响206人  赵海洋

可以设置的变量

使用方式cmake -DCMAKE_INSTALL_PREFIX=yourpath 或在CMAKE-GUI中勾选

可以设置的环境变量

可以引用的常量

可以引用的系统信息

常用函数

# 对构建目标设置规则
INSTALL(TARGETS myrun mylib mystaticlib
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION libstatic
        )
# 普通文件的安装规则
INSTALL(FILES files... DESTINATION <dir>
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [RENAME <name>] [OPTIONAL])

# 非目标文件的可执行程序安装(比如脚本之类),和File的区别只在于默认安装后权限是755,而FILE是644
INSTALL(PROGRAMS files... DESTINATION <dir>
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [RENAME <name>] [OPTIONAL])

# 安装时执行脚本
INSTALL([[SCRIPT <file>] [CODE <code>]] [...])

SCRIPT参数用于在安装时调用cmake脚本文件(也就是<abc>.cmake文件)
CODE参数用于执行CMAKE指令,必须以双引号括起来。比如:
INSTALL(CODE "MESSAGE(\"Sample install message.\")")        
EXEC_PROGRAM(Executable [directory in which to run]
            [ARGS <arguments to executable>]
            [OUTPUT_VARIABLE <var>]
            [RETURN_VALUE <var>])

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)
execute_process(COMMAND <cmd1> [args1...]]
                [COMMAND <cmd2> [args2...] [...]]
                [WORKING_DIRECTORY <directory>]
                [TIMEOUT <seconds>]
                [RESULT_VARIABLE <variable>]
                [OUTPUT_VARIABLE <variable>]
                [ERROR_VARIABLE <variable>]
                [INPUT_FILE <file>]
                [OUTPUT_FILE <file>]
                [ERROR_FILE <file>]
                [OUTPUT_QUIET]
                [ERROR_QUIET]
                [OUTPUT_STRIP_TRAILING_WHITESPACE]
                [ERROR_STRIP_TRAILING_WHITESPACE])
FILE(WRITE filename "message to write"... )
FILE(APPEND filename "message to write"... )
FILE(READ filename variable)
FILE(GLOB variable [RELATIVE path] [globbing
expressions]...)
FILE(GLOB_RECURSE variable [RELATIVE path]
[globbing expressions]...)
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(file1 [OPTIONAL])
INCLUDE(module [OPTIONAL])
OPTIONAL参数的作用是文件不存在也不会产生错误。
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)将其放入工程的某个目录中供工程使用

代码组织

TARGET_LINK_LIBRARIES(target library1
                    <debug | optimized> library2
                    ...)

生成规则

可执行程序

最简makefile

PROJECT(HELLO)
ADD_EXECUTABLE(hello main.c)

动态和静态库

ADD_LIBRARY

通过ADD_LIBRARY指令构建动态库和静态库。例:ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

原型

ADD_LIBRARY(libname [SHARED|STATIC|MODULE]
            [EXCLUDE_FROM_ALL]
            source1 source2 ... sourceN)

SET_TARGET_PROPERTIES

如果有一个名称为hello的SHARED库,还有个名为hello_static的STATIC库时,则可以使用下面的指令同时构建同名的动态库和静态库(libhello.a和libhello.so)

SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
# 还要加上以下两行,防止生成hello_static时清除了libhello.so
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT
1)

还可以通过SET_TARGET_PROPERTIES控制动态库版本,SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)VERSION指代动态库版本,SOVERSION指代API版本。
将上述指令加入lib/CMakeLists.txt中,重新构建看看结果。
build/lib目录会生成:

libhello.so.1.2
libhello.so.1->libhello.so.1.2
libhello.so ->libhello.so.1

控制指令

IF(var) | IF(NOT var) | IF(var1 AND var2) | IF(var1 OR var2) | IF(COMMAND cmd) | IF(EXISTS dir) | IF(file1 IS_NEWER_THAN file2) | IF(IS_DIRECTORY dirname) | IF(variable MATCHES regex) 
    MESSAGE(STATUS “do something”)
    # 条件满足时的操作
ELSEIF(var) | xxxx
ENDIF()
WHILE(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDWHILE(condition)
FOREACH(loop_var arg1 arg2 ...) | FOREACH(loop_var RANGE total) | FOREACH(loop_var RANGE start stop [step])
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDFOREACH(loop_var)
上一篇 下一篇

猜你喜欢

热点阅读