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编程.所以最开始还是有点信心的.所以也 ...
随机推荐
- Dapper存储过程分页
create database Month6use Month6 --用户表create table UserInfo( UId int primary key identity, UName var ...
- 汇编debug工具Dosbox使用
汇编debug工具DOSBOX使用说明 首先新建文件,更改后缀名为asm,然后写入一段汇编程序 之后打开DosBox 输入masm + 文件名(加不加文件名后缀都可以)但如果要加的话,应该加上. ...
- .netcore 跨域问题
CORS(跨域资源共享)是一种W3C标准,允许服务器放宽同源策略.使用CORS,服务器可以在显式允许某些跨域请求时拒绝其他跨域请求.CORS是相比其他跨域技术(比如JSONP)更安全.更灵活. ASP ...
- React++antd+ProComponents可编辑表格EditableProTable组件实现表单中的可编辑列表组件
需求: 在新增&编辑表单中,共分三个表单模块,第二个模块设计为一个可编辑表格组件,其中可选下拉列表依赖外层第一个模块的某条数据值,提供新增.编辑.删除.按规定条件去重等功能,并在第三个模块中自 ...
- 给linux串口,增加登录密码
一.密码更改 1.在linux系统上,输入passwd,输入需要设定的密码,密码文件保存在/etc/passwd里面. 2.把/etc/passwd文件拷贝出来,放到rootfs的etc/目录下,实现 ...
- 通达OA实施的小总结
1.表格中带有复选框的单独一行单元格(一行两列 表头在第一列 复选框在第二列),在手机上进行显示时,这一行会把行表头屏蔽掉.2.日历控件不要用自定义格式,要不部分手机上无法使用.但是有些手机只能进行填 ...
- 当jar包执行时,内嵌的文件找不到时,可以这样解决!
1.加载是可以加载到的,但是只能是以流的形式存在. 2.如果要按文件进行加载,可以新建一个文件,然后以流的形式写入到新的文件中. 3.加载这个新的文件来进行处理.
- jmeter性能测试学习1_配置oracl jdbc连接
1.导入orcle驱动的jar包 2.添加配置元件选择 JDBC连接配置 3.添加取样器 JDBCrequest 4.添加观察树,运行 配好密码 OK
- python中的变量定义
1 变量名:由下划线.字母和数字组成 2 python中变量名的特殊含义: xx:标准的标识符,共有的 _xx:只是在from - import *时是不会被导入的,其他导入方式会被引入 隐藏变量还有 ...
- kubeadm搭建k8s
一.kubeadm 部署 K8S 集群架构 主机名 IP地址 安装组件 master(2C/4G,cpu核心数要求大于2) 192.168.160.20 docker.kubeadm.kubelet. ...