C/C++学习笔记 CMake 与 Make有什么区别?

一、什么是编译?

编译器是一种将源代码翻译成机器码的程序。代码的编译包括几个步骤,包括预处理、编译和链接,以创建可在其目标计算机上直接运行的库或可执行文件。

​ 这个编译过程也称为构建过程,这是 CMake 和Make发挥作用的地方。 ​

CMake 和 Make 之间的主要区别之一是 CMake 创建的输出可供 Make 等构建系统使用。这意味着 CMake 充当其他构建系统的生成器,并不负责实际编译。相比之下,Make 的输出是可以在目标计算机上执行的已编译二进制文件。

另外CMake 附带一个 GUI,可用于配置项目。GUI 是命令行的替代品,特别是当需要以可视化方式执行命令时。相比之下,Make 是一个纯粹的命令行工具,不提供任何类型的 GUI。

二、CMake 和 Make 的工作原理

CMake 和 Make 将构建程序所需的所有命令放在 Makefile或CMakeLists.txt文件中,而无需每次都输入它们,从而节省时间。

Make是一个控制从程序源文件生成可执行文件和其他非源文件的工具。它从名为 Makefile 的文件中获取有关如何构建程序的说明。

CMake 需要一个CMakeLists.txt文件,并且是一个跨平台的 Make。这意味着它可以在不同的操作系统上运行。它允许独立于编译器的构建、测试、打包和安装软件。需要注意的是,CMake 为其他系统生成构建文件;但是,它本身并不是一个构建系统。CMake 可以生成 Makefile,然后可以在正在工作的平台上将生成的 Makefile 与 Make 一起使用:

三、一个简单实例

1、程序文件

该程序由三个文件组成:main.cppage.cppprocess_age.h。

main.cpp

复制代码
# include "process_age.h"
# include <iostream>

int main(){
    std::cout << "Hello, Earthly!\n";
    processAge();
    return 0;
}

age.cpp

复制代码
# include <iostream>
using namespace std;

void processAge(){
    int age;

    cout << "Please enter your age: ";
    cin >> age;

    cout << "You are " << age << " years old.\n";

process_age.h

复制代码
void processAge();

2、使用 Make 进行构建

要使用 Make 构建项目,您必须创建一个 Makefile。Makefile 条目通常具有以下格式:

复制代码
target: dependencies
<tab>    command

对于此示例,Makefile 的内容将如下所示:

复制代码
hello_age: hello.o age.o
    g++ hello.o age.o -o hello_age
    
hello.o: hello.cpp
    g++ -c hello.cpp
    
age.o: age.cpp
    g++ -c age.cpp
    
clean:
    rm *.o hello_age

从上面我们可以看到,我们有hello_age它依赖于 hello.o 和 age.o 对象。hello.o 和 age.o 对象分别由 hello.cpp 和 age.cpp 源文件创建。

创建 Makefile 后,四个文件现在应该位于目录中:

要使用 Make 运行此程序,请make在终端中运行。这将使用g++ 编译器编译文件,该编译器应该已安装在计算机上。此命令的输出将是hello_age可执行文件:

接下来,运行命令./hello_age,它将运行可执行文件并打印出"Hello, Earthly!"。然后它会提示输入年龄。对于给定的年龄"50",它将打印以下内容:

复制代码
Hello, Earthly!
Please enter your age: 50
You are 50 years old.

运行应用程序后,可以通过运行命令来清理创建的文件了,方法是运行make命令make clean,从目录中删除age.omain.ohello_age

3、使用CMake 进行构建

首先创建一个名为hello_cmake的目录,并放入三个文件:age.cppmain.cppprocess_age.h

然后在hello_cmake目录中,创建两个名为build-unixbuild-windows的目录。CMake 创建的所有内容都将放置在这些目录中,它们有助于分离源文件和 CMake 创建的文件。build-unix在 Unix 系统上运行的构建需要 ,build-windows在 Windows 系统上需要 。

接下来,创建一个名为 的文件CMakeLists.txt,即 CMake 配置文件。它包含用于构建程序的指令:

复制代码
cmake_minimum_required(VERSION 3.10.0)

#project name
project (hello_cmake)

add_executable(hello_age main.cpp age.cpp)

该CMakeLists.txt文件包含一组指令和说明,描述项目的源文件和目标。上面的内容以cmake_minimun_required(VERSION 3.10.0)开头,指定可用于处理项目的 CMake 的最低版本。

在本例中,您需要 3.10.0 版本,否则会报告错误。

project(hello_cmake)指定传递给命令的项目的名称,并添加从指定源文件(即和)构建的add_executable(hello_age main.cpp age.cpp)名为的可执行目标。

如果使用 Unix 系统,请到build-unix文件夹​​并运行以下命令:

复制代码
cmake ..

这将构建项目并在build-unix文件夹中创建一个 Makefile:

Makefile 现已创建。要编译应用程序,请运行以下make命令将hello-age可执行文件放入build-unix目录中:

复制代码
 make

简而言之,CMake 和 Make 的区别在于,Make 从源文件创建可执行文件,而源文件必须包含 Makefile。相反,使用 CMake 时,CMakeLists.txt会提供一个文件,用于创建 Makefile。然后,此 Makefile 与 Make 一起使用,创建可运行的可执行文件。

四、跨平台与单一平台

CMake 和 Make 之间的另一个区别是 CMake 是跨平台的,而 Make 是单平台的。使用 CMake,您可以在不同平台上使用相同的命令构建相同的程序。

上面的例子在Windows机器上,复制目录hello_cmake,然后build-windows使用命令提示符导航到该目录:

复制代码
cmake ..

这将为 Windows Visual Studio构建系统构建 C++ 代码:

复制代码
-- Building for: Visual Studio 15 2017
-- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.18363.
-- The C compiler identification is MSVC 19.16.27043.0
-- The CXX compiler identification is MSVC 19.16.27043.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/CMake_vs_Make/hello_cmake/build-windows

会生成类似如下的内容

接下来,使用 Visual Studio Code 打开hello_cmake.sln文件或在命令提示符中编译它。要编译它,只需确保MSBuild.exe在路径中。然后从build-windows文件夹中运行以下命令:

复制代码
MSBuild.exe hello_age.vcxproj

上述代码将构建项目,会创建三个目录:Debug、、hello_age.dirWin32。在目录中找到可执行文件Debug,我们就可以直接运行

复制代码
hello_age.exe

如上所述,可以在基于 Unix 的系统和基于 Windows 的系统上运行相同的命令,以使用 CMake 创建构建系统,这使得 CMake 与平台无关。生成输出后,可以使用任何构建系统来构建应用程序。在本例中,Make 用于基于 Unix 的平台,MSBuild 用于 Windows。

相关推荐
꧁坚持很酷꧂30 分钟前
Linux Ubuntu18.04下安装Qt Craeator 5.12.9(图文详解)
linux·运维·qt
李菠菜39 分钟前
解决Windows系统下Git克隆时报错“unable to checkout working tree”的方法详解
windows·git
凉、介1 小时前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci
电鱼智能的电小鱼1 小时前
EFISH-SBC-RK3588无人机地面基准站项目
linux·网络·嵌入式硬件·机器人·无人机·边缘计算
电鱼智能的电小鱼1 小时前
基于 EFISH-SBC-RK3588 的无人机环境感知与数据采集方案
linux·网络·嵌入式硬件·数码相机·无人机·边缘计算
小诸葛的博客2 小时前
详解Linux中的定时任务管理工具crond
linux·运维·chrome
一默19912 小时前
CentOS 7.9升级OpenSSH到9.9p2
linux·运维·centos
keep intensify2 小时前
Linux常用指令
linux·服务器·php
带电的小王3 小时前
sherpa-ncnn:Linux(x86/ARM32/ARM64)构建sherpa-ncnn --语音转文本大模型
linux·语音识别·实时音视频·sherpa-ncnn
沧浪之水!3 小时前
【Linux网络】:套接字之UDP
linux·网络·udp