PROJEXT(projectname [CXX] [C] [Java] )
例如:PROJECT (HELLO)
功能:用来定义工程名称,并可指定工程支持的语言,支持列表可以忽略,默认支持所有语言。
该指令使用后隐式的定义了两个变量:
_BINARY_DIR
,表示编译路径,等价于HELLO_BINARY_DIR
_SOURCE_DIR
,表示**工程路径,**等价于HELLO_SOURCE_DIR
此外,cmake系统默认预定义了:
PROJECT_BINARY_DIR
,等价于HELLO_BINARY_DIR
PROJECT_SOURCE_DIR
,等价于HELLO_SOURCE_DIR
两者区别在于:PROJECT永远指向当前工程名字,而另一种方法在修改工程名以后要全部修改,建议用PROJECT
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
例如:SET(SRC_LIST main.c)
功能:SET命令可以用来显示定义变量,在cmake中引用变量的方式是**${}**;
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...)
例如:MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR})
功能:用来向终端输出用户定义的信息
信息的类型包括三类:
SEND_ERROR
:产生错误,生成过程被跳过。SATUS
:输出前缀为“—”的信息。FATAL_ERROR
:立即终止cmake过程。ADD_EXECUTABLE(可执行文件,src1,src2,src3...);
例如:ADD_EXECUTABLE(hello ${SRC_LIST})
功能:定义这个工程生成一个名为hello的可执行文件,相关源文件是SRC_LIST中定义的源文件列表
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
例如:ADD_SUBDIRECTORY(src bin)
功能:用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。EXCLUDE_FROM_ALL
将这个目录从编译过程中排除。
我们可以使用SET
指令来重新定义一下两个变量来指定最终目标二进制的位置:
EXECUTABLE_OUTPUT_PATH
:最终可执行文件的位置LIBRARY_OUTPUT_PATH
:最终库的位置例如:
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
注意:在哪里ADD_EXECUTABLE
或 ADD_LIBRARY
,如果需要改变目标存放路径,就在哪里加入上述的定义。
目标文件的安装:INSTALL(TARGETS targets...)
。
普通文件的安装:INSTALL(FILES files...)
非目标文件的可执行文件的安装:INSTALL(PROGRAMS files...)
目录的安装:INSTALL(DIRECTORY dirs...)
功能:将编译好的文件安装到用户的目录中,通过变量**CMAKE_INSTALL_PREFIX
**可以修改目录起始位置,其默认是/usr/local
,
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
例如:ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
功能:将对应源文件编译成动态、静态库
注:书写库名字时,cmake系统会自动生成libxxx.x
不需要自己写,对应的lib和后缀。
SET_TARGET_PROPERTIES(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...)
功能:设置生成的库的属性
注:cmake在构建一个新的target
时会尝试清楚已经使用这个名字的库,为了回避这个问题可以利用SET_TARGET_PROPERTIES
设置CLEAN_DIRECT_OUTPUT
属性(不过这个现象我没发现。。。):
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
设置动态库版本号和API版本号:
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION
为动态库版本号,SOVERSION
为API版本号
GET_TARGET_PROPERTY(VAR target property)
例如:GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
功能:获取target
的对应属性到变量VAR
。
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
例如:INCLUDE_DIRECTORIES(/usr/include/hello)
功能:引入头文件搜索路径,自己构建的头文件不一定会在linux 默认的搜索路径下,所以需要添加。
CMAKE_INCLUDE_DIRECTORIES_BEFORE
,通过 SET
这个cmake 变量为
on`,可以将添加的头文件搜索路径放在已有路径的前面。AFTER
或者BEFORE
参数,也可以控制是追加还是置前。LINK_DIRECTORIES(directory1 directory2 ...)
例如:INCLUDE_DIRECTORIES(/usr/include/hello)
功能:添加非标准的共享库搜索路径。
注:在工程内部同时存在共享库和可执行二进制,在编译时就需要指定一下这些共享库的路径
TARGET_LINK_LIBRARIES(target library1
例如:TARGET_LINK_LIBRARIES(main libhello.a)
功能:用来为 arget
添加需要链接的共享库,可以是可执行文件也可以是共享库
一般使用${}
进行变量引用,在IF
语句中直接使用变量名而不是${}
取值。
PROJECT
指令后会自动生成_BINARY_DIR
SET
来进行。CMAKE_BINARY_DIR,PROJECT_BINARY_DIR,_BINARY_DIR
:
PROJECT_BINARY_DIR
另外两个有所区别CMAKE_SOOURCE_DIR,PROJECT_SOURCE_DIR,
:
工程顶层目录
。CMAKE_CURRENT_SOURCE_DIR
:
CMAKE_CURRRENT_BINARY_DIR
:
CMAKE_CURRENT_SOURCE_DIR
一致。CMAKE_CURRENT_LIST_FILE
:
CMAKE_CURRENT_LIST_LINE
:
CMAKE_MODULE_PATH
:
EXECUTABLE_OUTPUT_PATH
与LIBRARY_OUTPUT_PATH
:
PROJECT_NAME
:
通过使用$ENV{NAME}
来调用系统的环境变量。
通过使用SET(ENV{NAME} VALUE)
的方式设置环境变量的值。
CMAKE_INCLUDE_CURRENT_DIR
:
CMAKE_CURRENT_BINARY_DIR
和 CMAKE_CURRENT_SOURCE_DIR
到当前处理的CMakeLists.txt
.CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
:
CMAKE_INCLUDE_PATH
和CMAKE_LIBRARY_PATH
:
CMAKE_INCLUDE_PATH
:指定使用FIND_PATH
时的搜索路径,单独设置该变量没有用CMAKE_LIBRARY_PATH
:指定使用FIND_PATH
时的搜索路径,单独设置该变量没有用CMAKE_MAJOR_VERSION
,CMAKE 主版本号,比如 2.4.6 中的 2CMAKE_MINOR_VERSION
,CMAKE 次版本号,比如 2.4.6 中的 4CMAKE_PATCH_VERSION
,CMAKE 补丁等级,比如 2.4.6 中的 6CMAKE_SYSTEM
,系统名称,比如 Linux-2.6.22CMAKE_SYSTEM_NAME
,不包含版本的系统名,比如 LinuxCMAKE_SYSTEM_VERSION
,系统版本,比如 2.6.22CMAKE_SYSTEM_PROCESSOR
,处理器名称,比如 i686.UNIX
,在所有的类 UNIX 平台为 TRUE,包括 OS X 和 cygwinWIN32
,在所有的 win32 平台为 TRUE,包括 cygwinCMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
:
IF ELSE
语句的书写方式。BUILD_SHARED_LIBS
:
ADD_LIBRARY
并没有指定库类型的情况下,默认编译生成的库都是静态库。CMAKE_C_FLAGS
:
ADD_DEFINITIONS()
添加。CMAKE_CXX_FLAGS
:
ADD_DEFINITIONS()
添加。向 C/C++编译器添加-D
定义.
ADD_DEPENDENCIES(target-name depend-target1 depend-target2 ...)
定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。
ENABLE_TESTING()
ENABLE_TESTING
指令用来控制 Makefile 是否构建 test 目标,涉及工程所有目录。
ADD_TEST(testname Exename arg1 arg2 ...)
不知道有什么用,好像是执行生成对应文件的测试,ADD_TEST
只有在调用ENABLE_TESTING
才会生效。
AUX_SOURCE_DIRECTORY(dir VARIABLE)
:
作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表
CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])
指定需要cmake的最低版本。
EXEC_PROGRAM(Executable [directory in which to run] [ARGS ] [OUTPUT_VARIABLE ] [RETURN_VALUE ])
在 CMakeLists.txt 处理过程中执行命令,并不会在生成的 Makefile 中执行。
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])
用来载入 CMakeLists.txt 文件,也用于载入预定义的 cmake 模块,载入的内容将在处理到 INCLUDE 语句是直接执行。
FIND_FILE( name1 path1 path2 ...)
VAR 变量代表找到的文件全路径,包含文件名
FIND_LIBRARY( name1 path1 path2 ...)
VAR 变量表示找到的库全路径,包含库文件名
FIND_PATH( name1 path1 path2 ...)
VAR 变量代表包含这个文件的路径。
FIND_PROGRAM( name1 path1 path2 ...)
VAR 变量代表包含这个程序的全路径。
FIND_PACKAGE(
用来调用预定义在 CMAKE_MODULE_PATH
下的 Find
模块
IF(expression)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ELSE(expression)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDIF(expression)
表达式使用方法:
IF(var)
,如果变量不是:空,0,N, NO, OFF, FALSE, NOTFOUND
或_NOTFOUND
时,表达式为真。IF(NOT var )
,与上述条件相反。IF(var1 AND var2)
,当两个变量都为真是为真。IF(var1 OR var2
),当两个变量其中一个为真时为真。IF(COMMAND cmd)
,当给定的 cmd 确实是命令并可以调用是为真。IF(EXISTS dir)
或者IF(EXISTS file)
,当目录名或者文件名存在时为真。IF(file1 IS_NEWER_THAN file2)
,当 file1 比 file2 新,或者 file1/file2 其中有一个不存在时为真,文件名请使用完整路径。IF(IS_DIRECTORY dirname)
,当 dirname 是目录时,为真。IF(variable MATCHES regex)
,IF(string MATCHES regex)
。当给定的变量或者字符串能够匹配正则表达式 regex 时为真。IF(DEFINED variable)
,如果变量被定义,为真。WHILE(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDWHILE(condition)
真假判断参考IF
.
以列表形式执行:
FOREACH(loop_var arg1 arg2 ...)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
ENDFOREACH(loop_var)
以范围的形式执行:
FOREACH(loop_var RANGE total)
ENDFOREACH(loop_var)
注:以一自增
以范围和步进的方式:
FOREACH(loop_var RANGE start stop [step])
ENDFOREACH(loop_var)
从 start 开始到 stop 结束,以 step 为步进
这些基本的指令使用起来起始很麻烦,为此cmake设计成可扩展模式,可以为一些通用的模块编写扩展cmake,这样以后就可以直接调用而不用自己取写如何编译那些东西,编译的模块化?哈哈哈
每一个模块都会定义以下几个变量
_FOUND
_INCLUDE_DIR
or _INCLUDES
_LIBRARY
or _LIBRARIES
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)
一般使用上面这种结构,先引入模块,再对模块进行相应的操作。
我是地址