cmake使用记录
CMakeLists.txt 文件名
CMakeLists.txt
# 必须的
cmake_minimum_required(VERSION 3.5)
# 设置项目名称
project(<project name>)
# 设置变量 包含源文件
set(CLPEAK_SOURCE_FILES
src/common.cpp
src/clpeak.cpp
src/compute_integer.cpp
src/compute_integer_fast.cpp
src/transfer_bandwidth.cpp
src/kernel_latency.cpp
src/entry.cpp
)
# 添加编译一个可执行文件
add_executable(clpeak ${CLPEAK_SOURCE_FILES})
# 添加编译一个静态库或者动态库
# STATIC 静态库
# SHARE 动态库
add_library(OpenCL STATIC src/libopencl.c)
# 给指定target新增头文件搜索路径
target_include_directories(OpenCL PRIVATE "include")
include_directories(<path>) # 使用这个也可以,不指定target include_directories(${PROJECT_SOURCE_DIR}/include)
# 链接一个库
add_library(<lib>)
link_libraries(<static lib> [<static lib>...])
# 添加 链接库 的路径
link_directories(<path>) # 如 ${CMAKE_CURRENT_BINARY_DIR}/lib
# 链接动态库 也可以链接静态库
target_link_libraries(<target> <lib> ...) # target为需要链接到的目标程序。 lib 为库名,可以多个,空格隔开
add_definitions("-D<p>") #这个p为c或c++中定义的宏,可以用于控制代码的编译
指定库、执行文件的输出路径
set(EXECUTABLE_OUTPUT_PATH ${HOME}/bin) # 指定可执行文件的输出路径
set(LIBRARY_OUTPUT_PATH ${HOME}/lib) # 指定库文件的输出路径
指定c++标准
gcc和g++中指定
g++ *.cpp -std=c++11 -o app
CMakeLists.txt 中指定
#增加-std=c++11
set(CMAKE_CXX_STANDARD 11)
#增加-std=c++14
set(CMAKE_CXX_STANDARD 14)
#增加-std=c++17
set(CMAKE_CXX_STANDARD 17)
作者: 苏丙榅
链接: https://subingwen.cn/cmake/CMake-primer/
来源: 爱编程的大丙
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
变量
# cmake 变量设置
set(VT 1) # 设置普通变量
set(VB "test")
# 设置环境变量
set(ENV{OCL_ROOT} "${SDK_ROOT}")
# 使用变量
set(VC "${VT}") # VC 等于VB
内置变量
CMAKE_CURRENT_SOURCE_DIR: CMakeLists.txt所处文件目录。
变量操作
# 追加
set(变量名1 ${变量名1} ${变量名2} ...) # 对变量名1 进行追加
list(APPEND <list> [<element> ...]) # 例子 list(APPEND SRC_1 ${SRC_1} ${SRC_2} ${TEMP})
# cmake中的list操作,类似于c++ 中 STL库中的deque
# 字符串remove
list(REMOVE_ITEM <list> <value> [<value> ...])
# 获取list长度
list(LENGTH <list> <output variable>)
# 在list末尾追加
list (APPEND <list> [<element> ...])
# 其他
list (POP_BACK <list> [<out-var>...])
list (POP_FRONT <list> [<out-var>...])
宏定义
宏定义可以控制有些代码是否参与编译
g++中指定宏
g++ test.c -DDEBUG -o app
CMakeLists.txt中指定宏
add_definitions(-D宏名称)
# 例子
add_definitions(-DDEBUG)
添加子目录
子目录为一个子模块、库、可执行文件,子目录中需要有cmakelists.txt文件。所有CMakeLists.txt构成树状结构。
add_subdirectory(source_dir ) # 如 add_subdirectory(test) 其中test为一个目录
io操作
file(MAKE_DIRECTORY ${DEPS} ${DEPS_BUILD}) # 创建文件夹
file(WRITE "${DEPS}/CMakeLists.txt" "${CMAKE_LIST_CONTENT}") #创建文件,并写入变量的内容.
# 在指定的路径中搜索指定 后缀的文件
# V 为变量名,不需要提前定义。
# path为路径。suffix为后缀,如cpp等
file(GLOB <V> <path>/.<suffix>)
aux_source_directory(< dir > < variable >) # 搜索某个路径下所有源文件
cmake中执行shell脚本
execute_process(WORKING_DIRECTORY "${DEPS_BUILD}" COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ..)
execute_process() 方法可以执行多个子进程。原型如下:
execute_process(COMMAND <cmd1> [<arguments>]
[COMMAND <cmd2> [<arguments>]]...
[WORKING_DIRECTORY <directory>]
[TIMEOUT <seconds>]
[RESULT_VARIABLE <variable>]
[RESULTS_VARIABLE <variable>]
[OUTPUT_VARIABLE <variable>]
[ERROR_VARIABLE <variable>]
[INPUT_FILE <file>]
[OUTPUT_FILE <file>]
[ERROR_FILE <file>]
[OUTPUT_QUIET]
[ERROR_QUIET]
[COMMAND_ECHO <where>]
[OUTPUT_STRIP_TRAILING_WHITESPACE]
[ERROR_STRIP_TRAILING_WHITESPACE]
[ENCODING <name>]
[ECHO_OUTPUT_VARIABLE]
[ECHO_ERROR_VARIABLE]
[COMMAND_ERROR_IS_FATAL <ANY|LAST>])
命令COMMAND会并行执行,每个子进程的标准输出映射到下一个进程的标准输入上,所有进程共用standard error管道。
各选项的说明:
- COMMAND: 子进程的命令行,直接使用操作系统api执行。可以提供多个command,它们会并行执行。如果需要多个命令顺序执行,可以调用execute_process多次
- WORKING_DIRECTORY:在该目录下执行COMMAND命令
- TIMEOUT:超时时间,过了这个时间,所有子进程会被终止,RESULT_VARIABLE会被设置为“timeout”
- RESULT_VARIABLE:最后一个子进程的返回值(正常是0,异常是其他整数),或者描述发生错误的字符串
- RESULTS_VARIABLE:对应于每个子进程的返回值,使用分号分割的列表
- OUTPUT_VARIABLE:对应于standard output的内容
- ERROR_VARIABLE:对应于standard error的内容
- INPUT_FILE:第一个子进程的standard input
- OUTPUT_FILE:最后一个子进程的standard output
- ERROR_FILE:所有子进程的standard error
- OUTPUT_QUIET/ERROR_QUIET:忽略standard output 和 standard error
- COMMAND_ECHO:重显命令到指定的标准设备,如STDERR、STDOUT、NONE。使用CMAKE_EXECUTE_PROCESS_COMMAND_ECHO变量来修改它的行为
- OUTPUT_STRIP_TRAILING_WHITESPACE/ERROR_STRIP_TRAILING_WHITESPACE:删除空白字符
- ENCODING:在windows系统上指定进程输出时的解码方式,默认是utf-8,其他平台会忽略该参数
- ECHO_OUTPUT_VARIABLE/ECHO_ERROR_VARIABLE:输出将被复制,它将被发送到配置的变量中,也会在标准输出或标准错误中,3.18版本支持
- COMMAND_ERROR_IS_FATAL:触发致命错误并终止进程执行,方式取决于参数。ANY表示任意命令执行失败都触发,LAST表示最后一个进程执行失败才触发,3.19版本支持
引用:原文出处
判断
if(NOT OpenCL_FOUND)
message(FATAL_ERROR "Could not find OpenCL include/libs. Set OCL_ROOT to your OpenCL SDK")
else()
message(STATUS "Selected OpenCL includes from ${OpenCL_INCLUDE_DIRS}")
message(STATUS "Selected OpenCL lib ${OpenCL_LIBRARIES}")
endif()
循环
foreach(item RANGE 10)
message(STATUS "当前遍历的值为: ${item}" )
endforeach()
# 输出
$ cmake ..
-- 当前遍历的值为: 0
-- 当前遍历的值为: 1
-- 当前遍历的值为: 2
-- 当前遍历的值为: 3
-- 当前遍历的值为: 4
-- 当前遍历的值为: 5
-- 当前遍历的值为: 6
-- 当前遍历的值为: 7
-- 当前遍历的值为: 8
-- 当前遍历的值为: 9
-- 当前遍历的值为: 10
-- Configuring done
-- Generating done
-- Build files have been written to: /home/robin/abc/a/build
输出log
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] "message to display" ...)
#例子
# 输出一般日志信息
message(STATUS "source path: ${PROJECT_SOURCE_DIR}")
# 输出警告信息
message(WARNING "source path: ${PROJECT_SOURCE_DIR}")
# 输出错误信息
message(FATAL_ERROR "source path: ${PROJECT_SOURCE_DIR}")