【Linux基础开发工具 (四)】Linux编程基础:深入理解gcc / g++编译与链接原理

🔥艾莉丝努力练剑: 个人主页

专栏传送门:《C语言》《数据结构与算法》C/C++干货分享&学习过程记录Linux操作系统编程详解笔试/面试常见算法:从基础到进阶

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬艾莉丝的简介:


🎬艾莉丝的Linux专栏简介:


目录

前情提示

[1 编译型语言和解释型语言](#1 编译型语言和解释型语言)

[2 一张图总结动态库和静态库的优缺点](#2 一张图总结动态库和静态库的优缺点)

[3 ~> Linux下的编译器:gcc和g++](#3 ~> Linux下的编译器:gcc和g++)

[3.1 概念初识](#3.1 概念初识)

[3.2 概念区分](#3.2 概念区分)

[3.3 编译](#3.3 编译)

[3.3.1 翻译的过程------C:重点放在编译选项上](#3.3.1 翻译的过程——C:重点放在编译选项上)

[3.3.2 一般程序的构建过程------.o](#3.3.2 一般程序的构建过程——.o)

[3.3.3 条件编译](#3.3.3 条件编译)

[3.3.4 编译器和对应语言的关系------自举](#3.3.4 编译器和对应语言的关系——自举)

[3.4 链接](#3.4 链接)

[3.4.1 初步理解链接](#3.4.1 初步理解链接)

[3.4.2 关于链接和指令查看:ldd](#3.4.2 关于链接和指令查看:ldd)

[3.4.3 动态库和静态库](#3.4.3 动态库和静态库)

[3.4.4 如何理解库和链接?通过一个小故事先感性地理解一下吧!](#3.4.4 如何理解库和链接?通过一个小故事先感性地理解一下吧!)

[3.4.4.0 故事背景](#3.4.4.0 故事背景)

[3.4.4.1 动态库故事](#3.4.4.1 动态库故事)

​编辑

[3.4.4.2 静态库故事](#3.4.4.2 静态库故事)

[3.4.5 gcc默认是动态链接](#3.4.5 gcc默认是动态链接)

[3.4.6 两个细节](#3.4.6 两个细节)

[3.4.6.1 如果我删掉C动态库呢?](#3.4.6.1 如果我删掉C动态库呢?)

[3.4.6.2 gcc默认使用动态库和动态链接](#3.4.6.2 gcc默认使用动态库和动态链接)

[3.4.7 动态库和静态库的优缺点(总结)](#3.4.7 动态库和静态库的优缺点(总结))

博主手记

结尾


前情提示

1 编译型语言和解释型语言

2 一张图总结动态库和静态库的优缺点



3 ~> Linux下的编译器:gcc和g++

3.1 概念初识

3.2 概念区分

3.3 编译

把源文件翻译成可执行二进制文件------编译的过程。

3.3.1 翻译的过程------C:重点放在编译选项上

一张图搞定------

3.3.2 一般程序的构建过程------.o

bash 复制代码
gcc -c *.c
gcc *.o -o exe
./exe

形成同名目标文件再编译,增加编译效率------

所有的.c文件编译成.o文件再链接形成可执行文件。

3.3.3 条件编译

我们得先见一见猪跑条件编译,不知道uu们还记不记得C语言条件编译是什么样的?不记得没关系,艾莉丝把C语言条件编译那篇博客的链接放下下面了------

C语言条件编译往期回顾:

预处理深入详解:预定义符号、宏、命名约定、命令行定义、条件编译、头文件的包含

还回忆不起来也没关系,艾莉丝在XShell的CentOs7上给uu们再简单复现一下------

bash 复制代码
#include<stdio.h>

void version1()
{
    printf("version1:免费\n");
}

void version2()
{
	printf("version2:收费\n");
}

 //#define v1 1

int main()
{
//#ifdef v1
	version1();
//#else 
	version2();
//#endif                                                                                                                                        
	return 0;
}

中间这些艾莉丝把条件编译给注释掉了,gcc一下,大家可以看看------

bash 复制代码
[Alice@VM-4-17-centos ~]$ vim soft.c
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft -DFREE
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft -DFREE
[Alice@VM-4-17-centos ~]$ vim soft.c
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft -DFREE
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft.c -o -DFREE=1
[Alice@VM-4-17-centos ~]$ ./soft
version1:免费
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft
[Alice@VM-4-17-centos ~]$ ./soft
version1:免费
[Alice@VM-4-17-centos ~]$ vim soft.c
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft
[Alice@VM-4-17-centos ~]$ ./soft
version2:收费
[Alice@VM-4-17-centos ~]$ vim soft.v
[Alice@VM-4-17-centos ~]$ vim soft.c
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft
[Alice@VM-4-17-centos ~]$ ./soft
version1:免费
version2:收费
[Alice@VM-4-17-centos ~]$ vim soft.c

3.3.4 编译器和对应语言的关系------自举

两张图搞定------

3.4 链接

3.4.1 初步理解链接

一张图理解------

3.4.2 关于链接和指令查看:ldd

ldd:查看文件依赖哪个库。

bash 复制代码
[Alice@VM-4-17-centos ~]$ vim soft.cpp
[Alice@VM-4-17-centos ~]$ g++ soft.cpp -o softpp 
[Alice@VM-4-17-centos ~]$ ll
total 52
-rwxrwxr-x 1 Alice Alice 8424 Nov 19 23:13 a.out
-rwxrwxr-x 1 Alice Alice 8424 Nov 19 23:31 -DFREE=1
-rw-rw-r-- 1 Alice Alice  827 Nov 12 23:32 install.sh
drwxr-xr-x 2 root  root  4096 Nov 19 22:48 Ludy
-rw-rw-r-- 1 Alice Alice  234 Nov 20 02:41 soft.c
-rw-rw-r-- 1 Alice Alice   85 Nov 20 03:25 soft.cpp
-rwxrwxr-x 1 Alice Alice 8968 Nov 20 03:25 softpp
-rw-r--r-- 1 root  root     0 Nov 12 22:25 test.txt
[Alice@VM-4-17-centos ~]$ ldd softpp
	linux-vdso.so.1 =>  (0x00007ffda5b84000)
	libstdc++.so.6 => /home/Alice/.VimForCpp/vim/bundle/YCM.so/el7.x86_64/libstdc++.so.6 (0x00007f1a1c8fd000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f1a1c5fb000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f1a1c3e5000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f1a1c017000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f1a1cc7e000)

我们用cat打印一下艾莉丝写的soft.cpp的内容看看------

bash 复制代码
[Alice@VM-4-17-centos ~]$ cat soft.cpp
#include<iostream>

int main()
{
    std::cout<<"hello"<<std::endl;

    return 0;
}

3.4.3 动态库和静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大(大不少,前面展示过了),但在运行时也就不再需要库文件了。其后缀名一般为".a"

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由
运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为"so",如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。完成了链接之后,gcc就可以生成可执行文件,如下所示------

bash 复制代码
gcc hello.o -o hello

gcc默认生成的二进制程序,是动态链接的,这点可以通过file命令验证。

3.4.4 如何理解库和链接?通过一个小故事先感性地理解一下吧!

我们通过一个小故事来感性地理解一下库和链接------

3.4.4.0 故事背景

我们先了解一下故事的人物设定,主人公小艾是菲托亚初中的尖子生,以优异的成绩考入到阿斯拉王国最好的高中------阿斯拉王国一中,小艾喜欢上网,但是阿斯拉王国高中是一所"军事化管理"的顶级学府,强制学生住校,进入高中后,小艾的成绩一直名列前茅,稳居年级第一的宝座,但是小艾一直想上网,好在高中前的暑假,小艾爸爸让小艾向刚刚从阿斯拉王国一中毕业的邻居鲁迪同学请教高中的各种事宜,小艾趁机把想要上网的想法告诉了鲁迪学长,鲁迪邪魅一笑,告诉小艾:从学校东门出发,先向左走100米,再向右走100米,有一家[米里斯电竞馆],我高中时只要上网就会到那里去。最近,小艾又有些蠢蠢欲动了......

3.4.4.1 动态库故事

第一个小故事到这里就结束啦!艾莉丝在这里再解释一下故事梗概------

主人公小艾(不是钟小艾!!!)是年级第一,上了半个月网之后,一中学生去米里斯电竞馆玩的人越来越多,月考成绩出来后,老师注意到小艾他们班的成绩明显下滑,把这个情况告知了校长洛琪希女士,校长非常生气😠于是拨打110给附近的骑士团:举报电竞馆老板营业执照过期,骑士团于是出动查抄了电竞馆,可怜一中那些想要上网的同学们,同电竞馆老板在血与火中铸就的革命友谊就此告一段落------暂时。

3.4.4.2 静态库故事

小艾有这么一位神通广大的老父亲,小艾把情况一五一十交代了,小艾说:"我第一次月考比全校第二高100分,现在只高了50多分,就是因为不能上网才退步的!",父亲一个电话打给了校长:"校长,我们家小艾想要上网,你们不要阻止"。校长说:"好吧好吧,谁叫小艾是年级第一呢?"于是父亲准备去买电脑,刚好 [米里斯电竞馆] 的老板拘留完刚刚放出来,小艾父亲找到老板,买走了一台电脑,小艾又能上网了!小艾把电脑带到了宿舍,其他同学看到后心痒难耐,也跑去找爸爸,爸爸们把电话又打到了校长办公室,"校长,我们家孩子想上网,你们老师就不要管啦!"洛琪希摇摇头:"你们都这么说了,那还说啥,让孩子们上网不就行了吗?"爸爸们找到 [米里斯电竞馆] 的老板,又从他那里买走了电脑,老板因祸得福,走在校门口迎面撞见了骑士团的成员👮‍♀️,老板忍不住轻哼~😒"看我干嘛?我已经不开网吧了哦!"骑士团气得牙痒痒,拿他也没办法。

3.4.5 gcc默认是动态链接

bash 复制代码
[Alice@VM-4-17-centos ~]$ gcc soft.c -o soft
[Alice@VM-4-17-centos ~]$ ll
total 64
-rwxrwxr-x 1 Alice Alice 8424 Nov 19 23:13 a.out
-rwxrwxr-x 1 Alice Alice 8424 Nov 19 23:31 -DFREE=1
-rw-rw-r-- 1 Alice Alice  827 Nov 12 23:32 install.sh
drwxr-xr-x 2 root  root  4096 Nov 19 22:48 Ludy
-rwxrwxr-x 1 Alice Alice 8424 Nov 20 02:57 soft
-rw-rw-r-- 1 Alice Alice  234 Nov 20 02:41 soft.c
-rwxrwxr-x 1 Alice Alice 8424 Nov 19 23:17 soft-p
-rw-rw-r-- 1 Alice Alice   77 Nov 13 18:00 test.c
-rw-r--r-- 1 root  root     0 Nov 12 22:25 test.txt
[Alice@VM-4-17-centos ~]$ ldd soft
	linux-vdso.so.1 =>  (0x00007ffffc7f4000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f655e1dc000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f655e5aa000)
[Alice@VM-4-17-centos ~]$ file soft
soft: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=8b86a7a1eb26a5bbc12c85f51924cbd687cc6817, not stripped

如下图所示------

3.4.6 两个细节

3.4.6.1 如果我删掉C动态库呢?

一般而言,系统中大部分指令(C/C++编写的二进制指令)就无法运行了!

3.4.6.2 gcc默认使用动态库和动态链接

**Linux系统中,默认只安装了动态库,怎么办?**我们手动安装一下静态库就可以了------

Unbuntu版本的uu们可以大模型搜索一下,安装下来就可以了。

如果前面的强制静态链接可以生效,说明您的Linux默认安装了动态库。

3.4.7 动态库和静态库的优缺点(总结)

一张图解决------


博主手记

下面就是艾莉丝在学习vim这部分知识时的手写笔记啦,大家可以了解一下------


结尾

uu们,本文的内容到这里就全部结束了,艾莉丝再次感谢您的阅读!

往期回顾:

【Linux基础开发工具 (三)】Vim从入门到精通(下):效率翻倍的编辑技巧与个性化配置攻略

结语:本期我们在前一篇博客的基础上继续深入学习了Linux中的指令篇,希望对学习Linux指令相关内容的uu有所帮助,不要忘记给博主"一键四连"哦!

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡

૮₍ ˶ ˊ ᴥ ˋ˶₎ა

相关推荐
江瀚视野1 分钟前
小马智行发布PonyWorld世界模型2.0,如何改变市场?
人工智能
XM_jhxx3 分钟前
厦门晚报报道简会入选省首批“小快轻准”数字化产品
大数据·人工智能
Ivanqhz4 分钟前
SMT(Satisfiability Modulo Theories,基于模理论的可满足性)
人工智能·算法·机器学习
程序员老邢4 分钟前
【技术底稿 10】16G Ubuntu 服务器手动部署 Ollama 0.20.4 全流程(避坑 HTTP2 错误)
服务器·ubuntu·ai·语言模型·devops
饼瑶6 分钟前
Isaac Sim 5.0.0 Docker 部署手册(实验室服务器)
服务器·docker·容器
dddddppppp1236 分钟前
linux head.s 从第一条指令到start_kernel
linux·运维·服务器
ZGi.ai6 分钟前
一个LLM网关需要处理哪些工程问题?多模型路由与成本归因实战
大数据·网络·人工智能
BioRunYiXue6 分钟前
AlphaGenome:DeepMind 新作,基因组学迎来 Alpha 时刻
java·linux·运维·网络·数据库·人工智能·eclipse
十五年专注C++开发7 分钟前
windows和linux使用system启动进程是一样的吗?
linux·c++·windows·system
Dshuishui8 分钟前
VSCode 环境下编译运行 C++ 项目
c++·ide·vscode