# CmakeLists.txt示例
PROJECT(HELLO)
SET(SRC_LIST main.c)
MESSAGE(STATUS "this is binary dir" ${HELLO_BINARY_DIR})
MESSAGE(STATUS "this is source dir" ${HELLO_SOURCE_DIR})
ADD_EXECUTABLE(hello ${SRC_LIST})
###指令1
PROJECT(projectname [CXX] [C] [Java])
# 1.隐式定义两个cmake变量:_BINARY_DIR 和_SOURCE_DIR
# 2.采用内部编译,两个变量所指目录皆为工程所在目录
# 3.系统自动定义PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR,其和1中变量一样;
# 采用外部编译,则目录为编译所在文件夹。
###指令2
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
# 1.显式的定义变量,也可以定义多个源文件如SET(SRC_LIST main.c t1.c t2.c)
###指令3
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display")
# 1.用于向终端输出用户定义信息,包含3种类型:SEND_ERROR(产生错误 生成过程被跳过)
# STATUS(输出前缀为_的信息) FATAL_ERROR(立即终止所有cmake过程)
###指令4
ADD_EXECUTABLE(HELLO ${SRC_LIST})
# 1.定义此工程生成一个名为hello的可执行文件,相关源文件就是变量SRC_LIST中的源文件列表
# 源码文件夹中的CMakeLists.txt示例
ADD_EXECUTABLE(hello main.c)
# 工程中CMakeList.txt示例
PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)
###指令1
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
# 1.用于向当前工程添加存放源文件的子目录,并指定中间二进制或者目标二进制存放的位置。
# 2.EXCLUDE_FROM_ALL将这个目录从编译过程中排除。
# 3.编译目录指定为build/bin;如果不指定编译结果将保存在build/src中;前面有build是因为在build目录中进行的编译。
# 4.SUBDIRS指令和ADD_SUBDIRECTORY类似,但不推荐使用;其可以一次添加多个子目录,如:SUBDIRS(dir1 dir2 ...)
# 5.无论是SUBDIRS还是ADD_SUBDIRECTORY指令(无论是否指定编译输出目录),都可以通过SET指令重新定义EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量---来指定最终目标二进制的位置。
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
# 1. 将输出目录和编译目录关联起来。(见上段代码指令1的第五条解释)
# 2. 两条命令的位置:是写在工程的CMakeLists.txt还是写在src目录的CMakeLists.txt?
# 原则是ADD_EXECUTABLE或者ADD_LIBRARY在哪定义,此命令就在哪里加入。
# MakeFile样式:
DESTDIR=
install:
mkdir -p ${DESTDIR}/usr/bin
install -m 755 hello ${DESTDIR}/usr/bin
# 1.可以通过make install安装在/usr/bin目录。
# 2.也可以通过make install DESTDIR=/tmp/test安装在/tmp/test/usr/bin目录,打包时常用此方式。
DESTDIR=
PREFIX=/usr
install:
mkdir -p ${DESTDIR}/${PREFIX}/bin
install -m 755 hello ${DESTDIR}/${PREFIX}/bin
# 1. 编译时使用命令cmake -D CMAKE_INSTALL_PREFIX=/usr
# INSTALL指令解析(目标文件安装)
INSTALL(TARGETS targets...
[
[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS permissions ...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[OPTIONAL]
]
[...]
)
# 1.TARGETS后面跟的就是通过ADD_EXECUTABLE或者ADD_LIBRARY定义的目标文件
# ARCHIVE:静态库 LIBRARY:动态库 RUNTIME:可执行目标二进制
# 2.DESTINATION定义了安装路径,如果以/开头,指绝对路径,此时CMAKE_INSTALL_PREFIX无效
# 如果希望使用CMAKE_INSTALL_PREFIX,需要写成相对路径
# 例子
INSTALL(TARGETS myrun mylib mystaticlib
RUNTIME DESTNATION bin
LIBRARY DESTNATION lib
ARCHIVE DESTNATION libstatic
)
# 1.将可执行二进制myrun安装到${CMAKE_INSTALL_PREFIX}/bin目录
# 2.将动态库mylib安装到${CMAKE_INSTALL_PREFIX}/lib目录
# 3.将静态库mystaticlib安装到${CMAKE_INSTALL_PREFIX}/libstatic目录
普通文件安装:
# 指令解析(普通文件安装)
INSTALL(FILES files ...
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...] ]
[COMPONENT <component>]
[RENAME <name>]
[OPTIONAL]
)
# 1.用于安装一般文件,并可指定访问权限,文件名时此指令所在路径下的相对路径。
# 默认权限为OWNER_WRITE, OWNER_READ, GROUP_READ, WORLD_READ 即644权限
非目标文件可执行程序安装(比如脚本类):
# 指令解析(非目标可执行程序)
INSTALL(PROGRAMS files...
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...] ]
[COMPONENT <component>]
[RENAME <name>]
[OPTIONAL]
)
# 1.跟上面普通文件安装方法一样,唯一不同的是默认安装后的权限:
# OWNER_EXECUTE, GROUP_EXECUTE,WORLD_EXECUTE 即755权限
目录安装:
# 目录安装:
INSTALL(DIRECTORY dirs...
[DESTINATION <dir>]
[FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permisssions...]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|...] ]
[COMPONENT <component>]
[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE]
[PERMISSIONS permissions...]
[...]
)
# 1.DIRECORY后面连接的是所在Source目录的相对路径,但注意abc和abc/差别巨大:
# 目录名不以/结尾,这个目录将被安装为目标路径下的abc
# 目录名以/结尾,代表将这个目录的内容安装到目标路径,但是不包括这个目录本身
# 2.PATTERN用于使用正则表达式进行过滤。
# 示例
INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj
PATTERN "CSV" EXCLUDE
PATTERN "scripts/*"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ
)
# 1.将icons目录和scripts/目录中的内容都安装到/share/myproj
# 2.安装内容不包含目录名为CSV的目录,并对文件指定权限
修改hello world支持安装
CMAKE_INSTALL_PREFIX默认安装目录是/usr/local
# ADD_LIBRARY指令解析
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL])
# 1.libname无需写全,只需填入hello,即可生成libhello.so文件。
# 2.SHARED:动态库 STATIC:静态库 MODULE:在使用dyld的系统有效,如果不支持dyld,则被当作SHARED对待。
# 3.EXCLUDE_FROM_ALL参数意思是这个库不会被默认构建,除非有其他的组件依赖或者手工构建。
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static STATIC ${LIBHELLO_SRC})
# SET_TARGET_PROPERTIES指令解析
SET_TARGET_PROPERTIES(target1 target2...
PROPERTIES prop1 value1 prop2 value2)
# 1.这条指令可用于设置输出名称,对于动态库,还可以用来指定动态库版本和API版本。
# 2.据说在构建libhello.a时,会清理掉其它使用这个名字的库,即libhello.so。(测试时并未遇到这种现象) 如果遇到的话:
# 使用指令:SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
# 和指令:SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)来解决。
ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static STATIC ${LIBHELLO_SRC})
GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
MESSAGE(STATUS "this is the hello_static OUTPUT_NAME:"${OUTPUT_VALUE})
# GET_TARGET_PROPERTY指令解析:
1. 与SET_TARGET_PROPERTIES指令对应,获取属性。
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
# 指令解析
# 1. VERSION指动态库版本,SOVERSION指API版本。
INSTALL(TARGET hello hello_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
INSTALL(FILES hello.h DESTINATION include/hello)
# 1.注意静态库需要使用ARCHIVE关键字。
# 2.通过
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
make install
# 就可以将头文件和共享库安装到系统目录/usr/lib 和 /usr/include/hello中。
INCLUDE_DIRECTORIES([AFTER | BEFORE] [SYSTEM] dir1 dir2 ...)
# 指令解析:
# 1.本指令用来向工程添加多个特定头文件的搜索路径;路径之间用空格分开;如果路径之间包含了空格,可以使用双引号
# 将它括起来;默认是追加到当前头文件搜索路径的后面;
# 可使用CMAKE_INCLUDE_DIRECTORIES_BEFORE=on控制追加在前面。
LINK_DIRECTORIES(directory1 directory2 ...)
TARGET_LINK_LIBRARIES(target library1 <debug|optiimized> library2 ...)
# 指令解析:
# 1.TARGET_LINK_LIBRARIES(main hello)也可以写成
# TARGET_LINK_LIBRARIES(main libhello.so)
# 这两个变量需要用bash中export命令 或者csh中set命令进行设置。
CMAKE_INCLUDE_PATH=/home/include/...
FIND_PATH(myHeader hello.h)
IF(myHeader)
INCLUDE_DIRECTORIES(${myHeader})
ENDIF
# 1.FIND_PATH用来搜索指定路径中的文件名。
# 2.FIND_LIBRARY用来搜索CMAKE_LIBRARY_PATH中的动态库的路径。