Linux 编程环境
文章目录
- Vim
- GCC
- GDB
- Make
Vim
Vim
GCC
GCC(GNU Compiler Collection)是一套以 GPL 和 LGPL 许可证发布的程序语言编译器自由软件,由 Richard Stallman 于 1985 年开始开发。
GCC 原名为 GNU C语言编译器,因为它原本只能处理 C 语言,但如今的 GCC ,不仅可以编译 C、C++ 和 Objective-C,还可以通过不同的前端模块支持各种语言,包括 Java、Fortran、Ada、Pascal、Go 和 D 语言等等。
GCC支持多种硬件开发平台,还能进行跨平台交叉编译。此外,GCC是按模块化设计的,可以加入新语言和新CPU架构的支持。
- gcc(GUN C Compiler)是GCC中的c编译器
- g++(GUN C++ Compiler)是GCC中的c++编译器。
gcc和g++两者都可以编译c和cpp文件,但存在差异。gcc在编译cpp时语法按照c来编译但默认不能链接到c++的库(gcc默认链接c库,g++默认链接c++库)。g++编译.c和.cpp文件都统一按cpp的语法规则来编译。所以一般编译c用gcc,编译c++用g++。
GCC 编译器是 Linux 下默认的 C/C++ 编译器,大部分 Linux 发行版中都是默认安装的。若需要安装,在终端中执行以下命令安装。
sudo apt install build-essential # 安装
gcc --version # 查看版本
也可以安装其他组件
sudo apt install g++
sudo apt install gfortran
gcc hello.c -o hello # 编译生成 hello 可执行文件
./hello # 运行可执行文件
上述命令实际上是多个步骤的结合,依次为:
gcc hello.c -E -o hello.i # 预处理(Pre-Processing),生成预编译文件 .i
gcc hello.i -S -o hello.s # 编译(Compiling),生成汇编文件 .s
gcc hello.s -c -o hello.o # 汇编(Assembling),生成目标文件(二进制文件).o
gcc hello.c -o -o hello.out # 链接(Linking),生成可执行程序 .exe / .out
GCC 参数详解
gcc编译器版本切换
gcc -v # 查看版本
g++ -v # 查看版本
sudo apt-get install gcc-12 # 安装
sudo apt-get install g++-12 # 安装
ls /usr/bin/gcc* # 查看当前系统中编译器版本
ls /usr/bin/g++*
# 设置编译器的优先级
sudo udate-alternatives --install usr/bin/gcc gcc /usr/bin/gcc-12 100
sudo udate-alternatives --install usr/bin/gcc gcc /usr/bin/gcc-11 100
sudo udate-alternatives --install usr/bin/g++ g++ /usr/bin/g++-12 100
sudo udate-alternatives --install usr/bin/g++ g++ /usr/bin/g++-11 100
# 切换编译器的版本
sudo update-alternatives --config gcc
# 示例如下
root@ubuntu:~# sudo update-alternatives --config gcc
There are 2 choices for the alternative gcc (providing /usr/bin/gcc).
Selection Path Priority Status
------------------------------------------------------------
0 /usr/bin/gcc-11 100 auto mode
* 1 /usr/bin/gcc-11 100 manual mode
2 /usr/bin/gcc-12 100 manual mode
Press <enter> to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/bin/gcc-12 to provide /usr/bin/gcc (gcc) in manual mode
root@ubuntu:~# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper
# 切换编译器的版本
sudo update-alternatives --config g++
GDB
GDB,全称GNU调试器(GNU Debugger),是一个强大的Unix系统下的源代码级调试工具。它可以帮助程序员查看程序在执行过程中的内部状态,从而更好地理解程序的运行机制。GDB主要用于调试C和C++语言编写的程序。它的存在,使得我们能够更深入地了解程序的运行过程,找出并修复程序中的错误。
- 准备这样一份 hello.c
#include<stdio.h>
void swap(int a, int b) {
int t = a;
a = b;
b = t;
printf(" swap : a = %d, b = %d \n", a, b);
}
int main(int argc, char* argv[]) {
int a = 10, b = 20;
printf("start : a = %d, b = %d \n", a, b);
swap(a, b);
printf(" end : a = %d, b = %d \n", a, b);
return 0;
}
sudo apt-get install gdb # 安装 gdb
gdb -v # 查看版本
gcc hello.c -g -o hello # 生成可调式的可执行文件
gdb hello # 执行调试,进入调试界面
list 1 # 从第 1 行开始查看调试文件
list # 继续查看
break [line] # 设置断点,还有其他方式
info break [n] # 长查看断点 [n] 为断点号
r # 运行代码
p + var # 查看当前 变量 var 的值
continue # 恢复程序运行
step / next [count] # 单步执行,count条指令
quit # 退出gdb模式
kill #停止程序执行
【Linux】GDB保姆级调试指南(什么是GDB?GDB如何使用?
Make
make是linux中的自动化构建工具,一般来说系统会自带make,如果没有,安装即可。
sudo apt install make # Debian系安装make
make是个命令,也是个可执行程序,用来解析Makefile 文件的命令,这个命令存放在/usr/bin/目录下。
Makefile 是描述程序的编译规则的文本文件,执行 make 命令的时候,make 命令会在当前目录下寻找 Makefile 文件,根据Makefile文件里的规则,编译程序。
Makefile的编写语法规则
目标:依赖文件列表
命令列表
- 目标:要产生的文件名称,目标可以是可执行文件或其他object文件
- 依赖文件列表:由多个依赖文件组成,每个依赖文件是用来输入而产生目标的文件,一个目标通常有0个或多个依赖文件
- 命令列表:由0个或多个命令组成,代表 make 执行的动作,注意一个规则可以包含多个命令,存在多个命令时,每个命令占一行
Makefile文件内容举例:
- 使用
vim Makefile
,并输入以下信息
hello:hello.o
gcc -o hello hello.c
clean:
rm hello
@rm *.o
hello 可执行文件的生成需要依赖 hello.o 文件,通过 gcc -o hello hello.c
生成相应文件。
clean 是清空命令,可以用来删除相应的信息。
@ 符号的使用可以取消回显。
root@ubuntu:~$ ls
hello.c Makefile
root@ubuntu:~$ cat Makefile
hello:hello.o
gcc -o hello hello.c
clean:
rm hello
@rm *.o
root@ubuntu:~$ make # 利用make自动构建项目
cc -c -o hello.o hello.c
gcc -o hello hello.c
root@ubuntu:~$ ls
hello hello.c hello.o Makefile
root@ubuntu:~$ ./hello
Hello World
root@ubuntu:~$ make clean # 项目清理
rm hello
root@ubuntu:~$ ls
hello.c Makefile
root@ubuntu:~$
多个源文件的项目构建样例
- main.c
#include<stdio.h>
#include "func.h"
int main(int argc, char* argv[]){
func();
return 0;
}
- func.c
#include<stdio.h>
void func(){
puts("Hello World");
}
- func.h
#ifndef _FUNC_H
#define FUNC_H
void func();
#endif
- Makefile
main : main.o func.o # 目标:依赖
gcc main.o func.o -o main # 指定依赖如何生成目标
main.o : main.c
gcc -c main.c -o main.o # .o文件依赖于.c文件
func.o : func.c
gcc -c func.c -o func.o
.PHONY:clean # 伪目标,避免出现符号clean与文件clean重名的情况
clean:
rm *.o main
- 执行
make # 执行编译
make clean # 清除处理,删除目标文件
- Makefile 使用自动变量进行替换
main : main.o func.o
gcc $^ -o $@
main.o : main.c
gcc -c $< -o $@
func.o : func.c
gcc -c $< -o $@
.PHONY:clean
clean:
rm *.o main
- Makefile 自定义变量
CC = gcc
OBJS = main.o func.o
CFLAGS = -Wall -O2 -g
OBJ = main # 定义变量(无类型),并赋值
$(OBJ) : $(OBJS)
$(CC) $^ -o $@
#$(OBJ).o : $(OBJS).c
# $(CC) $(CFLAGS) -c $< -o $@
#func.o : func.c
# $(CC) $(CFLAGS) -c $< -o $@
.PHONY:clean
clean:
rm -f *.o $(OBJ)
Makefile 的规则
- 编译C程序的隐含规则:.o 的依赖自动推导为 .c
- 链接目标文件的隐含规则: 可执行文件的依赖自动推导为 .o
CC = gcc
OBJS = main.o func.o
CFLAGS = -Wall -O2 -g
OBJ = main # 定义变量(无类型),并赋值
$(OBJ) : $(OBJS)
.PHONY:clean
clean:
rm -f *.o $(OBJ)
- VPATH 的使用
如果在当前目录没有找到对应的文件,会到 PATH 指定的目录下寻找。
CC = gcc
OBJS = main.o func.o
CFLAGS = -Wall -O2 -g
OBJ = main
VPATH = ./test ./func
$(OBJ) : $(OBJS)
.PHONY:clean
clean:
rm -f *.o $(OBJ)