前言
对于C++工程开发,免不了的过程就是编译链接最后生成可执行文件。那么make和cmake命令则是必不可少的,对应的规则文件则是Makefile和CMakeList.txt。
介绍
从gcc到make,再到cmake,一切只为了工程生成可执行文件的过程更简单。
gcc
make底层调用的是gcc(GNU Compiler Collection,GNU编译器套件),可以简单的认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等)。当工程只有一个源文件时,可以直接用gcc命令编译。但是当工程包含很多个源文件时,我们便需要make这个工具了。
make与Makefile
make可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式,通过调用Makefile文件中用户指定的命令来进行编译和链接的。
常用的调用方法:
make -j8
Makefile文件中则是指定了make调用编译器去编译源文件的命令。
Makefile示例一览:
Makefile在一些简单的工程中可以自己编写,但是当工程文件特别多的时候,写Makefile就变得很麻烦。而且这么写的Makefile还不能跨平台。这时候Cmake工具开始出现。
cmake与CMakeLists.txt
cmake通过一系列规则来生成Makefile文件供make使用。这个规则文件则是CMakeLists.txt。CMake允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程。所以通常在一个复杂的工程编译过程中,一般会先写CMakeLists.txt,然后执行cmake指令生成Makefile,最后再执行make指定进行编译链接。
一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等。
如下则是OpenCV中的根CMakeLists.txt内容:
使用示例
以GitHub工程pybind11_guidedfilter_cuda示例,展示CMakeLists.txt编写到make执行。
完整的CMakeLists.txt内容如下:
#Change this if you need to target a specific CMake version
cmake_minimum_required(VERSION 2.8)
# Enable C++11
set(CMAKE_CXX_STANDARD 11)
# Set up project
project(guided_filter_cuda)
add_subdirectory(pybind11)
SET(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/guidedfilter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ndarray_converter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ndarray_converter.h
)
pybind11_add_module(gfcuda ${SOURCES})
# Detect and add OpenCV
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
find_package(OpenCV REQUIRED HINTS /usr/local/share/opencv4)
find_package(CUDA 10.2 REQUIRED)
# Define sources and executable
set(EXECUTABLE_NAME "gfcuda")
# Link against OpenCV
include_directories(${OpenCV_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE_NAME} PRIVATE ${OpenCV_LIBS})
# Link against CUDA
include_directories(${CUDA_INCLUDE_DIRS})
target_link_libraries(${EXECUTABLE_NAME} PRIVATE ${CUDA_LIBRARIES})
主要是set、find_package、include_directories、target_link_libraries等命令的使用。
set方法用于给变量设置值。find_package用于查找已安装的库。include_directories添加文件夹到包含路径。target_link_libraries用于链接库文件。更多命令的使用可以参考官方文档或其他参考资料。
在编写好CMakeLists.txt后,进入创建好的build目录,执行cmake ..
生成Makefile,然后执行make
。最终会生成可以被导入的.so文件。
参考资料
[1] GNU Make
[2] About CMake
[3] 5分钟理解make/makefile/cmake/nmake
[4] CMake 入门实战
[5] Linux平台CUDA+OpenCV3.4配置
[6] GitHub - TracelessLe / pybind11_guidedfilter_cuda
[7] Cmake入门之——Set方法(六)
[8] CMake之find_package
[9] CMake » latest release (3.19.3) Documentation
[10] 【使用CMake组织C++工程】2:CMake 常用命令和变量