文章目录
CMakeLists的编译
CMakeLists编译原理
CMake主要是编写CMakeLists.txt文件,然后用cmake命令将CMakeLists.txt文件转化为make所需要的makefile文件,最后用make命令编译源码生成可执行程序或共享库(so(shared object))。因此CMake的编译基本就两个步骤:
1. cmake
2. make
cmake 指向CMakeLists.txt所在的目录,例如cmake … 表示CMakeLists.txt在当前目录的上一级目录。cmake后会生成很多编译的中间文件以及makefile文件,所以一般建议新建一个新的目录,专门用来编译,例如
mkdir build
cd build
cmake ..
make
make根据生成makefile文件,编译程序。
文件路径:
.
├── build
├── CMakeLists.txt
├── include
│ └── b.h
└── src
├── b.c
└── main.c
编写CMakeLists.txt
1 #1.cmake verson,指定cmake版本
2 cmake_minimum_required(VERSION 3.2)
3
4 #2.project name,指定项目的名称,一般和项目的文件夹名称对应
5 PROJECT(test_sqrt)
6
7 #3.head file path,头文件目录
8 INCLUDE_DIRECTORIES(
9 include
10 )
11
12 #4.source directory,源文件目录
13 AUX_SOURCE_DIRECTORY(src DIR_SRCS)
14
15 #5.set environment variable,设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
16 SET(TEST_MATH
17 ${DIR_SRCS}
18 )
19
20 #6.add executable file,添加要编译的可执行文件
21 ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_MATH})
22
23 #7.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),就添加该库的名称
24 TARGET_LINK_LIBRARIES(${PROJECT_NAME} m)
编译完成结果
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 3.2.2
│ │ │ ├── CMakeCCompiler.cmake
│ │ │ ├── CMakeCXXCompiler.cmake
│ │ │ ├── CMakeDetermineCompilerABI_C.bin
│ │ │ ├── CMakeDetermineCompilerABI_CXX.bin
│ │ │ ├── CMakeSystem.cmake
│ │ │ ├── CompilerIdC
│ │ │ │ ├── a.out
│ │ │ │ └── CMakeCCompilerId.c
│ │ │ └── CompilerIdCXX
│ │ │ ├── a.out
│ │ │ └── CMakeCXXCompilerId.cpp
│ │ ├── cmake.check_cache
│ │ ├── CMakeDirectoryInformation.cmake
│ │ ├── CMakeOutput.log
│ │ ├── CMakeTmp
│ │ ├── feature_tests.bin
│ │ ├── feature_tests.c
│ │ ├── feature_tests.cxx
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── progress.marks
│ │ ├── TargetDirectories.txt
│ │ └── test_sqrt.dir
│ │ ├── build.make
│ │ ├── C.includecache
│ │ ├── cmake_clean.cmake
│ │ ├── DependInfo.cmake
│ │ ├── depend.internal
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ ├── progress.make
│ │ └── src
│ │ ├── b.c.o
│ │ └── main.c.o
│ ├── cmake_install.cmake
│ ├── Makefile
│ └── test_sqrt
├── CMakeLists.txt
├── include
│ └── b.h
└── src
├── b.c
└── main.c
CMakeLists常用命令
cmake_minimum_required
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vBrWIaj5-1635406583475)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211028150640409.png)]
cmake_minimum_required(VERSION 3.14)
**project命令:**用于指定项目的名称
project(BVTest)
**aux_source_directory: ** 将dir目录下的所有源文件的名字保存在变量中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wuftJoLz-1635406583477)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211028150850892.png)]
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_List) //将src下的文件都保存在SRC_List下
**add_executable: **用于指定从源文件中编译出一个可执行文件并且命名为name
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tveDn9vY-1635406583480)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20211028151036811.png)]
ADD_EXECUTABLE(${PROJECT_NAME} ${DIR_SRCS})
**add_library: ** 用于从指定源文件中编译出一个lib,命名为name
add_library(Lib ${DIR_SRCS})
**target_link_libraries: ** 添加可执行文件所需要的库
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Xml Qt5::SerialPort ${OpenCV_LIBS})
**set : **用于设置变量
set(Qt5 DIR D:/Qt5/5.12.6/..)
**unset : **用于移除变量
unset(VAR CACHE) //移除CACHE
**message : **输出信息
message("hello world")
**include_directories : **设置头文件目录
include_directories(${PROJECT_SOURCE_DIR}/lib)
find_path : 用于查找路径,保存在var
find_path(<var> name1[path1..])
find_library : 用于查找lib,保存在var
find_library(<var> name1[path1..])
**find_package :**寻找包
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Sql Xml Charts SerialPort)
**file : **提供了丰富的目录和文件的操作
file(GLOB_RECURSE HDRS include/.*h)
file(GLOB_RECURSE SRCS src/*.cpp)
CmkeLists的基本步骤
my_add_executable(${PROJECT_NAME} main.cpp ${SRCS} ${HDRS} )
生成可执行文件 注意顺序,不然会有link错误,或未定义的声明
把当前工程目录下的 src 目录的下的所有 .cpp 和 .c 文件赋值给 SRC_LIST
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_LIST)
指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
。。。。。
生成可执行文件 注意顺序,不然会有link错误,或未定义的声明
ADD_EXECUTABLE(CMakeFF ./src/ffplay.c ./src/cmdutils.c main.c)
1.1 CMake版本
每个catkin CMakeList.txt文件都必须以需要的CMake版本。
cmake_minimum_required(VERSION 3.14)
1.2 软件包名称
由CMake项目功能指定的包的名称。这里我们制作一个名为robot_brain的软件包。
project(robot_brain)
1.3 查找相关的CMake包
我们需要使用find_package函数来制定需要找到哪些其他的CMake包来构建我们的项目
find_package(catkin REQUIRED)
对于find_package来说,有两种不同的表达方式分别为:
find_package(catkin REQUIRE COMPONENTS nodelet)
或者
find_package(catkin REQUIRE)
find_package(nodelet REQUIRE)
对于两者的区别。如果通过了find_package找到了一个包,会创建几个提供有关找到的包的消息的Cmake环境变量。
这些环境变量导出了头文件的位置,源文件的位置,包所依赖的库以及这些库的地址。
<NAME>_FOUND-如果找到库,则设置为true,否则为false
<NAME>_INCLUDE_DIR/_INCLUDE-包导出的路径
<NAME>_LIBRARIES/_LIBS-包导出的库
如果find_package作为catkin的组件(例如第一种方式),这是有好处的。
find_package(catkin REQUIRE COMPONENTS nodelet)
这意味着由nodelet导出的include路径,库等也附加到了catkin_变量,这里的变量是上面指示的<NAME>_,反之使用方式二,则路径,库等不会被添加到catkin_变量中。
1.4 设置配置环境
//设置Qt路径
set(Qt5 DIR D:/Qt5.12.6/5.12.6/msvc2015_64/lib/cmake/Qt5/) //.cmake..
//设置opencv路径
set(OpenCV DIR D:/opencv/cv/opencv/build/)
1.5 指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
include_directories(${OpenCV_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(./include)
include_directories(./lib)
1.6 可执行目标
要指定可执行目标,我们必须使用add_executable()CMake函数
add_executable(myProgram src/main.cpp src/some_file.cpp src/another_file.cpp)
这将构建一个名为myProgram的目标可执行文件,由后面的三个源文件构成。
Qt CMakeLists使用案例
cmake_minimum_required(VERSION 3.14)
project(BinocularCamera)
set(Qt5_DIR D:/Qt5.12.6/5.12.6/msvc2015_64/lib/cmake/Qt5/)
set(OpenCV_DIR D:/opencv/cv/opencv/build/)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOUIC_SEARCH_PATHS ./FormFile/)
set(CMAKE_AUTOMOC ON)
#设置工程目录为当前路径
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
function(assign_source_group)
foreach (_source IN ITEMS ${ARGN})
if (IS_ABSOLUTE "${_source}")
file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source}")
else ()
set(_source_rel "${_source}")
endif ()
get_filename_component(_source_path "${_source_rel}" PATH)
string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
source_group("${_source_path_msvc}" FILES "${_source}")
endforeach ()
endfunction(assign_source_group)
function(my_add_executable)
foreach (_source IN ITEMS ${ARGN})
assign_source_group(${_source})
endforeach ()
add_executable(${ARGV})
endfunction(my_add_executable)
find_package(OpenCV REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Sql Xml Charts SerialPort )
file(GLOB_RECURSE HDRS include/*.h)
file(GLOB_RECURSE SRCS src/*.cpp)
file(GLOB PREHEADER stdafx.h)
FILE(GLOB UI_FILES "FormFile/*.ui")
QT5_WRAP_UI(PROJECT_UIS_H ${UI_FILES})
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(./thirdparty/include)
link_directories(./thirdParty/lib)
include_directories(.)
my_add_executable(${PROJECT_NAME} main.cpp ${SRCS} ${HDRS} ${PROJECT_UIS_H} )
#ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${HDRS})
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Xml Qt5::Sql Qt5::Widgets Qt5::Charts ${OpenCV_LIBS}
setupapi CameraDevices Qt5::SerialPort )
#控制台窗口隐掉
#Set_Target_Properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")