CMake 教程
CMake 是开源、跨平台的构建工具,可以让我们通过编写简单的配置文件去生成本地的CMakeList.txt ,这个配置文件是独立于运行平台和编译器的,这样就不用亲自去编写Makefile了,而且配置文件可以直接拿到其它平台上使用,无需修改,非常方便。
参考网站:
[1] Cmake官网
[2] Cmake github网址
[3] Cmake Documentation
[4] Linux下CMake简明教程
[5] Modern CMake 简体中文版
0. CMake安装及卸载
- sh文件安装
sudo sh cmake-3.22.3-linux-x86_64.sh --prefix=/usr/local --exclude-subdir
- apt-get 方式
sudo apt-get install cmake
- 源代码方式
wget https://github.com/Kitware/CMake/releases/download/v3.22.3/cmake-3.22.3.tar.gz
tar -zxvf cmake-3.22.3.tar.gz
cd cmake-3.22.3.tar.gz
./bootstrap --parallel=32
make -j32
make install -j32
ln -s /usr/local/bin/cmake /usr/bin/cmake
cmake --version
- CMake 卸载
sudo apt-get autoremove cmake
1. 创建简单的实例
#include <iostream>
int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
cmake_minimum_required(VERSION 3.13)
project(cmake_study)
set(CMAKE_CXX_STANDARD 11)
add_executable(cmake_study src/main.cpp)
-
文件列表 -
CMake 编译
mkdir build
cd build
cmake ..
make
./cmake_study
2. CMake 重要参数
project(MyProject)
执行:project(MyProject),就是定义了一个项目的名称为:MyProject,对应的就会生成两个变量:_BINARY_DIR和_SOURCE_DIR,但是cmake中其实已经有两个预定义的变量:PROJECT_BINARY_DIR和PROJECT_SOURCR_DIR ;
cmake ./
make
mkdir build
cd ./build
cmake ../
make
aux_sourcr_directory(<dir> <variable>)
aux_sourcr_directory(. DIR_SRCS)
add_executable(exename srcname)
add_executable(Demo ${DIR_SRCS})
./Demo
add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
说明:
libname : 生成的库文件的名字
[SHARED|STATIC|MODULE] :生成库文件的类型(动态库|静态库|模块)
[EXCLUDE_FROM_ALL] :有这个参数表示该库不会被默认构建
source1 source2 … sourceN: 生成库依赖的源文件
add_library(ALib SHARE alib.cpp)
aux_sourcr_directory(. DIR_SRCS)
add_library(ALib STATIC ${DIR_SRCS})
-
添加头文件目录
target_include_directories(<target> [SYSTEM] [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …])
include_directories("/opt/MATLAB/R2012a/extern/include")
引入opencv头文件和库说明:
按照此路径,cmake可以找到一个opencv的设置文件OpenCVConfig.cmake ,其中预定义变量OpenCV_INCLUDE_DIRS ,OpenCV_VERSION ,OpenCV_LIBS
cmake_minimum_required( VERSION 3.15 )
project( mainwindow )
set( CMAKE_CXX_FLAGS "-std=c++11" )
set(OpenCV_DIR /home/ubuntu/opt/opencv-3.4.6/release)
find_package( OpenCV 3 REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( mainwindow mainwindow.cpp )
target_link_libraries( mainwindow ${OpenCV_LIBS} )
参考 :
使用CMake构建OpenCV项目
Linux 使用cmake构建OpenCV项目
target_link_libraries(<target> [item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
link_libraries()
link_libraries(("/opt/MATLAB/R2012a/bin/glnxa64/ ")
set_target_properties()
set_target_properties(target1 target2 ... PROPERTIES 属性名称1 值 属性名称2 值 ... )
-
变量与缓存
变量的名称通常大写 ;
set(MY_VARIABLE "value")
${MY_VARIABLE}
缓存变量就是cache变量,相当于全局变量;
set(MY_CACHE_VALUE "cache_value" CACHE INTERNAL "THIS IS MY CACHE VALUE")
-
CMake 基本语法 不太完善后续补充一下
if (expression)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
else (expression)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
endif (expression)
WHILE(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDWHILE(condition)
FOREACH(loop_var arg1 arg2 ...)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDFOREACH(loop_var)
AUX_SOURCE_DIRECTORY(. SRC_LIST)
FOREACH(F ${SRC_LIST})
MESSAGE(${F})
ENDFOREACH(F)
?
3. 构建项目结构
.
├── CMakeList.txt
├── include/
│ ├── CMakeList.txt
│ ├── includeA.h
│ └── includeB.h
├── lib/
│ ├── CMakeList.txt
│ ├── libA.c
│ └── libB.c
└── main.cpp
project(main)
cmake_minium_required(VERSION 2.8)
aux_source_directories(. DIR_SRC)
include_directories(include)
add_executable(main ${DIR_SRC})
add_subdirectories(lib)
target_link_libraries(main test)
aux_source_director(. DIR_LIB)
add_libraries(test ${DIR_LIB})
4. CMakeList.txt 模板
cmake_minimum_required(VERSION 3.5)
project(main)
if(CMAKE_COMPILER_IS_GNUCC)
message("COMPILER IS GNUCC")
ADD_DEFINITIONS ( -std=c++11 )
endif(CMAKE_COMPILER_IS_GNUCC)
find_package(Protobuf REQUIRED)
if(PROTOBUF_FOUND)
message(STATUS "protobuf library found")
else()
message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()
include_directories(${PROTOBUF_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${CMAKE_SOURCE_DIR}/include/protobuf/proto/config.proto)
message(${PROTO_HDRS})
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/protobuf)
set(CUDA_DIR "/usr/local/cuda")
find_package(CUDA)
SET(CUDA_NVCC_FLAGS --disable-warnings;-std=c++11;-O3;-gencode arch=compute_75,code=sm_75)
message(${CUDA_NVCC_FLAGS})
link_directories("/usr/local/lib")
include_directories("/usr/local/include/opencv4")
link_directories("")
include_directories(/data/wuh/software/TensorRT-5.1.2.2/include)
link_directories(/data/wuh/software/TensorRT-5.1.2.2/lib)
link_directories(/data/wuh/project/test_algorithm_module/algorithm_module/build/)
LINK_LIBRARIES(algorithm)
function(include_sub_directories_recursively root_dir)
if (IS_DIRECTORY ${root_dir})
message("include dir: " ${root_dir})
include_directories(${root_dir})
endif()
file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*)
foreach(sub ${ALL_SUB})
if (IS_DIRECTORY ${root_dir}/${sub})
include_sub_directories_recursively(${root_dir}/${sub})
endif()
endforeach()
endfunction()
include_sub_directories_recursively(${CMAKE_SOURCE_DIR}/include)
MESSAGE(STATUS "CMAK_SOURCE_DIR" ${CMAKE_SOURCE_DIR})
FILE(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/src/*.cu ${CMAKE_SOURCE_DIR}/src/*.cpp)
LINK_LIBRARIES(opencv_ml opencv_objdetect opencv_imgproc opencv_core opencv_highgui opencv_imgcodecs opencv_shape opencv_videoio opencv_video)
LINK_LIBRARIES(nvcaffe_parser nvinfer nvinfer_plugin nvparsers)
LINK_LIBRARIES(avcodec avformat swscale avutil)
LINK_LIBRARIES(cuda nvcuvid)
LINK_LIBRARIES(glog)
AUX_SOURCE_DIRECTORY(test DIR_SRCS)
SET(ALL_SRCS ${DIR_SRCS} ${PROTO_SRCS} ${SOURCE_FILES} ${M_INCLUDE_FILES})
CUDA_ADD_EXECUTABLE(${PROJECT_NAME} ${ALL_SRCS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PROTOBUF_LIBRARIES})
target_link_libraries(${PROJECT_NAME} /usr/local/cuda-10.1/lib64/libcudart.so)
target_link_libraries(${PROJECT_NAME} /usr/local/cuda-10.1/lib64/libcudnn.so)
文件目录结构; ├── CMakeLists.txt ├── fileA/ │ ├── CMakeLists.txt │ ├── fileA.cpp │ └── fileA.h ├── fileB/ │ ├── CMakeLists.txt │ ├── fileB.cpp │ └── fileB.h └── main.cpp
#include <iostream>
#include "fileA.h"
#include "fileB.h"
int main()
{
fileA();
fileB();
return 0;
}
cmake_minimum_required(VERSION 2.8.3)
project (cmake_files)
include_directories(./fileA ./fileB)
set(FILEA_SRC fileA/fileA.cpp)
set(FILEB_SRC fileB/fileB.cpp)
add_executable(cmake_files main.cpp ${FILEA_SRC} ${FILEB_SRC})
#ifndef FILEA_H
#define FILEA_H
#include <iostream>
void fileA();
#endif
#include "fileA.h"
#include<iostream>
void fileA()
{
std::cout<<"FileA--Start"<<std::endl;
}
aux_source_directory(. DIR_FILEA_SRCS)
add_library(fileA ${DIR_FILEA_SRCS})
#ifndef FILEB_H
#define FILEB_H
#include <iostream>
void fileB();
#endif
#include "fileB.h"
#include<iostream>
void fileB()
{
std::cout<<"FileB--Start"<<std::endl;
}
aux_source_directory(. DIR_FILEB_SRCS)
add_library(fileB ${DIR_FILEB_SRCS})
|