前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux与g++基本知识「建议收藏」

linux与g++基本知识「建议收藏」

作者头像
全栈程序员站长
发布2022-09-22 12:29:40
1.3K0
发布2022-09-22 12:29:40
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

基本知识

gcc、g++、gdb区别

GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。

  • gcc是GCC中的GUN C Compiler(C 编译器)
  • g++是GCC中的GUN C++ Compiler(C++编译器)
  • gdb是是GCC中的GUN 调试工具

linux和win换行符

  • windows : CRLR \r\n
  • linux : LF \n

yum、apt、rpm区别

rpm 命令是RPM软件包的管理工具,包括安装,升级,卸载,查询等操作。

尽管几乎所有的Linux发行版本都使用rpm进行软件包的管理安装、更新和卸载软件,但是并不受linux用户喜爱, 主要原因就是因为rpm软件包之间的依赖性问题往往会很繁琐,一般用户根本无法解决。 而yum仓库的产生,就是为了解决这个问题,它最大的特点就是为了帮助linux用户降低软件安装难度。

apt是ubuntu系列的包管理工具

一般来说著名的linux系统基本上分两大类:

  • RedHat系列:Redhat、Centos、Fedora等
  • Debian系列:Debian、Ubuntu等

vscode底层也是调用gcc和g++来编译代码的

二进制包和源码包

Linux 软件包管理大致可分为二进制包、源码包,使用的工具也各不相同。Linux 常见软件包分为两种,分别是源代码包(Source Code)、二进制包(Binary Code),源代码包是没有经过编译的包,需要经过 GCC、C++编译器环境编译或解压才能运行,二进制包无需编译,可以直接安装使用。

通常而言,可以通过后缀简单区别源码包和二进制包,例如.tar.gz、.zip、.rar 结尾的包通常称之为源码包,以.rpm 结尾的软件包称之为二进制包。

linux动态库和静态库

静态库(.a、.lib)和动态库(.so、.dll)

cpp文件编译流程

  1. 预处理pre-processing
代码语言:javascript
复制
# 头文件和宏定义等 进行展开 生成.i文件
g++ -E test.cpp -o test.i
  1. 编译Compiling
代码语言:javascript
复制
# 将test.i文件生成汇编文件 生成.s文件
g++ -S test.i -o test.s
  1. 汇编Assembling
代码语言:javascript
复制
# 将汇编代码转换为机器码
#缺省时 g++建立的目标代码文件有一个.o扩展名
g++ -c test.s -o test.o
  1. 链接Linking
代码语言:javascript
复制
#将机器码所使用的静态库动态库链接起来
g++ test.o -o test

也可以使用

代码语言:javascript
复制
g++ test.cpp -o test

一条命令代替以上四条命令 生成test.cpp文件

代码语言:javascript
复制
vim test.cpp
#include<iostream>
using namespace std;

int main(){ 
   
	cout<<"hello world";
	return 0; 
}

# 生成test可执行文件
g++ test.cpp -o test

#使用./test执行可执行文件
./test

g++ 重要参数

-g

代码语言:javascript
复制
# -g 告诉GCC产生能被GNU调试器GDB使用的调式信息
# 所以生成的文件比一般的文件大一些
g++ -g test.cpp -o test

-O

代码语言:javascript
复制
# -O告诉g++对源代码进行优化 大多数情况下可以替换
# -O0不做优化
# -O1默认优化
# -O2进行额外调整入指令重排
# -O3 包括循环展开和其他一些与处理工程相关的优化工作
g++ -O2 test.cpp

-I 和 -L 指定库文件 | 指定库文件路径

代码语言:javascript
复制
# -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

代码语言:javascript
复制
# /usr/include目录一般是不用指定的,gcc知道去哪里找 但是如果文件不在/usr/include里 
#我们就要使用-I 参数指定. 比如文件在/myinclude目录里,那编译命令就要加上 -I/myinclude 参数了
#如果不加你会得到一个"xxx.h No such file or directory"的错误 
#-I参数可以用相对路径 比如头文件在当前目录 可以用 -I. 来指定 上面我们提到的-cflags参数就是我们用来生成-I参数的
g++ -I/myinclude test.cpp

-Wall 打印警告信息

代码语言:javascript
复制
# 打印警告信息
g++ -Wall test.cpp

-w 关闭警告信息

代码语言:javascript
复制
#关闭警告信息
g++ -w test.cpp

-std=c++11 设置编译标准

代码语言:javascript
复制
g++ -std=c++ test.cpp

-o 指定输出文件名字

代码语言:javascript
复制
g++ test.cpp -o test

-D 定义宏

代码语言:javascript
复制
# 使用gcc/g++编译的时候定义宏

#常用场景
# -DDEBUG 定义DEBUG宏 可能文件中又DEBUG宏部分的相关信息 用个DDEBUG来选择开去或关闭DEBUG

#如

1.#include<stdio.h>
2.int main(){ 
   
3.	#ifdef DEBUG
4.		printf("DEBUG LOG\n");
5.	#endif
6.		printf("in\n");
7.	return 0;
}

#编译的时候 使用g++ -DDEBUG main.cpp
#第4行的代码会被执行
代码语言:javascript
复制
[root@master test]# tree .
.
├── include
│   └── swap.h
├── main.cpp
└── src
    └── swap.cpp
代码语言:javascript
复制
#main.cpp函数
#include<iostream>
#include "swap.h"
using namespace std;
int main(){ 
   
        int a = 1;
        int b = 2;
        cout<<"before swap"<<endl;
        cout<<"a is "<<a<<endl;
        cout<<"b is "<<b<<endl;
        cout<<"after swap"<<endl;
        cout<<"a is "<<a<<endl;
        cout<<"b is "<<b<<endl;
    return 0;
}

#swap.cpp
#include "swap.h"
void swap(int &a,int &b){ 
   
    int temp;
    temp = a;
    a = b;
    b = temp;
}

#swap.h
oid swap(int &a,int &b);
代码语言:javascript
复制
#生成
g++ main.cpp src/swap.cpp -Iinclude -Wall -std=c++11 -o b.out

生成库文件

生成静态库

代码语言:javascript
复制
#进入src目录下
cd src

#汇编 生成swap.o文件
g++ swap.cpp -c -I,,/include

#生成静态库libswap.a
ar rs libswap.a swap.o

#回到上级目录
cd ..

#链接 生成可执行文件 staticmain
#-lswap 则系统就会去查找libswap.a静态库
g++ main.cpp -lswap -Lsrc -Iinclude -o static_main

生成动态库

代码语言:javascript
复制
#进入src目录
cd src

#生成动态库libswap.so
g++ swap.cpp -I../include -fPIC -shared -o libswap.so
#上面这条命令相当于下面两条命令
#gcc swap.cpp -I../include -c fPIC
#gcc -shared -o libswap.so swap,o
#-shared参数指定生成动态库

#回到上级目录
cd ..

#链接
g++ main.cpp -Iinclude -Lsrc -lswap -o sharemain
代码语言:javascript
复制
./sharemain
#执行./sharemain: error while loading shared libraries: libswap.so: cannot open shared object file: No such file or directory

静态库和动态库区别 静态库生成的可执行文件已经包装了静态库 运行的时候不需要额外链接静态库 动态库生成的可执行文件没有包括静态库 运行的时候需要额外链接动态库

代码语言:javascript
复制
#执行动态库可执行文件
LD_LIBRARY_PATH=src ./sharemain

GDB调试

执行gdb [exefilename] 进入gdb调试程序

代码语言:javascript
复制
help(h)			#查看帮助 在gdb中输入 Help + 命令
run(r)			#重新开始运行文件
start			#单步执行
list(l)			#查看源代码(list-n 从第n行开始查看代码 list+函数名 查看具体函数)
set				#设置变量值
next(n)			#单步调试(越过函数)
step(s)			#单步调试(进入函数)
backtrace(bt)	#查看函数调用的栈帧和层级关系
frame(f)		#切换函数栈帧
info(i)			#查看函数内部局部变量的值
finish			#结束当前函数 回到原函数
continue(c)		#跳到下一个断点
print(p)		#打印值及地址
quit(q)			#退出gdb


break num(b num)	#在第num行打断点
info breakpoints#查看当前所有断点
delete breakpoints num(d)#删除第num个断点
display			#追踪查看具体变量值
undisplay		#取消追踪具体变量值
watch			#被设置观察点的变量发生变化时 打印显示
i watch			#显示观察点
enable breakpoints#启用断点
disable breakpoints	#禁用断点
x				#查看内存x/20xw 显示20个单元 16进制 4字节单元
run argv[1] argv[2]	#调试时命令传参
set follow-fork-mode child #makefile项目管理 选择跟踪父子进程(fork())

注意

  • 编译程序的时候需要加上-g参数 之后才能使用gdb进行调试 gcc -g main.c -o main
  • 回车键代表上一命令

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/168518.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基本知识
  • gcc、g++、gdb区别
  • linux和win换行符
  • yum、apt、rpm区别
  • 二进制包和源码包
  • linux动态库和静态库
  • cpp文件编译流程
  • g++ 重要参数
  • 生成库文件
    • 生成静态库
      • 生成动态库
      • GDB调试
      相关产品与服务
      项目管理
      CODING 项目管理(CODING Project Management,CODING-PM)工具包含迭代管理、需求管理、任务管理、缺陷管理、文件/wiki 等功能,适用于研发团队进行项目管理或敏捷开发实践。结合敏捷研发理念,帮助您对产品进行迭代规划,让每个迭代中的需求、任务、缺陷无障碍沟通流转, 让项目开发过程风险可控,达到可持续性快速迭代。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档