这里有个写的非常好的cmake入门教程!!!
cmake中有很多已经定义好的默认变量,要知道其代表什么并且可以使用它们。这里假设我们的项目路径在/project
中,而编译后文件的存放位置为/project/build。
PROJECT_SOURCE_DIR | 当前项目的路径,即为/project |
PROJECT_BINARY_DIR | 项目编译后存放的路径/project/build |
CMAKE_CURRENT_BINARY_DIR | 与PROJECT_BINARY_DIR基本相同 |
CMAKE_CURRENT_SOURCE_DIR | 与PROJECT_SOURCE_DIR基本相同 |
CMAKE_POSITION_INDEPENDENT_CODE | 设置为ON时,告诉编译器生成与路径无关代码。常用在动态库中使用 |
CMAKE_CXX_FLAGS | 指C++编译器。可以通过修改它选择C++编译的参数 |
CMAKE_C_FLAGS | 指C编译器。可以通过修改它选择C编译的参数 |
LIBRARY_OUTPUT_PATH | 生成的库文件路径 |
一个案例:
# 大小写不严格区分
# cmake verson,指定cmake版本
cmake_minimum_required(VERSION 3.0.0)
# set():用来显式的定义变量
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # 添加-fPIC编译,即:装成一个动态库(Linux为.so扩展文件;windows为.dll扩展文件)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") # CMAKE_CXX_FLAGS:设置 C++ 编译选项。带-Wall和-Wextra进行编译(作用是提示错误或警告)
set(CUDA_TOOLKIT_ROOT_DIR /usr/local/cuda) # 定义cuda路径变量
# project name,指定项目的名称,一般和项目的文件夹名称对应
project(smart)
add_definitions(-std=c++11) # 添加支持c++11特征
# find_package(CUDA)
find_package(OpenCV REQUIRED) # 它找到OpenCV程序库之后,就会帮助我们预定义几个变量,OpenCV_FOUND、OpenCV_INCLUDE_DIRS、OpenCV_LIBRARY_DIRS、OpenCV_LIBRARIES,
# 它们分别指是否找到OpenCV,OpenCV的头文件目录,OpenCV的库文件目录,OpenCV的所有库文件列表
if (NOT OpenCV_FOUND)
message(FATAL_ERROR "opencv not found")
endif (NOT OpenCV_FOUND)
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
add_subdirectory(src) # 指定的文件夹加到build任务列表中
命令语法:project(<projectname> [languageName1 languageName2 … ] )
命令简述:用于指定项目的名称
使用范例:project(Main)
命令语法:cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]][FATAL_ERROR])
命令简述:用于指定需要的 CMake 的最低版本
使用范例:cmake_minimum_required(VERSION 2.8)
命令语法:aux_source_directory(<dir> <variable>)
命令简述:用于将 dir 目录下的所有源文件的名字保存在变量 variable 中
使用范例:aux_source_directory(. DIR_SRCS)
命令语法:add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN)
命令简述:用于指定从一组源文件 source1 source2 … sourceN 编译出一个可执行文件且命名为 name
使用范例:add_executable(Main ${DIR_SRCS})
命令语法:add_library([STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1source2 … sourceN)
命令简述:用于指定从一组源文件 source1 source2 … sourceN 编译出一个库文件且命名为 name
使用范例:add_library(Lib ${DIR_SRCS})
命令语法:add_dependencies(target-name depend-target1 depend-target2 …)
命令简述:用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。这里的目标必须是 add_executable、add_library、add_custom_target 命令创建的目标
命令语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
命令简述:用于添加一个需要进行构建的子目录
使用范例:add_subdirectory(Lib)
命令语法:set(<variable> <value> [[CACHE <type><docstring> [FORCE]] | PARENT_SCOPE])
命令简述:用于设定变量 variable 的值为 value。如果指定了 CACHE 变量将被放入 Cache(缓存)中。
使用范例:set(ProjectName Main)
命令语法:unset(<variable> [CACHE])
命令简述:用于移除变量 variable。如果指定了 CACHE 变量将被从 Cache 中移除。
使用范例:unset(VAR CACHE)
命令语法:message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] “message todisplay”…)
命令简述:用于输出信息
使用范例:message(“Hello World”)
命令语法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
命令简述:用于设定目录,这些设定的目录将被编译器用来查找 include 文件
使用范例:include_directories(${PROJECT_SOURCE_DIR}/lib)
命令语法:find_path(<VAR> name1 [path1 path2 …])
命令简述:用于查找包含文件 name1 的路径,如果找到则将路径保存在 VAR 中(此路径为一个绝对路径),如果没有找到则结果为 <VAR>-NOTFOUND。
默认的情况下,VAR 会被保存在 Cache 中,这时候我们需要清除 VAR 才可以进行下一次查询(使用 unset 命令)。
使用范例:
find_path(LUA_INCLUDE_PATH lua.h${LUA_INCLUDE_FIND_PATH})
if(NOT LUA_INCLUDE_PATH)
message(SEND_ERROR "Header file lua.h not found")
endif()
命令语法:find_library(<VAR> name1 [path1 path2 …])
命令简述:用于查找库文件 name1 的路径,如果找到则将路径保存在 VAR 中(此路径为一个绝对路径),如果没有找到则结果为 <VAR>-NOTFOUND。
命令语法:add_definitions(-DFOO -DBAR …)
命令简述:用于添加编译器命令行标志(选项),通常的情况下我们使用其来添加预处理器定义
使用范例:add_definitions(-D_UNICODE -DUNICODE)
file:文件操作命令
1..................
file(GLOB variable [RELATIVE path] [globbingexpressions]...)
GLOB 会产生一个由所有匹配globbing表达式的文件组成的列表,并将其保存到变量中。Globbing 表达式与正则表达式类似,但更简单。
如果指定了RELATIVE 标记,返回的结果将是与指定的路径相对的路径构成的列表。(通常不推荐使用GLOB命令来从源码树中收集源文件列表。
原因是:如果CMakeLists.txt文件没有改变,即便在该源码树中添加或删除文件,产生的构建系统也不会知道何时该要求CMake重新产生构建文件)
globbing表达式包括:
*.cxx- match all files with extension cxx
*.vt? - match all files with extension vta,...,vtz
f[3-5].txt - match files f3.txt,f4.txt, f5.txt
2..................
file(WRITE filename "message towrite"... )
WRITE 将一则信息写入文件’filename’中,如果该文件存在,它会覆盖它,如果不存在,它会创建该文件。
3..................
file(APPEND filename "message to write"... )
APPEND 如同WRITE,区别在于它将信息内容追加到文件末尾。
4..................
file(READ filename variable [LIMIT numBytes] [OFFSEToffset] [HEX])
READ 会读取文件的内容并将其存入到变量中。它会在给定的偏移量处开始读取最多numBytes个字节。如果指定了HEX参数,
二进制数据将会被转换成十进制表示形式并存储到变量中。