对于第三方依赖的头文件可用include_directories()添加依赖的头文件。 include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH
变量的作用,可以用相对路径。
对于在gcc默认搜索路径如/usr/include 和 /usr/local/include内的头文件可以不用include_directories,会默认搜索到,对于非默认路径下的头文件需要加include_directories,如
include_directories(../../../thirdparty/comm/include)
可以通过include_directories(${PROJECT_SOURCE_DIR})
添加一个目录级别较高的目录,不一定是头文件的直属父目录,可以在引用头文件的时候写明目录级别,如
#include "util/tc_epoll_server.h"
#include "servant/AppProtocol.h"
#include "tup/Tars.h"
include_directories的目录至少包含util servant tup这三个子目录。
添加需要链接的库文件目录LINK_DIRECTORIES语法:它相当于g++命令的-L选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用。link_directories("/home/server/third/lib"),后面可以直接用名字表示link该目录下的文件库。
link_libraries: The target_link_libraries() command should be preferred whenever possible. Library dependencies are chained automatically, so directory-wide specification of link libraries is rarely needed. 应尽可能首选target_link_libraries()命令。 库依赖项是自动链接的,因此很少需要链接库的目录范围规范。
link_libraries(“/home/server/third/lib/libcommon.a”)
link_libraries("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")
add_library该指令的主要作用就是将指定的源文件生成链接文件,然后添加到工程中去。可加set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
把生成的库输出到指定的路径下。一般子目录中使用,父目录可以add到生成的库。 该指令常用的语法如下:
add_library(
其中
表示库文件的名字,直接写名字即可,不要写lib,会自动加上前缀,该库文件会根据命令里列出的源文件来创建。
而STATIC、SHARED和MODULE的作用是指定生成的库文件的类型。STATIC库是目标文件的归档文件,在链接其它目标的时候使用。SHARED库会被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数。如果没有类型被显式指定,这个选项将会根据变量BUILD_SHARED_LIBS的当前值是否为真决定是STATIC还是SHARED。
默认状态下,库文件将会在于源文件目录树的构建目录树的位置被创建,该命令也会在这里被调用。而语法中的source1 source2分别表示各个源文件。
例如:
aux_source_directory(. DIR_LIB_SRCS)
add_library (MathFunctions ${DIR_LIB_SRCS})
TARGET_LINK_LIBRARIES(target library1
TARGET_LINK_LIBRARIES(myProject hello),连接libhello.so库
TARGET_LINK_LIBRARIES(myProject libhello.a)
# 以下写法都可以:
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_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
这条命令的作用是为构建添加一个子路径。source_dir选项指定了CMakeLists.txt源文件和代码文件的位置。如果source_dir是一个相对路径,那么source_dir选项会被解释为相对于当前的目录,但是它也可以是一个绝对路径。binary_dir选项指定了输出文件的路径。如果binary_dir是相对路径,它将会被解释为相对于当前输出路径,但是它也可以是一个绝对路径。在source_dir指定路径下的CMakeLists.txt将会在当前输入文件的处理过程执行到该命令之前,立即被CMake处理。
如果指定了EXCLUDE_FROM_ALL选项,在子路径下的目标默认不会被包含到父路径的ALL目标里,并且也会被排除在IDE工程文件之外。用户必须显式构建在子路径下的目标,比如一些示范性的例子工程就是这样。典型地,子路径应该包含它自己的project()命令调用,这样会在子路径下产生一份完整的构建系统(比如VS IDE的solution文件)。注意,目标间的依赖性要高于这种排除行为。如果一个被父工程构建的目标依赖于在这个子路径下的目标,被依赖的目标会被包含到父工程的构建系统中,以满足依赖性的要求。
父目录会注册add_subdirectory子目录中的PROJECT_SOURCE/BINARY_DIR
的宏信息,只有CMakeList中定义了project()才有当前目录下定义的相关目录宏。子目录中的目录宏可以在父目录中的CMakeList中使用,而父目录的后续add_subdirectory中所有的子目录也可以使用此宏定义。
查找目录< dir >下的所有源文件并将名称保存到< variable > 变量
通过add_definitions添加编译选项, 向C/CPP添加宏定义,相当于gcc中的-D,参数之间用空格分割。GCC编译时增加宏定义-D标识符,相当于宏定义#define 标识符。
gcc -DDEBUG :-D 后面直接跟宏命,相当于定义这个宏,默认这个宏的内容是1
gcc -DNAME=Peter: -D 后面跟 key=value 表示定义key这个宏,它的内容是value。
set(_USE_OPENTRACKING $ENV{_USE_OPENTRACKING})
if(_USE_OPENTRACKING)
set(OPENTRACKING_INC "/usr/local/include")
add_definitions(-D_USE_OPENTRACKING=${_USE_OPENTRACKING})
endif()
MESSAGE(STATUS “HOME dir: $ENV{HOME}”)
$
符号,而写和if判断是否定义时,ENV{JAVA_HOME}
指代变量名所以不加$符号CMAKE_INCLUDE_PATH:cmake中头文件包含路径的环境变量。可以通过在bash中使用环境变量的形式(如export)进行设置值,也可以在cmake文件中使用set关键字进行设置,set(CMAKE_INCLUDE_PATH "include_path")
或
export CMAKE_INCLUDE_PATH=xxxxx
CMAKE_INCLUDE_PATH需要配合 FIND_FILE() 以及 FIND_PATH() 使用。如果头文件没有存放在常规路径(/usr/include, /usr/local/include等),则可以通过这些变量就行弥补。如果不使用 FIND_FILE 和 FIND_PATH的话,CMAKE_INCLUDE_PATH,没有任何作用。
find_path用于查找包含的头文件,其查找顺序为:
1)从CMAKE_INCLUDE_PATH中查找。
2)从系统默认头目录即/usr/include、/usr/local/inlucde中查找。
CMAKE_LIBRARY_PATH:cmake中库文件路径的环境变量。CMAKE_LIBRARY_PATH需配合 FIND_LIBRARY() 使用。否则没有任何作用.
find_library用于查找包含的库文件,其查找顺序为:
1)从CMAKE_LIBRARY_PATH中查找。
2)从系统默认库目录即/usr/lib、/usr/local/lib中查找。
${NAME_INCLUDE_DIRS}
中,将链接库设置到${NAME_LIBS}
中。
add_custom_target(Name [ALL] [command1 [args1...]]
[COMMAND command2 [args2...] ...]
[DEPENDS depend depend depend ... ]
[BYPRODUCTS [files...]]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[JOB_POOL job_pool]
[VERBATIM] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS]
[SOURCES src1 [src2...]])
用Name选项给定的名字添加一个目标,这个目标会引发给定的那些COMMAND命令。这个目标没有输出文件,并且总是被认为是过时的,即使那些命令试图去创建一个与该目标同名的文件。
cmake_minimum_required(VERSION 3.0)
project(test)
add_custom_target(CpTask
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/config ${CMAKE_CURRENT_SOURCE_DIR}/etc
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/log.txt ${CMAKE_CURRENT_SOURCE_DIR}/etc
)
运行该CMakeLists.txt:
cmake ..
make CpTask
这段代码的目的就是将config文件夹的内容和log.txt文件复制到新的etc文件夹内。
add_custom_target生成一个目标CopyTask,该目标是用来复制文件夹或者复制文件的!也就是COMMAND中定义的操作。其中:${CMAKE_COMMAND}是CMake的路径,-E使CMake运行命令而不是构建,copy_directory和copy是cmake_command_line,再后面两个就是command_line的参数。当然,生成文件不仅仅只能是复制,还可以是其他的操作。而这些COMMAND操作,都在command_line中规定了。至于cmake_command_line的内容,可参考cmake的官方资料:Run a Command-Line Tool。
该命令的其他一些参数的含义:
ALL:表明该目标会被添加到默认的构建目标,使得它每次都被运行;
COMMAND:指定要在构建时执行的命令行;
DEPENDS:指定命令所依赖的文件;
COMMENT:在构建时执行命令之前显示给定消息;
WORKING_DIRECTORY:使用给定的当前工作目录执行命令。如果它是相对路径,它将相对于对应于当前源目录的构建树目录;
BYPRODUCTS:指定命令预期产生的文件。
add_custom_command(OUTPUT output1 [output2 ...]
COMMAND command1 [ARGS] [args1...]``
[COMMAND command2 [ARGS] [args2...] ...]
[MAIN_DEPENDENCY depend]
[DEPENDS [depends...]]
[BYPRODUCTS [files...]]
[IMPLICIT_DEPENDS depend1
[ depend2] ...]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[DEPFILE depfile]
[JOB_POOL job_pool]
[VERBATIM] [APPEND] [USES_TERMINAL]
[COMMAND_EXPAND_LISTS])
//这种命令格式定义了一条生成指定的文件(文件组)的命令。
cmake_minimum_required(VERSION 3.0)
project(test)
add_custom_command(OUTPUT COPY_RES
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/config ${CMAKE_CURRENT_SOURCE_DIR}/etc
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/log.txt ${CMAKE_CURRENT_SOURCE_DIR}/etc
)
add_custom_target(CopyTask ALL DEPENDS COPY_RES)
add_custom_target生成一个目标CopyTask,该目标依赖于COPY_RES。而对于COPY_RES而言,它实际上是用来复制文件夹或者复制文件的!也就是COMMAND中定义的操作。
SET(CMAKE_INSTALL_PREFIX < install_path >)
要加在 PROJECT(< project_name>) 之后。1.目标文件的安装
install(TARGETS targets... [EXPORT ]
[[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
[DESTINATION ]
[INCLUDES DESTINATION [ ...]]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT ]
[OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP]
] [...])
INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及 文件、目录、脚本等。参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的 目标文件,可能是可执行二进制、动态库、静态库。目标类型也就相对应的有三种,ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME 特指可执行目标二进制。
DESTINATION定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候 CMAKE_INSTALL_PREFIX其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX来 定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是 ${CMAKE_INSTALL_PREFIX}/
INSTALL(TARGETS run dylib staticlib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
上面的例子会将:
可执行二进制run安装到${CMAKE_INSTALL_PREFIX}/bin
目录
动态库libdylib安装到${CMAKE_INSTALL_PREFIX}/lib
目录
静态库libstaticlib安装到${CMAKE_INSTALL_PREFIX}/libstatic
目录
特别注意的是你不需要关心TARGETS具体生成的路径,只需要写上TARGETS名称就可以了。
2、目录的安装
INSTALL(DIRECTORY dirs... DESTINATION
[FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permissions...]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT ]
[[PATTERN | REGEX ]
[EXCLUDE] [PERMISSIONS permissions...]] [...])
这里主要介绍其中的DIRECTORY、PATTERN以及PERMISSIONS参数。
DIRECTORY后面连接的是所在Source目录的相对路径,但务必注意:
abc和abc/有很大的区别。
abc意味着abc这个目录会安装在目标路径下;
abc/意味着abc这个目录的内容会被安装在目标路径下;
如果目录名不以/结尾,那么这个目录将被安装为目标路径下的abc,如果目录名以/结尾, 代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
PATTERN用于使用正则表达式进行过滤,
PERMISSIONS用于指定PATTERN过滤后的文件权限。
install(DIRECTORY build/servers/ DESTINATION deploy/framework/servers
PATTERN "tars*"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)
install(DIRECTORY deploy DESTINATION ./
PATTERN "*.sh"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)
```
将当前Source目录的相对路径build/servers/安装到${CMAKE_INSTALL_PREFIX}/deploy/framework/servers下。