cmake if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") MESSAGE("Clang") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") MESSAGE("GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") MESSAGE("Intel") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") MESSAGE("MSVC") endif()
例子
cmake -DCMAKE_BUILD_TYPE=Debug
在cmake
脚本中,设置编译选项可以通过add_compile_options
命令,也可以通过set
命令修改CMAKE_CXX_FLAGS
或CMAKE_C_FLAGS
。 使用这两种方式在有的情况下效果是一样的,但请注意它们还是有区别的:
add_compile_options
命令添加的编译选项是针对所有编译器的(包括c和c++编译器),CMAKE_C_FLAGS
或CMAKE_CXX_FLAGS
变量则是分别只针对c和c++编译器的。例子
#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)
语法
add_compile_options(<option> ...)
# 例子
add_compile_options(-Wall -Wextra -pedantic -Werror -g)
待补充
语法
# Provides an option for the user to select as ON or OFF. If no initial <value> is provided, OFF is used. If <variable> is already set as a normal variable then the command does nothing
option(<variable> "<help_text>" [value])
# Add -D define flags to the compilation of source files.
add_definitions(-DFOO -DBAR ...)
cmake option(TEST_DEBUG "option for debug" OFF) if (TEST_DEBUG) add_definitions(-DTEST_DEBUG) endif()
bash cmake -DTEST_DEBUG=ON ..
在CMake中基础的数据形式是字符串。CMake也支持字符串列表。
列表通过分号分隔。譬如两个声明给变量VAR设同样的值:
set(VAR a;b;c)
set(VAR a b c)
字符串列表可以通过foreach命令迭代或直接操控列表命令。
CMake 支持简单的变量可以是字符串也可以是字符串列表。变量参考使用${VAR}
语法。多参数可以使用set
命令组合到一个列表中。所有其他的命令
通过空白分隔符传递命令来扩展列表,例如
set(Foo a b c)
# 将 变量 Foo 设为 a b c, 并且如果Foo 传递给另一个命令
command(${Foo})
# 等同于
command(a b c)
# 如果要把参数列表传递给一个命令,且它是一个简单的参数只要加一个双引号就可以。例如
command("${Foo}")
# 等价于
command("a b c")
像大多数语言一样,Cmake 提供了控制流结构。Cmake提供了三中控制流:
if
foreach
和 while
更多控制流信息参见命令 if,while,foreach,macro,function文档。
在CMake中原义字符串用双引号括起来。字符串可以是多行字符串,并在其中嵌入新的行。例如
set(MY_STRING "this is a string with a
newline in
it")
也可以在一个字符串中转义字符和使用变量
set(VAR "
hello
world
")
message("\${VAR}= ${VAR}")
# prints out
${VAR}=
hello
world
同样支持标准C中的转义
message("\n\thello world")
#prints out
hello world
如果字符在引号之前是空格则原义字符串只是原义字符串。但是引号必须成对,例如
message(hell"o") -> prints hell"o"
message(hell\"o\") -> prints hello"o"
cmake可以使用正则表达式
cmake project 头文件必须存在这行命令, 例如cmake_minimum_required(VERSION 3.10)
设置项目名称project(Tutorial)
语法
# Set Normal Variable
set(<variable> <value>... [PARENT_SCOPE])
# Set Environment Variable
# 这个环境变量只对当前cmake工程有效,对外界是无效的。
set(ENV{<variable>} [<value>])
例子
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3 -Wall -Wl,-rpath=/tools/lib64 -Wl,--dynamic-linker=/tools/lib/ld-2.17.so")
语法
message([<mode>] "message to display" ...)
The optional <mode> keyword determines the type of message:
|mode | explaination| |--|--:| |FATAL_ERROR
|CMake Error, stop processing and generation. |SEND_ERROR
|CMake Error, continue processing, but skip generation. |WARNING
|CMake Warning, continue processing. |AUTHOR_WARNING
|CMake Warning (dev), continue processing. |DEPRECATION
|CMake Deprecation Error or Warning if variable CMAKE_ERROR_DEPRECATED
or CMAKE_WARN_DEPRECATED
is enabled, respectively, else no message. |(none)
or NOTICE
|Important message printed to stderr to attract user’s attention. |STATUS
|一般就用这个,Ideally these should be concise, no more than a single line, but still informative. |VERBOSE
|Detailed informational messages intended for project users. These messages should provide additional details that won’t be of interest in most cases, but which may be useful to those building the project when they want deeper insight into what’s happening. |DEBUG
|Detailed informational messages intended for developers working on the project itself as opposed to users who just want to build it. These messages will not typically be of interest to other users building the project and will often be closely related to internal implementation details. |TRACE
|Fine-grained messages with very low-level implementation details. Messages using this log level would normally only be temporary and would expect to be removed before releasing the project, packaging up the files, etc.
# 找到所有dir目录下的源文件(不会递归遍历子文件夹),源文件是.c文件(也就是makefile中可以生成.o的文件)
aux_source_directory(<dir> <variable>)
将指定的源文件(CPP文件)生成链接文件,然后添加到工程中去。
语法
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
其中<name>
表示库文件的名字,该库文件会根据命令里列出的源文件来创建。而STATIC
、SHARED
和MODULE
的作用是指定生成的库文件的类型。
STATIC
库是目标文件的归档文件,在链接其它目标的时候使用。SHARED
库会被动态链接(动态链接库),在运行时会被加载。MODULE
库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。例子
add_library(roland_pb CreateUDiskRequest.pb.cc)
add_executable(echo_client echo_client.cc)
target_link_libraries(echo_client uevent event uevent_base pthread roland_pb protobuf)
在子文件夹添加了library
或者executable
之后,在上层目录添加subdirectory
, 也可以在同一个CMakeList.txt中使用
它相当于g++
选项中的-I
参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用。
语法:
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
# 例子
include_directories(../../../thirdparty/comm/include)
它相当于g++
命令的-L
选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH
的路径的作用。 语法:
`link_directories(directory1 directory2 ...)`
# 例子
`link_directories("/home/server/third/lib")`
语法:
# A short-hand signature is:
find_library (<VAR> name1 [path1 path2 ...])
# The general signature is:
find_library (
<VAR>
name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
# 例子如下
FIND_LIBRARY(RUNTIME_LIB rt /usr/lib /usr/local/lib NO_DEFAULT_PATH)
cmake会在目录中查找,如果所有目录中都没有,值RUNTIME_LIB就会被赋为NO_DEFAULT_PATH
该指令的作用主要是指定要链接的库文件的路径,该指令有时候不一定需要。因为find_package和find_library指令可以得到库文件的绝对路径。不过你自己写的动态库文件放在自己新建的目录下时,可以用该指令指定该目录的路径以便工程能够找到。
语法:
link_libraries(library1 <debug | optimized> library2 ...)
# 直接是全路径
link_libraries(“/home/server/third/lib/libcommon.a”)
# 下面的例子,只有库名,cmake会自动去所包含的目录搜索
link_libraries(iconv)
# 传入变量
link_libraries(${RUNTIME_LIB})
# 也可以链接多个
link_libraries("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")
可以链接一个,也可以多个,中间使用空格分隔.
语法:
target_link_libraries(<target> [item1 [item2 [...]]]
[[debug|optimized|general] <item>] ...)
# 以下写法都可以:
target_link_libraries(myProject comm) # 连接libhello.so库,默认优先链接动态库
target_link_libraries(myProject libcomm.a) # 显示指定链接静态库
target_link_libraries(myProject libcomm.so) # 显示指定链接动态库
# 再如:
target_link_libraries(myProject libcomm.so) #这些库名写法都可以。
target_link_libraries(myProject comm)
target_link_libraries(myProject -lcomm)
语法:
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
source1 [source2 ...])
简单的例子如下:
add_executable(demo main.cpp)
add_executable(echo_client echo_client.cc CreateUDiskRequest.pb.cc)
本篇文章由一文多发平台ArtiPub自动发布
原文:https://www.cnblogs.com/wxxujian/p/12851574.html