名词辨析

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. 简体Windows系统登录玩新枫之谷方法

    2022-2-23  游戏更新后Locale.Emulato失效,64位游戏使用新的工具Locale_Remulator,请自行到GitHub上搜索下载,使用方法与Locale.Emulato类似. ...

  2. CPU密集型和IO密集型与线程池的配置

    CPU密集型任务应配置尽可能小的线程,如配置CPU数目+1个线程的线程池.由于IO密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如2*CPU数目.

  3. Java中Math类常用方法

    ​在编写程序时,可能需要计算一个数的平方根.绝对值或获取一个随机数等.java.lang包中的Math类包含许多用来进行科学计算的static方法,这些方法可以直接通过类名调用.另外,Math类还有两 ...

  4. DER编码

    1. Attribute Type编码 ​ 对于标识串,采用低标识编码方式,只需1个字节.OBJECT IDENTIFIER的 tag为Ox06;class选择universal,则位8和位7为0,O ...

  5. MQTT服务器搭建——Liunx安装mosquitto,并设置用户密码

    一.安装 1.下载mosquitto安装包 地址:http://mosquitto.org/files/source/ 2.安装依赖包 yum install gcc gcc-c++ libstdc+ ...

  6. 虚拟机VMware15的CentOS7.3的docker下安装Oracle11g

    1.拉取镜像docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g 2.安装容器:docker run -d --name o ...

  7. mysql_记录操作

    在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括 使用INSERT实现数据的插入 UPDATE实现数据的更新 使用DELETE实现数据的删除 使用SELECT查询数据以及 ...

  8. 如何跳出forEach循环

    for(let ii in this.listData){ console.log("提交前数据",ii) try{ this.listData[ii].forEach((el,i ...

  9. maven远程debug

    1.修改tomcat服务器配置 打开tomcat/bin/catalina.sh 添加参数 CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_soc ...

  10. Spring校验:@Validated和@Valid区别

    结论: Spring validation验证框架对入参实体进行嵌套验证必须在相应属性(字段)加上@Valid而不是@Validated Spring Validation验证框架对参数的验证机制提供 ...