cmake教程

随便记

cmake -DCMAKE_INSTALL_PREFIX= //设置安装路径

静态库:ARCHIVE
动态库:LIBRARY
可执行文件:RUNTIME

locate libpthread.so //搜索libpthread.so的位置

set(CMAKE_STATIC_LIBRARY_PREFIX “”) //cmake 去除库名称前面的lib前缀

set(CMAKE_VERBOSE_MAKEFILE ON) //显示gcc详细编译参数

在哪里使用add_executable 或add_library 在哪里之后link动态库或静态库,install

基础语法:

1,变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
2,指令(参数 1 参数 2…) 参数使用括弧括起,参数之间使用空格或分号分开
3,指令是大小写无关的,参数和变量是大小写相关的。但,推荐你全部使用大写指令

常用变量:

<projectname>_BINARY_DIR: 指代编译路径
<projectname>_SOURCE_DIR: 指代工程路径

PROJECT_BINARY_DIR: 指代编译路径
PROJECT_SOURCE_DIR: 指代工程路径
CMAKE_CURRENT_SOURCE_DIR: 指代当前CMakeLists.txt文件所在路径
EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH:重新定义最终结果的存放目录
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCT: 用来控制 IF ELSE 语句的书写方式

cmake 调用环境变量的方式:

$ENV{} //取环境变量值,ENV需大写
设置环境变量的方式是:
SET(ENV{变量名} 值)

ADD_DEFINITIONS:

向 C/C++编译器添加-D 定义,比如:
ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间用空格分割。
如果你的代码中定义了#ifdef ENABLE_DEBUG #endif,这个代码块就会生效。
如果要添加其他的编译器开关,可以通过 CMAKE_C_FLAGS 变量和 CMAKE_CXX_FLAGS 变
量设置

ENABLE_TESTING

ENABLE_TESTING 指令用来控制 Makefile 是否构建 test 目标,涉及工程所有目录。语
法很简单,没有任何参数,ENABLE_TESTING(),一般情况这个指令放在工程的主
CMakeLists.txt 中。

ADD_TEST

ADD_TEST(testname Exename arg1 arg2 …)
testname 是自定义的 test 名称,Exename 可以是构建的目标文件也可以是外部脚本等
等。后面连接传递给可执行文件的参数。如果没有在同一个 CMakeLists.txt 中打开
ENABLE_TESTING()指令,任何 ADD_TEST 都是无效的。

例如:
ADD_TEST(mytest ${PROJECT_BINARY_DIR}/bin/main)
ENABLE_TESTING()

AUX_SOURCE_DIRECTORY

AUX_SOURCE_DIRECTORY(dir VARIABLE)
作用是发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来
自动构建源文件列表
AUX_SOURCE_DIRECTORY(. SRC_LIST)

EXEC_PROGRAM

EXEC_PROGRAM(Executable [directory in which to run]
[ARGS <arguments to executable>]
[OUTPUT_VARIABLE <var>]
[RETURN_VALUE <var>])
用于在指定的目录运行某个程序,通过 ARGS 添加参数,如果要获取输出和返回值,可通过
OUTPUT_VARIABLE 和 RETURN_VALUE 分别定义两个变量.
这个指令可以帮助你在 CMakeLists.txt 处理过程中支持任何命令,比如根据系统情况去
修改代码文件等等。

例如:
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)

FILE

文件操作指令,基本语法为:
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

用来载入 CMakeLists.txt 文件,也用于载入预定义的 cmake 模块.
INCLUDE(file1 [OPTIONAL])
INCLUDE(module [OPTIONAL])
OPTIONAL 参数的作用是文件不存在也不会产生错误。
你可以指定载入一个文件,如果定义的是一个模块,那么将在 CMAKE_MODULE_PATH 中搜
索这个模块并载入

FIND 相关指令:

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( [major.minor] [QUIET] [NO_MODULE]
[[REQUIRED|COMPONENTS] [componets…]])
用来调用预定义在 CMAKE_MODULE_PATH 下的 Find.cmake 模块,你也可以自己
定义 Find<name>模块,通过 SET(CMAKE_MODULE_PATH dir)将其放入工程的某个目录
中供工程使用,我们在后面的章节会详细介绍 FIND_PACKAGE 的使用方法和 Find 模块的
编写。
FIND_LIBRARY 示例:
FIND_LIBRARY(libX X11 /usr/lib)
IF(NOT libX)
MESSAGE(FATAL_ERROR “libX not found”)
ENDIF(NOT libX)

add_link_options

设置LDFLAGS=“-lrt”, 对应的cmake设置是:
add_link_options(“-lrt”)

控制指令:

IF

基本语法为:
IF(expression)

THEN section.

COMMAND1(ARGS …)
COMMAND2(ARGS …)

ELSE(expression)

ELSE section.

COMMAND1(ARGS …)
COMMAND2(ARGS …)

ENDIF(expression)

另外一个指令是 ELSEIF,总体把握一个原则,凡是出现 IF 的地方一定要有对应的
ENDIF.出现 ELSEIF 的地方,ENDIF 是可选的

IF(var),如果变量不是:空,0,N, NO, OFF, FALSE, NOTFOUND 或
<var>_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(“hello” MATCHES “ell”)
MESSAGE(“true”)
ENDIF(“hello” MATCHES “ell”)
IF(variable LESS number)
IF(string LESS number)
IF(variable GREATER number)
IF(string GREATER number)
IF(variable EQUAL number)
IF(string EQUAL number)
数字比较表达式
IF(variable STRLESS string)
IF(string STRLESS string)
IF(variable STRGREATER string)
IF(string STRGREATER string)
IF(variable STREQUAL string)
IF(string STREQUAL string)
按照字母序的排列进行比较.
IF(DEFINED variable),如果变量被定义,为真。

FOREACH

FOREACH 指令的使用方法有三种形式:
1,列表
FOREACH(loop_var arg1 arg2 …)
COMMAND1(ARGS …)
COMMAND2(ARGS …)

ENDFOREACH(loop_var)
像我们前面使用的 AUX_SOURCE_DIRECTORY 的例子
AUX_SOURCE_DIRECTORY(. SRC_LIST)
FOREACH(F S R C L I S T ) M E S S A G E ( {SRC_LIST}) MESSAGE( SRCLIST)MESSAGE({F})
ENDFOREACH(F)
2,范围
FOREACH(loop_var RANGE total)
ENDFOREACH(loop_var)
从 0 到 total 以1为步进
举例如下:
FOREACH(VAR RANGE 10)
MESSAGE(${VAR})
ENDFOREACH(VAR)
最终得到的输出是:
0
1
2
3
4
5
6
7
8
9
10
3,范围和步进
FOREACH(loop_var RANGE start stop [step])
ENDFOREACH(loop_var)
从 start 开始到 stop 结束,以 step 为步进,
举例如下
FOREACH(A RANGE 5 15 3)
MESSAGE(${A})
ENDFOREACH(A)
最终得到的结果是:
5
8
11
14

INSTALL指令:

目标文件安装:

INSTALL(TARGETS targets…
[[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS permissions…]
[CONFIGURATIONS
[Debug|Release|…]]
[COMPONENT <component>]
[OPTIONAL]
] […])

DESTINATION 定义了安装的路径,如果路径以/开头,那么指的是绝对路径, 否则是相对路径
多个TARGETS 用空格分开

普通文件安装:

INSTALL(FILES files… DESTINATION <dir>
[PERMISSIONS permissions…]
[CONFIGURATIONS [Debug|Release|…]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])

FILES目标默认的PERMISSIONS权限为:
OWNER_WRITE, OWNER_READ,GROUP_READ,WORLD_READ, 即644权限。

非目标的可执行程序安装:

INSTALL(PROGRAMS files… DESTINATION <dir>
[PERMISSIONS permissions…]
[CONFIGURATIONS [Debug|Release|…]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
PROGRAMS目标默认的PERMISSIONS权限为:
OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE, 即755权限。

目录安装:

INSTALL(DIRECTORY dirs… DESTINATION <dir>
[FILE_PERMISSIONS permissions…]
[DIRECTORY_PERMISSIONS permissions…]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|…]]
[COMPONENT <component>]
[[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE] [PERMISSIONS permissions…]] […])

DIRECTORY 后面连接的是所在 源码 目录的相对路径。
如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾,
代表将这个目录中的内容安装到目标路径,但不包括这个目录本身
PATTERN 用于使用正则表达式进行过滤,PERMISSIONS 用于指定 PATTERN 过滤后的文件
权限
示例:
INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj
PATTERN “CVS” EXCLUDE
PATTERN “scripts/*”
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
GROUP_EXECUTE GROUP_READ)

安装时 CMAKE 脚本的执行:

INSTALL([[SCRIPT <file>] [CODE <code>]] […])
SCRIPT 参数用于在安装时调用 cmake 脚本文件(也就是.cmake 文件)
CODE 参数用于执行 CMAKE 指令,必须以双引号括起来。比如:
INSTALL(CODE “MESSAGE(“Sample install message.”)”)

ADD_LIBRARY指令:

SET(LIBRARY_OUTPUT_PATH <路径>)来指定一个新的lib输出位置

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

SET_TARGET_PROPERTIES 用来修改生成目标文件属性。
例如,修改输出文件名称:
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME “hello”)

GET_TARGET_PROPERTY(VAR target property)
例如:
GET_TARGET_PROPERTY(OUTPUT_VALUE hello_static OUTPUT_NAME)
MESSAGE(STATUS “This is the hello_static
OUTPUT_NAME:”${OUTPUT_VALUE})

实现动态库版本号:
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION 指代动态库版本,SOVERSION 指代 API 版本

结果:
libhello.so.1.2
libhello.so ->libhello.so.1
libhello.so.1->libhello.so.1.2

添加静态库或动态库:

INCLUDE_DIRECTORIES指令:

INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径
中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的
后面,你可以通过两种方式来进行控制搜索路径添加的方式

LINK_DIRECTORIES指令:

LINK_DIRECTORIES(directory1 directory2 …)
添加非标准的共享库搜索路径

将LINK_DIRECTORIES放在ADD_EXECUTABLE之前。

TARGET_LINK_LIBRARIES指令:

TARGET_LINK_LIBRARIES(target library1
<debug | optimized> library2
…)
用来为 target 添加需要链接的共享库

window下链接动态库时, 所链接的动态库需要将符号导出, 也可以使用以下方式:

if (MSVC)
    set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
    set(BUILD_SHARED_LIBS TRUE)
endif ()

增加静态库:

find_library ( <VAR> name | NAMES name1 [name2 …] [NAMES_PER_DIR] [HINTS [path | ENV var]… ] [PATHS [path | ENV var]… ] [REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)] [PATH_SUFFIXES suffix1 [suffix2 …]] [DOC “cache documentation string”] [NO_CACHE] [REQUIRED] [NO_DEFAULT_PATH] [NO_PACKAGE_ROOT_PATH] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_SYSTEM_PATH] [NO_CMAKE_INSTALL_PREFIX] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH] )

例如:
find_library(LIB_NAMES name xxx PATHS “${PROJECT_BINARY_DIR/lib}”)
TARGET_LINK_LIBRARIES(hello ${LIB_NAMES})

使用qt

find_package(Qt5 COMPONENTS Core Widgets)

qt的模块:
3DAnimation Help QuickWidgets
3DCore LinguistTools RemoteObjects
3DExtras Location RepParser
3DInput Multimedia Scxml
3DLogic MultimediaWidgets Sensors
3DQuick Network SerialPort
3DQuickAnimation Nfc Sql
3DQuickExtras OpenGL Svg
3DQuickInput OpenGLExtensions Test
3DQuickRender Positioning TextToSpeech
3DQuickScene2D PositioningQuick UiPlugin
3DRender PrintSupport UiTools
AndroidExtras Qml WebChannel
Bluetooth Quick WebSockets
Concurrent QuickCompiler WebView
Core QuickControls2 Widgets
Gamepad QuickTemplates2 Xml
Gui QuickTest XmlPatterns

cmake和swig

FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS “-c++”)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
#SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS “-includeall”)
SWIG_ADD_MODULE(example python example.i example.cxx)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值