C/C++编译构建相关问题
名词辨析
GNU
- GNU's Not Unix!的递归缩写
- 一个自由的操作系统,起源于GNU计划,希望发展出一套完整的开放源代码操作系统来取代Unix
- 基本组成包括:
- GNU编译器套装(GCC)
- GNU的C库(glibc)
- GNU核心工具组(coreutils)
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 build 或 ctrl + shift + p > cmake configure
2.构建项目:cmake --build build 或 ctrl + 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})
参考
- [1] GNU的发展史
- [2] GCC的gcc和g++区别
- [3] 编译器 cc、gcc、g++、CC 的区别
- [4] Linux环境中gcc和g++的区别详解
- [5] GCC、LLVM、Clang区别
- [6] 业界主流3大编译器
- [7] 区分gnu的gcc/g++, mingw/msvc, llvm的clang/clang++, make,cmake
- [8] LLVM架构(相关资料)
- [9] CMake入门
编译流程
以gcc为例

- 预处理(预编译):头文件包含,条件编译,宏替换,删除注释
- 编译:词法,语法,语义分析,生成汇编代码
- 汇编:将汇编语言转化为相应的机器语言(二进制目标文件)
- 链接[2]:将多个可重定位目标文件和标准库函数合并为可执行目标文件
关于驱动器的说法,目前只在gcc/g++链接选项一文中看到相关说法 ︎
C/C++编译构建相关问题的更多相关文章
- pbuilder编译构建工具分析
1. 简介 pbuilder(personal Debian package builder)是ubuntu环境下维护debian包的专业工具,能够为每个deb包创建纯净的编译构建环境,自动解析和安装 ...
- kubernetes下jenkins实战maven项目编译构建
关于kubernetes环境的jenkins集群 在kubernetes环境部署的jenkins集群,执行任务时会新建pod,任务完成后pod被销毁,架构如下所示: 在kubernetes搭建jenk ...
- Nginx编译安装相关参数
Nginx编译安装相关参数 Nginx插件安装 ------------------pcre------------------ cd /usr/local/source wget http://ww ...
- wxWidgets的安装编译、相关配置、问题分析处理
wxWidgets的安装编译.相关配置.问题分析处理 一.介绍部分 (win7 下的 GUI 效果图见 本篇文章的最后部分截图2张) wxWidgets是一个开源的跨平台的C++构架库(framewo ...
- 纯干货!华为软件开发云编译构建之Maven
一.Maven介绍 Maven是一个项目管理和整合的工具.Maven为开发者提供了一套完整的构建生命周期框架.开发团队基本不用花多少时间就能自动完成工程的基础构建配置,因为Maven使用了一个标准的目 ...
- 《Linux操作系统编译构建指南》
在线阅读地址:http://www.doc88.com/p-5126905896771.html Linux编译构建定制qq群: 521902245 文件夹...0 前言...3 第零章 绪论...5 ...
- 如何在Idea中编译构建Spring Framework 5.x
如何在Idea中编译构建Spring Framework 5.x 安装配置Gradle(略) 下载源码:git clone https://github.com/spring-projects/spr ...
- 【计算机视觉】关于OpenCV中GPU配置编译的相关事项
[计算机视觉]关于OpenCV中GPU配置编译的相关事项 标签(空格分隔): [计算机视觉] 前一段发现了OpenCV中关于GPU以及opencl的相关知识,打算升级一下对OpenCV的使用,但是发现 ...
- Qt 编译配置相关总结
MinGW 与 MSVC 编译的区别 我们可以从 Qt 下载页面看到两种版本编译器,如下图: 我们来对比一下这两个编译器的区别: MSVC 是指微软的 VC 编译器. MinGW 是 Minimali ...
- 踩坑经验总结之go web开源库第一次编译构建
前言:记录一个go新手第一次构建复杂开源库的经历.go虽然是新手,但是编程上还是有多年的经验,除了c/c++,用过IDEA能进行简单的java编程.甚至scala编程.所以最开始还是有点信心的.所以也 ...
随机推荐
- 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 ...
- 项目实训DAY 11-12 学习
在神经网络可视化工具中,选择了三种,NNSVG,PlotNeuralNet,GraphCore 前两者应该比较好实现,例子都跑通了,对于定制的代码读起来也不难.PNN的示例图如下 最后一个虽然有实例图 ...
- SQL server——基础篇之数据完整性
定义:保证数据库中的数据在逻辑上的一致性.正确性和可靠性. 作用:防止无效数据或错误数据进入数据库 数据完整性包括:实体完整性.域完整性和参照完整性 实体完整性 规定表的每一行记录在表中是唯一的 实体 ...
- 自己制作Switch大气层SDFile
️SWITCH SDFILE 每次吃灰之后,就想更新下系统,每次都得研究一遍... 决定好好研究下,发现不是很繁琐. SDFile有哪些文件组成! Atmosphere 任天堂Switch定制固件 H ...
- uniapp中使用echarts点击图例与tooltips无反应
只需要在项目main.js文件中加上 window.wx = {} // echarts中tooltips点击无反应与点击图例无反应解决方法 即可
- uniapp 微信小程序 使用 echarts 避坑
echarts.min.js的版本 5.3.2 第一步 : https://blog.csdn.net/qq_45164516/article/details/125298373 第二步: 重中之重修 ...
- k8s利用endpoints和service访问外部服务
一.原理解析 在k8s集群中我们通过创建service去访问对应pod内的服务,而在创建service的时候会同时创建一个与service同名的endpoints对象,endpoints与pod实际建 ...
- 小梅哥课程学习——LED花式玩法(从计数器器到线性序列机)——实验六
//每隔10ms,让led灯的一个8状态循环执行一次(每个变化时间值小一点,方便测试比如设置为10us) 源代码 module counter_led_6( clk, reset_n, ...
- .netCore Nuget包引用记录
1.画图 System.Drawing.Common 2.
- 基础篇二:Linux常用系统命令
Linux常用系统命令 pwd 打印当前目录 cd /目录 切换目录 cd .. 切换上一级目录 ls 显示目录 ls -a 包括隐藏文件 ls -l 以长格式列出 alias 当前系统所有别名 ...