目录
一、概述与安装
二、编译源文件
三、无关文件管理
一、概述与安装
CMake是一个跨平台的项目构建工具,相比于Makefile,CMake更加高级,因为CMake代码在执行的时候是会先翻译生成Makefile文件,再调用Makefile文件完成项目构建,这就像是高级语言和低级语言之间的关系。
Makefile虽然也支持在不同的平台上运行,但是不同平台上进行项目构建的Makefile代码是不一样的,也就是说不具备Makefile代码不具备跨平台性,所以CMake的出现便是帮Makefile解决了这个问题,因为CMake可以根据不同的平台生成不同的Makefile文件。
Linux系统CMake直接命令行安装:yum install -y cmake
Windows系统CMake安装地址:https://cmake.org/files/
选择对应版本的 x86_64.msi 文件下载运行,安装的时候选择添加系统环境变量:
# 在PowerShell上检查是否安装成功PS C:\Users\pheonixFly> cmake --version
cmake version 3.28.0-rc1CMake suite maintained and supported by Kitware (kitware.com/cmake).
PS C:\Users\pheonixFly>
二、编译源文件
// add.h#pragma once
int add(int a, int b);
// sub.h#pragma once
int sub(int a, int b);
// add.cpp#include "add.h"int add(int a, int b) {return a + b;
}
// add.cpp#include "sub.h"int sub(int a, int b) {return a - b;
}
# CMakeLists.txt 文件代码cmake_minimum_required(VERSION 2.8)
# 指定使用的 cmake 的最低版本
# 可选,非必须,如果不加可能会有警告project(MATH)
# 定义工程名称,
# 并可指定工程的版本、工程描述、web主页地址、支持的语言(默认情况支持所有语言),
# 如果不需要这些都是可以忽略的,只需要指定出工程名字即可。add_executable(math.exe add.cpp sub.cpp main.cpp)
# add_executable(可执行程序名 源文件名称)
# 定义工程会生成一个可执行程序
# 源文件名可以是一个也可以是多个,如有多个可用空格或分号间隔
# 执行 cmake . 命令,生成 Makefile 文件
# 执行新生成的 Makefile 文件(base) [root@localhost 10_test]# tree .
.
├── add.cpp
├── add.h
├── CMakeLists.txt
├── main.cpp
├── sub.cpp
└── sub.h0 directories, 6 files
(base) [root@localhost 10_test]# cmake .
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test
(base) [root@localhost 10_test]# tree .
.
├── add.cpp
├── add.h
├── CMakeCache.txt
├── CMakeFiles
│ ├── 2.8.12.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
│ ├── Makefile2
│ ├── Makefile.cmake
│ ├── math.exe.dir
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── DependInfo.cmake
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ └── progress.make
│ ├── progress.marks
│ └── TargetDirectories.txt
├── cmake_install.cmake
├── CMakeLists.txt
├── main.cpp
├── Makefile ################ 新生成的 Makefile 文件
├── sub.cpp
└── sub.h6 directories, 32 files
(base) [root@localhost 10_test]# make
Scanning dependencies of target math.exe
[ 33%] Building CXX object CMakeFiles/math.exe.dir/add.cpp.o
[ 66%] Building CXX object CMakeFiles/math.exe.dir/sub.cpp.o
[100%] Building CXX object CMakeFiles/math.exe.dir/main.cpp.o
Linking CXX executable math.exe
[100%] Built target math.exe
(base) [root@localhost 10_test]# tree .
.
├── add.cpp
├── add.h
├── CMakeCache.txt
├── CMakeFiles
│ ├── 2.8.12.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
│ ├── Makefile2
│ ├── Makefile.cmake
│ ├── math.exe.dir
│ │ ├── add.cpp.o
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── CXX.includecache
│ │ ├── DependInfo.cmake
│ │ ├── depend.internal
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ ├── main.cpp.o
│ │ ├── progress.make
│ │ └── sub.cpp.o
│ ├── progress.marks
│ └── TargetDirectories.txt
├── cmake_install.cmake
├── CMakeLists.txt
├── main.cpp
├── Makefile ################ 新生成的 Makefile 文件
├── math.exe ################ 新生成的 math.exe 文件
├── sub.cpp
└── sub.h6 directories, 38 files
(base) [root@localhost 10_test]# ./math.exe
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost 10_test]#
# CMake 生成的 Makefile 文件代码# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 2.8# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target#=============================================================================
# Special targets provided by cmake.# Disable implicit rules so canonical targets will work.
.SUFFIXES:# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =.SUFFIXES: .hpux_make_needs_suffix_list# Suppress display of executed commands.
$(VERBOSE).SILENT:# A target that is always out of date.
cmake_force:
.PHONY : cmake_force#=============================================================================
# Set environment variables for the build.# The shell in which to execute make rules.
SHELL = /bin/sh# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake# The command to remove a file.
RM = /usr/bin/cmake -E remove -f# Escaping for special characters.
EQUALS = =# The program to use to edit the cache.
CMAKE_EDIT_COMMAND = /usr/bin/ccmake# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /root/gitee/Test/Make_Learn/10_test# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /root/gitee/Test/Make_Learn/10_test#=============================================================================
# Targets provided globally by CMake.# Special rule for the target edit_cache
edit_cache:@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."/usr/bin/ccmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast# Special rule for the target rebuild_cache
rebuild_cache:@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast# The main all target
all: cmake_check_build_system$(CMAKE_COMMAND) -E cmake_progress_start /root/gitee/Test/Make_Learn/10_test/CMakeFiles /root/gitee/Test/Make_Learn/10_test/CMakeFiles/progress.marks$(MAKE) -f CMakeFiles/Makefile2 all$(CMAKE_COMMAND) -E cmake_progress_start /root/gitee/Test/Make_Learn/10_test/CMakeFiles 0
.PHONY : all# The main clean target
clean:$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean# The main clean target
clean/fast: clean
.PHONY : clean/fast# Prepare targets for installation.
preinstall: all$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall# Prepare targets for installation.
preinstall/fast:$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast# clear depends
depend:$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend#=============================================================================
# Target rules for targets named math.exe# Build rule for target.
math.exe: cmake_check_build_system$(MAKE) -f CMakeFiles/Makefile2 math.exe
.PHONY : math.exe# fast build rule for target.
math.exe/fast:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/build
.PHONY : math.exe/fastadd.o: add.cpp.o
.PHONY : add.o# target to build an object file
add.cpp.o:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/add.cpp.o
.PHONY : add.cpp.oadd.i: add.cpp.i
.PHONY : add.i# target to preprocess a source file
add.cpp.i:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/add.cpp.i
.PHONY : add.cpp.iadd.s: add.cpp.s
.PHONY : add.s# target to generate assembly for a file
add.cpp.s:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/add.cpp.s
.PHONY : add.cpp.smain.o: main.cpp.o
.PHONY : main.o# target to build an object file
main.cpp.o:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/main.cpp.o
.PHONY : main.cpp.omain.i: main.cpp.i
.PHONY : main.i# target to preprocess a source file
main.cpp.i:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/main.cpp.i
.PHONY : main.cpp.imain.s: main.cpp.s
.PHONY : main.s# target to generate assembly for a file
main.cpp.s:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/main.cpp.s
.PHONY : main.cpp.ssub.o: sub.cpp.o
.PHONY : sub.o# target to build an object file
sub.cpp.o:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/sub.cpp.o
.PHONY : sub.cpp.osub.i: sub.cpp.i
.PHONY : sub.i# target to preprocess a source file
sub.cpp.i:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/sub.cpp.i
.PHONY : sub.cpp.isub.s: sub.cpp.s
.PHONY : sub.s# target to generate assembly for a file
sub.cpp.s:$(MAKE) -f CMakeFiles/math.exe.dir/build.make CMakeFiles/math.exe.dir/sub.cpp.s
.PHONY : sub.cpp.s# Help Target
help:@echo "The following are some of the valid targets for this Makefile:"@echo "... all (the default if no target is provided)"@echo "... clean"@echo "... depend"@echo "... edit_cache"@echo "... math.exe"@echo "... rebuild_cache"@echo "... add.o"@echo "... add.i"@echo "... add.s"@echo "... main.o"@echo "... main.i"@echo "... main.s"@echo "... sub.o"@echo "... sub.i"@echo "... sub.s"
.PHONY : help#=============================================================================
# Special targets to cleanup operation of make.# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system
三、无关文件管理
通过上面的例子可以看出,在执行 cmake 命令的时候,会在当前目录生成一些与项目执行无关的目录和文件,如果再基于 Makefile 执行 make,还会生成更过的中间件文件,这样会导致整个项目变得混乱和难以管理,所以我们需要将通过 cmake 生成的新文件都统一放到一个目录里面进行管理,这个目录通常叫做 build。
(base) [root@localhost 10_test]# mkdir build
(base) [root@localhost 10_test]# cd build
(base) [root@localhost build]# cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/gitee/Test/Make_Learn/10_test/build
(base) [root@localhost build]# tree .
.
├── CMakeCache.txt
├── CMakeFiles
│ ├── 2.8.12.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
│ ├── Makefile2
│ ├── Makefile.cmake
│ ├── math.exe.dir
│ │ ├── build.make
│ │ ├── cmake_clean.cmake
│ │ ├── DependInfo.cmake
│ │ ├── depend.make
│ │ ├── flags.make
│ │ ├── link.txt
│ │ └── progress.make
│ ├── progress.marks
│ └── TargetDirectories.txt
├── cmake_install.cmake
└── Makefile ####################### 在 build 目录下的 Makefile 文件 6 directories, 26 files
(base) [root@localhost build]# cd ..
(base) [root@localhost 10_test]# ls
add.cpp add.h build CMakeLists.txt main.cpp sub.cpp sub.h
(base) [root@localhost 10_test]# cd build/
(base) [root@localhost build]# make
Scanning dependencies of target math.exe
[ 33%] Building CXX object CMakeFiles/math.exe.dir/add.cpp.o
[ 66%] Building CXX object CMakeFiles/math.exe.dir/sub.cpp.o
[100%] Building CXX object CMakeFiles/math.exe.dir/main.cpp.o
Linking CXX executable math.exe
[100%] Built target math.exe
(base) [root@localhost build]# tree ..
..
├── add.cpp
├── add.h
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ │ ├── 2.8.12.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
│ │ ├── Makefile2
│ │ ├── Makefile.cmake
│ │ ├── math.exe.dir
│ │ │ ├── add.cpp.o
│ │ │ ├── build.make
│ │ │ ├── cmake_clean.cmake
│ │ │ ├── CXX.includecache
│ │ │ ├── DependInfo.cmake
│ │ │ ├── depend.internal
│ │ │ ├── depend.make
│ │ │ ├── flags.make
│ │ │ ├── link.txt
│ │ │ ├── main.cpp.o
│ │ │ ├── progress.make
│ │ │ └── sub.cpp.o
│ │ ├── progress.marks
│ │ └── TargetDirectories.txt
│ ├── cmake_install.cmake
│ ├── Makefile ####################### 在 build 目录下的 Makefile 文件
│ └── math.exe ####################### 在 build 目录下的 math.exe 文件
├── CMakeLists.txt
├── main.cpp
├── sub.cpp
└── sub.h7 directories, 38 files
(base) [root@localhost build]# ./math.exe
10 + 5 = 15
10 - 5 = 5
(base) [root@localhost build]#
这样就可以在 build 目录中执行 make 命令编译项目,生成的相关文件自然也就被存储到 build 目录中了。这样通过 cmake 和 make 生成的所有文件就全部和项目源文件分离了。