gcc 编译器使用指南
目录
- 安装
- 准备test.cpp
- 编译
- g++ 编译参数
- -g :编译带调试信息的可执行文件
- -O[n] :开启优化
- -l 和 -L :指定库文件 | 指定库文件路径
- -I :指定头文件搜索目录
- -Wall 和 -w:打印警告信息 | 关闭警告信息
- -std=c++11 :设置编译标准
- -o :指定输出文件名
- -D :定义宏
- 实例演示
- 直接编译
- 生成库文件并编译
参考:
https://b23.tv/tWqKrC
我的linux版本如下:
Linux version 5.4.0-88-generic (buildd@lgw01-amd64-008) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04))
使用命令:
cat /proc/version
即可查看
安装
sudo apt update
# 安装编译器和调试器
sudo apt install build-essential gdb
# 安装完成后,确认是否成功
gcc --version
g++ --version
gdb --version
准备test.cpp
mkdir test
cd test
touch test.cpp
vim test.cpp
# 设置tab缩进
:set tabstop=4
然后写代码:
#include<iostream>
using namespace std;
int main()
{cout << "test" << endl;return 0;
}
编译
在实际使用中,使用gcc指令编译c代码,g++指令编译c++代码。
一般cpp文件需要通过四个过程生成可执行文件:
预处理、编译、汇编、链接
# 预处理 .cpp -> .i
# -E 表示编译器只对输入文件进行预处理
g++ -E test.cpp -o test.i
# 编译 .i -> .s
# -S 表示在c++代码产生了汇编语言文件后停止编译,产生的汇编语言文件为 .s
g++ -S test.i -o test.s
# 汇编 .s -> .o
# -c g++仅把源代码编译为机器语言的目标代码
g++ -c test.s -o test.o
# 链接 .o -> bin文件
# -o 为将来产生的可执行文件用指定的文件名
g++ test.o -o test
以上的步骤也可以直接用一个步骤代替:
g++ test.cpp -o test
现在test文件夹里面是这样:
drwxrwxrwx 2 dyy dyy 4096 10月 19 14:44 ./
drwxrwxrwx 8 777 dyy 4096 10月 19 13:54 ../
-rwxrwxr-x 1 dyy dyy 17320 10月 19 14:44 test*
-rw-rw-r-- 1 dyy dyy 91 10月 19 14:38 test.cpp
运行它: 成功
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/test$ ./test
test
g++ 编译参数
-g :编译带调试信息的可执行文件
# -g 选项告诉 GCC 产生能被 GNU 调试器GDB使用的调试信息,以调试程序。
g++ -g test.cpp
-O[n] :开启优化
# -O 选项告诉 g++ 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。 -
# -O0 表示不做优化
# -O1 为默认优化
# -O2 除了完成-O1的优化之外,还进行一些额外的调整工作,如指令调整等。
# -O3 则包括循环展开和其他一些与处理特性相关的优化工作。
g++ -O2 test.cpp
-l 和 -L :指定库文件 | 指定库文件路径
# -l参数(小写)就是用来指定程序要链接的库,-l参数紧接着就是库名
# 在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接# 链接glog库
g++ -lglog test.cpp# 如果库文件没放在上面三个目录里,需要使用-L参数(大写)指定库文件所在目录
# -L参数跟着的是库文件所在的目录名
# 链接mytest库,libmytest.so在/home/bing/mytestlibfolder目录下
g++ -L/home/bing/mytestlibfolder -lmytest test.cpp
-I :指定头文件搜索目录
# -I
# /usr/include目录一般是不用指定的,gcc知道去那里找,但 是如果头文件不在/usr/icnclude
# 里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-
# I/myinclude 参数了,如果不加你会得到一个”xxxx.h: No such file or directory”的错
# 误。-I参数可以用相对路径,比如头文件在当前 目录,可以用-I.来指定。上面我们提到的–cflags参
# 数就是用来生成-I参数的。
g++ -I/myinclude test.cpp
-Wall 和 -w:打印警告信息 | 关闭警告信息
# 打印出gcc提供的警告信息
g++ -Wall test.cpp
# 关闭警告信息
g++ -w test.cpp
-std=c++11 :设置编译标准
# 使用c++11的标准编译 test.cpp
g++ -std=c++11 test.cpp
-o :指定输出文件名
# 若不指定,生成文件为a.out
g++ test.cpp -o test
-D :定义宏
# 常用场景:
# -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭
# DEBUG
g++ -DDEBUG debugTest.cpp -o debugTest
比如:
#include<stdio.h>
using namespace std;
int main()
{#ifdef DEBUGprintf("DEBUG LOG\n");#endifprintf("in\n");
}
我们编译运行:
g++ -DDEBUG debugTest.cpp -o debugTest
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/test$ ./debugTest
DEBUG LOG
in
实例演示
test项目录如下:
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│ └── swap.h
├── main.cpp
└── src└── swap.cpp2 directories, 3 files
main.cpp内容:
#include<iostream>
#include<swap.h>
using namespace std;
int main()
{int val1 = 10;int val2 = 20;cout << "before" << endl;cout << val1 << " " << val2 << endl;swap(val1, val2);cout << "after" << endl;cout << val1 << " " << val2 <<endl;return 0;
}
swap.h内容
#ifndef _swap_h_
#define _swap_h_
#include<stdio.h>
void swap(int& a, int& b);
#endif
swap.cpp内容
#include"swap.h"
void swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
直接编译
最简单编译运行
# 将 main.cpp src/Swap.cpp 编译为可执行文件
g++ main.cpp src/Swap.cpp -Iinclude
# 运行可执行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./a.out
before
10 20
after
20 10
增加编译参数运行
g++ main.cpp src/swap.cpp -Iinclude -std=c++11 -O2 -Wall -o b.out
生成库文件并编译
首先尝试生成静态库:
cd src
# 汇编,生成swap.o文件
g++ swap.cpp -c -I../include
# 生成静态库libswap.a
ar rs libswap.a swap.o
cd ..
# 链接 生成可执行文件staticmain
g++ main.cpp -Iinclude -Lsrc -lswap -o staticmain
现在观察一下项目文件:
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│ └── swap.h
├── main.cpp
├── src
│ ├── libswap.a
│ ├── swap.cpp
│ └── swap.o
└── staticmain2 directories, 6 files
dyy@dyy-Lenovo-ThinkBo
现在尝试动态链接
cd src
# 生成动态库
g++ swap.cpp -I../include -fPIC -shared -o libswap.so
# 上面的命令等同于以下两条合起来:
# g++ swap.cpp -I../include -c -fPIC
# g++ -shared -o libswap.so swap.o
cd ..
# 链接,生成可执行文件
g++ main.cpp -Iinclude -Lsrc -lswap -o sharemain
现在观察一下项目文件:
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│ └── swap.h
├── main.cpp
├── sharemain
├── src
│ ├── libswap.a
│ ├── libswap.so
│ ├── swap.cpp
│ └── swap.o
└── staticmain
运行可执行文件
# 运行静态链接的可执行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./staticmain
before
10 20
after
20 10
# 运行含有动态链接的可执行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./sharemain
./sharemain: error while loading shared libraries: libswap.so: cannot open shared object file: No such file or directory
# 指定一下动态库目录然后再运行
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ LD_LIBRARY_PATH=src ./sharemain
before
10 20
after
20 10
gcc 编译器使用指南相关推荐
- GCC编译优化指南【作者:金步国】
GCC编译优化指南[作者:金步国] GCC编译优化指南 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分 ...
- Keil5.15使用GCC编译器链接.a库文件
我们知道,当使用第三方的代码时,人家有可能会扔个Lib文件给你.这时候,别人仅仅要提供header文件给你,则你就能够通过Lib文件及header的函数声明,对Lib中的函数进行调用.在Keil中假设 ...
- 转 vi 编辑器,gcc 编译器的使用
vi编辑器是我们在linux下经常使用的文本编辑器,这个东西也是专门为程序员准备的,基本上每个Unix和Linux系统都为我们提供了这个软件,我们可以使用vi来编写我们的代码.在vi编辑器下所有操作都 ...
- linux make链接.o文件,Linux操作系统至gcc编译器、makefile
gcc编译器: 将高级语言代码编译成为机器可识别的指令代码 编译文件 编译步骤: 1.预处理,展开所有代码 gcc-E只预处理 -o 指定修改后的文件名称 2.编译:纠错,没有错误则将c语言代码 ...
- vs编译器 printf 控制台输出_【语言教程】通过语言了解GCC编译器工作过程
通过c语言了解GCC编译器如何工作的 比特 下面是c语言初学必看的打印helloworld #include int main(){ printf("hello, world\n" ...
- 手把手教你搭建Linux开发环境(VMware+Ubuntu)(四)——gcc编译器的安装和使用
上回,我们已经把vim的安装.配置和使用说完了,今天我们就来谈谈Linux下gcc编译器的安装和使用. PS:还不会vim的同学,建议移步: Ubuntu下vim编辑器的安装.配置和使用 1.查看gc ...
- C++对象内存布局--⑤GCC编译器--单个虚拟继承
C++对象内存布局--⑤GCC编译器--单个虚拟继承 测试GNU的GCC编译器在处理虚拟继承上跟VS不同的地方.派生类的虚函数表跟虚基类表合并. //GCC编译器--单个虚拟继承.cpp //2010 ...
- 【C 语言】Windows 下使用 gcc 编译器 ( 常用的编译器 | Qt 中的 gcc 编译器 | 独立安装 MinGW )
文章目录 一.常用的编译器 二.使用 Qt 中的 gcc 编译器 三.独立安装 MinGW 一.常用的编译器 常用编译器 : MSVC GCC MinGW CLANG ; MSVC : 微软 Micr ...
- linux编译器6,Linux安装gcc编译器详解(CentOS 6.5 64位系统)
本次安装针对CentOS 6.5 64位系统,由于在安装系统的时候并没有勾选安装gcc编译器,因此需要自行安装gcc编译器. 使用yum安装gcc 对于配备了yum的Linux发行版而言,安装gcc编 ...
最新文章
- 美国卡尔顿学院计算机专业怎么样,美国卡尔顿学院排名
- 众所周知,static修饰的成员只实例化一次,而string类型每次赋值都会重新创建一个实例,那么用static修饰string呢?...
- Keil 5出现Error: L6218E: Undefined symbol解决方法
- 【408预推免复习】操作系统引论
- Hibernate sqlserver 的对象转成 Hibernate mysql 的对象时 需注意
- ES6对象(1):新增语法与API
- c语言队列原理的实现,c印记(十二):队列queue原理与实现
- numpy tricks(一)—— 多维数组的阈值化处理
- C++11 Intro - Thread Id
- WebStorm 添加多个项目到当前工程目录
- WAP PUSH解析(2)——WSP以及WBXML编码
- 如何编辑修改PDF文件内容?修改方法很简单
- 银河麒麟系统10服务器安装教程,麒麟系统下安装win10的详细教程
- mysql查询之左连接查询与右连接查询
- 配置PLSQL连接ORACLE数据库
- 华为计算机视觉博士,华为视觉计划发布,要做“智能世界的眼睛”
- 2022-01-19:青蛙过河。 一只青蛙想要过河。 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有)。 青蛙可以跳上石子,但是不可以跳入水中。 给你石子的位置列
- 解决android上WIFI提示“未检测到任何互联网连接,因此不会自动重新连接“
- 【ACM- OJ】《Oulipo》C++
- cmd脚本编程基础命令
热门文章
- android 5.0 新功能,Android 5.0新特性有哪些?安卓5.0新功能汇总
- 记一次CNVD通用漏洞审计
- java开发环境搭建 pdf_01搭建java web开发环境.pdf
- js笔记(三)ES5、ES5新增的数组的方法、字符串的方法、字符编码、对象的序列化和反序列化、bind
- 201771010120 苏浪浪 《面向对象程序设计(java)》第二周学习总结
- (转)Cobbler无人值守批量安装Linux系统
- 九度OJ1486 /POJ 1029/2012北京大学研究生复试上机
- 06链队列_LinkQueue--(栈与队列)
- Linq list 排序,Dictionary 排序
- modelsim 编译 xilinx库