CMakeList 编写规则,cmakelist编写规则
CMakeList 编写规则,cmakelist编写规则
Makefilen内容
1. 显示规则:显示规则说明了,如何生成一个或多个目标。这是由Makefile指出要生成的文件和文件依赖的文件。
2. 隐晦规则:基于Makefile的自动推导功能
3. 变量的定义:一般是字符串
4. 文件指示:一般是在Makefile中引用另外一个makefile文件;根据某些规则指定Makefile中有效的部分;多行
5. 注释:#指示注释
#常用变量
$@ ---目标文件
$^ ---所有依赖文件
$< ---第一个依赖文件
.PHONY ---伪目标文件
#常见指令
CMAKE_MINIMUM_REQUIRED(VERSION major[.minor[.patch[.tweak]]] [FATAL_ERROR]) 声明Cmake版本,如果低于指定版本则会停止处理工程文件,并报告错误
PROJECT(PROJECTNAME [CXX] [C] [指定工程支持的语言,如果忽略,表示支持所有语言])
ADD_EXECUTABLE([WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 ...)引入一个名为的可执行目标,该目标会由调用该命令时在源文件列表中指定的源文件来构建。对应于逻辑目标名字,并且在工程范围内必须是全局唯一的
如果构成可执行文件的源文件很多,则最好在MakeFiles中一样指定一个源文件列表
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
PROJECT(Hello)
SET (SRC_LIST main.cpp v4l2_util.cpp tran_data.cpp)
MESSAGE(${SRC_LIST})
ADD_EXECUTABLE(Hello ${SRC_LIST})
ADD_EXECUTABLE:可执行程序由哪些.o文件生成
#编译静态库,并让主程序调用静态库最终生成一个可执行程序
即先生成一个hello.a,再让主程序main.cpp使用libhello.a,最终生成Hello
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
PROJECT(Hello)
SET(LIB_SRC_LIST source1.cpp source2.cpp)
SET(EXEC_SRC_LIST main.cpp)
ADD_LIBRARY(LIB STATIC ${LIB_SRC_LIST})
ADD_EXECUTABLE(Test_Hello ${EXEC_SRC_LIST})
TARGET_LINK_LIBRARIES(Test_Hello LIB)
ADD_LIBRARY(NAME [STATIC| SHARED|MODULE] [EXCLUDE_FROM_ALL] source1, source2,...)
创建一个名字name的库文件,SHARED STATIC 制定生成库的类型
TARGET_LINK_LIBRARIES(target [item1 [item2] [ ...] ]),将给定的库链接到target上
#指定include路径
一般情况下,src和include为同级目录,需要指定include路径src才可以正确定位头文件
SET(INCLUDE_DIRECTORIES " ../include")
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})
#添加第三方库,不需要编译,将他放在resource目录下,需要指定搜索库路径
SET(LINK_DIR "../../resource")
LINK_DIRECTORIES(${LINK_DIR })
LINK_DIRECTORIES(${LINK_DIR }): 指定连接器查找库路径
#创建Release和Debug版本
SET(CMAKE_BUILD_TYPE Release)
SET(CMAKE_BUILD_TYPE Debug)
指定二者模式区别在于
Release: -O3 -DNDEBUG
Debug: -g
也可不加在MakeFiles.txt里面,在产生Makefiles时候才加入
cmake -DCMAKE_BUILD_TYPE=Release
#增加编译和链接选项
CMAKE_C_FLAGS
CMAKE_CXX_FLAGS
CMAKE_EXE_LINKER_FLAGS
分别相当于:CFLAGS, CXXFLAGS, LDFLAGS。
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEMBED")这种写法的好处是,不会覆盖CMAKE_CXX_FLAGS本来的信息。只是把需要添加的内容添加进去
Debug和Release版本:
关键在于三个CMake设置:
CMAKE_BUILD_TYPE
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
当CMAKE_BUILD_TYPE设置为Debug。 则编译时采用CMAKE_CXX_FLAGS_DEBUG。
当CMAKE_BUILD_TYPE设置为Release。 则编译时采用CMAKE_CXX_FLAGS_RELEASE
cmake_minimum_required (VERSION 2.6)
project (CMAKE_Test)
add_executable(CMAKE_Test src/banchmark.cpp)
#set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -Wno-unused-but-set-variable")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -Wno-unused-but-set-variable")
#多目录结构的cmake使用
Hello 实际的目录结构其实并不是所有源码都存放在src目录内。
它的目录结构是:
src: 存放生成库的源码。source1.cpp, source2.cpp
test:存放使用库的测 试程序: main.cpp
include: 存放头文件: source1.h
resource: 存放第三方库
build:存放编译过程的文件
build/lib: 存放生成的libv4l2_utils.so
build/bin:存放main.cpp所产生的测试程序可执行文件。
此时,可以采用顶层目录和每个有源码的目录中均创建CMakeLists.txt的方式来处理(和Makefile处理方式类似)
顶层目录的CMakeLists.txt 内容如下:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(Hello)
ADD_SUBDIRECTORIES(src lib)
ADD_SUBDIRECTORIES(test bin)
ADD_SUBDIRECTORIES([source dir] [bin dir] [exclude_from_all])构建添加一个子路径。source_dir选项指定了CMakeLists.txt源文件和代码文件的位置。如果source_dir是一个相对路径,那么source_dir选项会被解释为相对于当前的目录,但是它也可以是一个绝对路径。binary_dir选项指定了输出文件的路径。如果binary_dir是相对路径,它将会被解释为相对于当前输出路径。
source_dir算相对路径时,是从CMakeLists.txt算起。
所以src指的是当前 CMakeLists.txt所在路径下的src. 而bin, lib 指的是当前输出路径下的bin,lib. 也就是build/bin build/lib
src CMakeLists.txt :
SET(LIB_SRC_LIST source1.cpp)
SET(CMAKE_BUILD_TYPE Release)
INCLUDE_DIRECTORIES(../include)
ADD_LIBRARY(SOURCE1 SHARED ${LIB_SRC_LIST})
test CMakeLists.txt :
SET(EXEC_SRC_LIST main.cpp)
SET(INCLUDE_DIRECTORIES ../include)
SET(LINK_DIR ../../resource)
SET(LINK_DIR "${LINK_DIR} ../../libs/")
SET(CMAKE_BUILD_TYPE Release)
INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})
LINK_DIRECTORIES(${LINK_DIR})
ADD_EXECUTABLE(Test_Hello ${EXEC_SRC_LIST})
TARGET_LINK_LIBRARIES(Test_Hello SOURCE1 )
#显示编译细节
SET(CMAKE_VERBOSE_MAKEFILE ON)
如果不希望改变CMakeLists.txt,可以在创建Makefile时候加入
cmake -DCMAKE_VERBOSE_MAKEFILE=ON
如果连Makefile都不希望修改可以
make VERBOSE=1
#相对路径问题:
set (LIBRARY_DIRECTORIES ../resource)
link_directories(${LIBRARY_DIRECTORIES})
这里会出警告:
This command specifies the relative path
../resource
可以做如下处理:
set (LIBRARY_DIRECTORIES ../resource)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/${LIBRARY_DIRECTORIES})
#FIND_PACKAGE()功能
可以被用来在系统中自动查找配置构建工程所需的程序库。在linux和unix类系统下这个命令尤其有用。CMake自带的模块文件里有大半是对各种常见开源库的find_package支持,支持库的种类非常多.
FIND_PACKAGE(Qt5Widgets)
FIND_PACKAGE( [version] [EXACT] [QUIET] [[REQUIRED|COMPONENTS] [components...]] [NO_POLICY_SCOPE])
查找并加载外来工程的设置。该命令会设置_FOUND变量,用来指示要找的包是否被找到了。如果这个包被找到了,与它相关的信息可以通过包自身记载的变量中得到。REQUIRED选项表示如果报没有找到的话,cmake的过程会终止,并输出警告信息
在REQUIRED选项之后,或者如果没有指定REQUIRED选项但是指定了COMPONENTS选项,在它们的后面可以列出一些与包相关的部件清单(components list)。
FIND_PACKAGE
每一个模块都会产生如下变量,_FOUND _INCLUDE_DIR _LIBRARY或者_LILBRARIES
如果_FOUND为真,_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中
就会有相应的变量Qt5Widgets_FOUND,Qt5Widgets_INCLUDE_DIRS等相应的变量生效。
PKG_CHECK_MODULES讲解
PKG_CHECK_MODULES(<PREFIX> [REQUIRED] [QUIET] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] <MODULE> [<MODULE>]*)
检测所有给出的modules
PKG_CHECK_MODULES(PC_OPENNI2 libopenni2)
if (NOT PC_OPENNI2_FOUND)
PKG_CHECK_MODULES(PC_OPENNI2 REQUIRED openni2)
endif()
PC_OPENNI2_INCLUDE_DIRS, PC_OPENNI2_LIBRARY_DIRS 等被设置。
评论暂时关闭