名词辨析

GNU

  • GNU's Not Unix!的递归缩写
  • 一个自由的操作系统,起源于GNU计划,希望发展出一套完整的开放源代码操作系统来取代Unix
  • 基本组成包括:

GCC

  • GNU Compiler Collection, GNU编译器套装
  • 有多种语言前端,可用于解析不同的编程语言、操作系统、计算机系统结构,是GNU计划的关键部分,也是GNU工具链的主要组成部分之一
  • 可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada,Go等语言

gcc/g++/MinGW

  • gcc: GCC中的GUN C Compiler(C 编译器)
  • g++: GUN C++ Compiler(C++编译器)
  • MinGW: Minimalist GNU for Windows,是将GCC编译器和GNU Binutils移植到Win32平台下的产物

但根据GCC的gcc和g++区别的说法,gcc和g++并不是编译器,它们只是一种驱动器[1],它们会根据参数中要编译的文件的类型,调用对应的GUN编译器。以编译C语言为例,包含以下过程。

Step1:Call a preprocessor, like cpp.

Step2:Call an actual compiler, like cc or cc1.

Step3:Call an assembler, like as.

Step4:Call a linker, like ld

因此gcc带参数个人理解就是去单独调用上面提及的一些工具,由此来说gcc更像是一种工具的封装,通过参数实现具体的工具调用

两者的联系和区别

对于 *.c文件,gcc当做c文件看待,g++当做cpp文件看待

虽然gcc和g++都可以编译*.c文件,但是二者会以不同的语言来对待c文件,而C++ 标准和 C 语言标准的语法要求是有区别的。

#include <stdio.h>
int main()
{
const char * a = "abc";
printStr(a);
return;
}
int printStr(const char* str)
{
printf(str);
}

以上代码使用gcc进行编译,其会看为c语言,编译结果为



以上代码使用g++进行编译,其会看为c++,编译结果为



由此可见,c++的语言要求会更高一些

对于 *.cpp文件,gcc当做cpp文件看待,g++当做cpp文件看待

虽然二者都会以cpp文件来对待,但是对于调用某些标准库中现有的函数或者类对象的c++程序,而单纯的 gcc 命令无法自动链接这些标准库文件,无法完成编译

MSVC

  • Microsoft Visual C++,is a compiler for the C, C++ and C++/CX programming languages by Microsoft

LLVM

LLVM最初是指Low Level Virtual Machine,是类似但不同于jvm的一种虚拟机,现在来说,有很多理解方式,可以说LLVM是编译器的工具链的集合,Clang是使用LLVM的编译器;又或者说LLVM是一个优秀的编译器框架,它也采用经典的三段式设计

根据编译原理可以了解到,在GCC中前端和后端的分界并非明显,这就导致出现下面的情况,一种语言的前端对对应多个后端



而LLVM架构通过引入LLVM IR(Intermediate Representation)解决了这一问题,形成的LLVM架构如下图所示

clang/clang++

是LLVM项目中的一个子项目,是基于LLVM架构的轻量级编译器,属于整个LLVM架构中的编译器前端(由LLVM架构图可得知)

创造目的是为了替代GCC,提供更快的编译速度

make

make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令利用gcc(或g++)来进行编译和链接。当程序只有一个源文件时,可以直接使用用gcc(或g++)命令进行编译。但当程序包含多个源文件时,逐文件去编译,编译顺序可能出现混乱同时工作量较大

cmake

makefile在一些简单的工程中可以人工书写,但当工程较大时,手写makefile较为麻烦,同时更换平台需要修改makefile,cmake工具可以根据CMakeLists.txt文件去生成makefile,过程如下图所示

构建流程

1.配置项目:cmake -S . -B buildctrl + shift + p > cmake configure

2.构建项目:cmake --build buildctrl + shift + p > cmake build

// cmake最低版本
cmake_minimum_required(VERSION 3.0.0) // 工程文件名
project(experiment2 VERSION 0.1.0) // 寻找第三方库
// c++包管理工具vcpkg(类似pip,使用时再查找)
find_package(库名称 REQUIRED(库是必须的,未安装则报错)) // 匹配所有源文件添加到变量SRC_FILES中
file(GLOB SRC_FILES
"${PROJECT_SOURCE_DIR}/src/*.h"
"${PROJECT_SOURCE_DIR}/src/*.cpp"
"${PROJECT_SOURCE_DIR}/src/*.cc"
"${PROJECT_SOURCE_DIR}/src/*.c"
) # 这里只是设置两个变量,并没有指定这个路径
set(INC_DIR include目录路径) # 设置include路径变量
set(LINK_DIR 库目录路径) # 设置library路径变量 # 指定include和lib路径
include_directories(${INC_DIR})
link_directories(${LINK_DIR}) # 链接静态库,在下一步构建可执行文件之前
# 需要理解的是上一步只是指示了头文件和库的路径,程序还需要显示包含
# 头文件往往都是在程序中再include,lib可以在程序中指明,但一般是直接在这里写上,程序中就不再添加代码了
link_libraries(库名称) # 构建可执行文件
# ${CMAKE_PROJECT_NAME}:被替换为project指定的名称
# ${SRC_FILES}:file命令找到的所有源文件
add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES}) # 链接动态库(Link),需要在上一步构建可执行文件之后
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE 库名称) // 支持c++17
target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE cxx_std_17) // 自动化工作
// 需要使用再详细查找
add_custom_command(
TARGET ${CMAKE_PROJECT_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"")

CMakeLists示例

此示例用于winPcap开发

cmake_minimum_required(VERSION 3.0.0)
project(experiment2 VERSION 0.1.0) file(GLOB SRC_FILES
"${PROJECT_SOURCE_DIR}/*.cpp"
) set(INC_DIR E:/useful/cmake_project/WpdPack/Include)
set(LINK_DIR E:/useful/cmake_project/WpdPack/Lib/x64) include_directories(${INC_DIR})
link_directories(${LINK_DIR}) link_libraries(Packet wpcap) add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES})

参考

编译流程

以gcc为例

  1. 预处理(预编译):头文件包含,条件编译,宏替换,删除注释
  2. 编译:词法,语法,语义分析,生成汇编代码
  3. 汇编:将汇编语言转化为相应的机器语言(二进制目标文件)
  4. 链接[2]:将多个可重定位目标文件和标准库函数合并为可执行目标文件

  1. 关于驱动器的说法,目前只在gcc/g++链接选项一文中看到相关说法

  2. 详细分析见程序编译的链接过程

C/C++编译构建相关问题的更多相关文章

  1. pbuilder编译构建工具分析

    1. 简介 pbuilder(personal Debian package builder)是ubuntu环境下维护debian包的专业工具,能够为每个deb包创建纯净的编译构建环境,自动解析和安装 ...

  2. kubernetes下jenkins实战maven项目编译构建

    关于kubernetes环境的jenkins集群 在kubernetes环境部署的jenkins集群,执行任务时会新建pod,任务完成后pod被销毁,架构如下所示: 在kubernetes搭建jenk ...

  3. Nginx编译安装相关参数

    Nginx编译安装相关参数 Nginx插件安装 ------------------pcre------------------ cd /usr/local/source wget http://ww ...

  4. wxWidgets的安装编译、相关配置、问题分析处理

    wxWidgets的安装编译.相关配置.问题分析处理 一.介绍部分 (win7 下的 GUI 效果图见 本篇文章的最后部分截图2张) wxWidgets是一个开源的跨平台的C++构架库(framewo ...

  5. 纯干货!华为软件开发云编译构建之Maven

    一.Maven介绍 Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使用了一个标准的目 ...

  6. 《Linux操作系统编译构建指南》

    在线阅读地址:http://www.doc88.com/p-5126905896771.html Linux编译构建定制qq群: 521902245 文件夹...0 前言...3 第零章 绪论...5 ...

  7. 如何在Idea中编译构建Spring Framework 5.x

    如何在Idea中编译构建Spring Framework 5.x 安装配置Gradle(略) 下载源码:git clone https://github.com/spring-projects/spr ...

  8. 【计算机视觉】关于OpenCV中GPU配置编译的相关事项

    [计算机视觉]关于OpenCV中GPU配置编译的相关事项 标签(空格分隔): [计算机视觉] 前一段发现了OpenCV中关于GPU以及opencl的相关知识,打算升级一下对OpenCV的使用,但是发现 ...

  9. Qt 编译配置相关总结

    MinGW 与 MSVC 编译的区别 我们可以从 Qt 下载页面看到两种版本编译器,如下图: 我们来对比一下这两个编译器的区别: MSVC 是指微软的 VC 编译器. MinGW 是 Minimali ...

  10. 踩坑经验总结之go web开源库第一次编译构建

    前言:记录一个go新手第一次构建复杂开源库的经历.go虽然是新手,但是编程上还是有多年的经验,除了c/c++,用过IDEA能进行简单的java编程.甚至scala编程.所以最开始还是有点信心的.所以也 ...

随机推荐

  1. GBDT中损失函数的负梯度用来拟合的一些理解

    将\(L(y_i,f(x_i))\)在\(f(x_i)=f_{m-1}(x_i)\)处泰勒展开到一阶(舍去余项,故为近似) \[L(y_i,f(x_i))\approx L(y_i,f_{m-1}(x ...

  2. 项目实训DAY 11-12 学习

    在神经网络可视化工具中,选择了三种,NNSVG,PlotNeuralNet,GraphCore 前两者应该比较好实现,例子都跑通了,对于定制的代码读起来也不难.PNN的示例图如下 最后一个虽然有实例图 ...

  3. SQL server——基础篇之数据完整性

    定义:保证数据库中的数据在逻辑上的一致性.正确性和可靠性. 作用:防止无效数据或错误数据进入数据库 数据完整性包括:实体完整性.域完整性和参照完整性 实体完整性 规定表的每一行记录在表中是唯一的 实体 ...

  4. 自己制作Switch大气层SDFile

    ️SWITCH SDFILE 每次吃灰之后,就想更新下系统,每次都得研究一遍... 决定好好研究下,发现不是很繁琐. SDFile有哪些文件组成! Atmosphere 任天堂Switch定制固件 H ...

  5. uniapp中使用echarts点击图例与tooltips无反应

    只需要在项目main.js文件中加上 window.wx = {} // echarts中tooltips点击无反应与点击图例无反应解决方法 即可

  6. uniapp 微信小程序 使用 echarts 避坑

    echarts.min.js的版本 5.3.2 第一步 : https://blog.csdn.net/qq_45164516/article/details/125298373 第二步: 重中之重修 ...

  7. k8s利用endpoints和service访问外部服务

    一.原理解析 在k8s集群中我们通过创建service去访问对应pod内的服务,而在创建service的时候会同时创建一个与service同名的endpoints对象,endpoints与pod实际建 ...

  8. 小梅哥课程学习——LED花式玩法(从计数器器到线性序列机)——实验六

    //每隔10ms,让led灯的一个8状态循环执行一次(每个变化时间值小一点,方便测试比如设置为10us) 源代码 module counter_led_6(    clk,    reset_n,   ...

  9. .netCore Nuget包引用记录

    1.画图  System.Drawing.Common 2.

  10. 基础篇二:Linux常用系统命令

    Linux常用系统命令 pwd 打印当前目录 cd /目录 切换目录 cd ..   切换上一级目录 ls 显示目录 ls -a  包括隐藏文件 ls -l 以长格式列出 alias 当前系统所有别名 ...