【linux】gcc makefile

Alt

🔥个人主页Quitecoder

🔥专栏linux笔记仓

Alt

目录

    • 01.gcc如何完成
    • 02.gcc选项
    • 03.函数库与动静态链接
      • 静态链接
      • 动态链接
      • 库文件
      • 特点和用途
      • 动态链接
      • 版本和兼容性
    • 04.makefile
      • 自动推导

01.gcc如何完成

在这里插入图片描述

  • 预处理(进行宏替换)
    • 预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
    • 预处理指令是以#号开头的代码行
    • 实例: gcc –E test1.c –o test1.i
    • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
    • 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
  • 编译(生成汇编)
    • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言
    • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
    • 实例: gcc –S test1.i –o test1.s
  • 汇编(生成机器可识别代码)
    • 汇编阶段是把编译阶段生成的“.s”文件转成目标文件
    • 读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
    • 实例: gcc –c test1.s –o test1.o
  • 链接(生成可执行文件或库文件)
    • 在成功编译之后,就进入了链接阶段。
    • 实例: gcc test1.o –o test1

在这里插入图片描述
我们可以指定可执行文件的文件名

cpp文件:以cpp或者cc为后缀,不能用gcc编译,用g++编译

在这里插入图片描述

02.gcc选项

  • -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
  • -S 编译到汇编语言不进行汇编和链接
  • -c 编译到目标代码
  • -o 文件输出到 文件
  • -static 此选项对生成的文件采用静态链接
  • -g 生成调试信息。GNU 调试器可利用该信息。
  • -shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
  • -O0
  • -O1
  • -O2
  • -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
  • -w 不生成任何警告信息。
  • -Wall 生成所有警告信息

下面体会一下各种过程:

在这里插入图片描述

gcc –E test1.c –o test1.i

在这里插入图片描述
上面八百多行,都是预处理过程头文件stdio.h展开得到的

在这里插入图片描述
在这里插入图片描述

gcc -S test.i -o test.s

在这里插入图片描述

gcc -c test.s -o test.o

在这里插入图片描述

03.函数库与动静态链接

在软件开发中,链接是将一个或多个编译后的目标文件(.o文件)和库文件合并,生成可执行文件或更大的库文件的过程。链接可以是静态的(static)或动态的(dynamic),并且涉及到库文件,这些库可以是静态库(.a文件)或动态库(.so 文件或在Windows上的.dll 文件

我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

答案是 :系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用

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

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

 gcc hello.o –o hello

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

在软件开发中,链接是将一个或多个编译后的目标文件(.o 文件)和库文件合并,生成可执行文件或更大的库文件的过程。链接可以是静态的(static)或动态的(dynamic),并且涉及到库文件,这些库可以是静态库(.a 文件)或动态库(.so 文件或在Windows上的.dll 文件)。

静态链接

  • 定义:在静态链接中,链接器(如GNU的 ld)将所有用到的库文件的内容复制到最终的可执行文件中。这意味着,运行程序时不需要这些库在系统中存在,因为所有必需的代码都已经包含在单个可执行文件中了。

  • 优点

    • 独立性:生成的可执行文件不依赖于外部的库文件,因此更易于在没有安装这些库的系统上运行。
    • 性能:在某些情况下,静态链接的应用程序启动和运行速度可能会更快,因为避免了运行时解析库符号的开销。
  • 缺点

    • 文件大小:可执行文件会包含所有静态链接的库的代码,这会显著增加文件大小。
    • 更新和维护:如果库需要更新(例如修复安全漏洞),则必须重新编译和链接整个应用程序。

动态链接

  • 定义:在动态链接中,程序使用的库在编译时不被复制到可执行文件中。相反,库留在独立的文件中(动态库),在程序启动或运行时由动态链接器(如Linux上的 ld.so)加载。

  • 优点

    • 内存和磁盘空间效率:多个程序可以共享内存中同一个库的单个副本,减少了内存和磁盘的使用。
    • 易于更新:更新库文件后,所有使用该动态库的程序都会自动使用更新后的版本,无需重新链接。
  • 缺点

    • 运行时依赖:程序运行时必须能够访问它所依赖的动态库。共享动态库,但是一旦动态库缺失,所有的动态链接这个库的程序,都无法执行了!
    • 启动时间:由于需要在运行时加载外部库,动态链接的应用程序可能启动较慢。

库文件

  • 静态库:通常以 .a (Archive) 格式存储,是多个目标文件的集合。使用静态库时,其内容在编译时整合到最终的可执行文件中。

  • 动态库:通常以 .so (Shared Object) 或 .dll (Dynamic Link Library) 格式存储。动态库在运行时被加载,可以被多个程序共享。

[dyx@VM-8-13-centos ~]$ ll
total 44
-rwxrwxr-x 1 dyx  dyx  8968 Sep 22 21:54 a.out
d--------- 2 dyx  dyx  4096 Jul 24 17:52 dir
drwxr-xr-x 2 root root 4096 Sep 22 16:06 dir1
-rw-rw-r-- 1 dyx  dyx   827 Jul 22 10:03 install.sh
-rwxrwxr-x 1 dyx  dyx  8408 Sep 22 22:26 my
drwxr-xr-x 2 root root 4096 Sep 19 17:09 test
-rw-rw-r-- 1 dyx  dyx   209 Sep 23 17:15 test.c
[dyx@VM-8-13-centos ~]$ ldd a.outlinux-vdso.so.1 =>  (0x00007ffdc15d2000)libstdc++.so.6 => /home/dyx/.VimForCpp/vim/bundle/YCM.so/el7.x86_64/libstdc++.so.6 (0x00007fc019380000)libm.so.6 => /lib64/libm.so.6 (0x00007fc01907e000)libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fc018e68000)libc.so.6 => /lib64/libc.so.6 (0x00007fc018a9a000)/lib64/ld-linux-x86-64.so.2 (0x00007fc019701000)
[dyx@VM-8-13-centos ~]$ ls /lib64/libc.so.6
/lib64/libc.so.6
[dyx@VM-8-13-centos ~]$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Mar 23  2023 /lib64/libc.so.6 -> libc-2.17.so

libc-2.17.so 是 Linux 系统中的一个非常核心的动态库,也被称为 C 标准库。这个库提供了标准 C语言的许多基本功能和服务,包括输入输出操作、字符串处理、内存分配、数学计算等。此外,它还提供了操作系统级别的接口,如系统调用的封装(例如文件操作、进程控制等)。

特点和用途

  1. 标准C功能libc 包含标准 C 函数,如 printf, malloc, strncpy 等。
  2. 系统级接口:提供 POSIX 标准定义的各种系统调用的接口,如 open, read, write, fork, exec 等。
  3. 本地化和时间管理:处理各种与地区、文化、时间和日期相关的功能。

动态链接

  • 动态链接libc.so.6 是最常见的符号链接名称,它指向系统中当前 C 标准库的具体版本,比如 libc-2.17.so。这种符号链接机制允许系统在保持相同库名(libc.so.6)的情况下升级到新版本的库,而不会打断依赖它的应用程序。

版本和兼容性

  • 版本号libc-2.17 指的是 glibc(GNU C Library)的特定版本。glibc 是大多数 Linux 发行版使用的 libc 实现。
  • 向后兼容性:新版本的 glibc 设计时通常会考虑到向后兼容性,使得旧的应用程序仍然可以在新版本的库上运行。

libc-2.17.so 是系统中的标准 C 库实现的一个版本,它是许多 Linux 程序运行不可或缺的组成部分。通过 libc.so.6 这样的符号链接,系统能够方便地管理库的版本,而不影响依赖这些库的应用程序。

在这里插入图片描述
在这里插入图片描述
默认情况,Linux上,一般静态库都是默认没有安装的

sudo yum install -y glibc-static libstdc++-static

04.makefile

make是一个命令
makefile是一个文件

在这里插入图片描述

这个 Makefile 的片段定义了如何编译一个名为 mytest 的目标文件,以及如何清理生成的文件。让我们逐行解析这个片段的内容。

Makefile 内容解析

mytest: test.cgcc -o mytest test.c
.PHONY: clean
clean:rm -f mytest

第一部分:目标以及规则

mytest: test.cgcc -o mytest test.c
  • mytest: test.c

    • 目标mytest
      • 这是 make 尝试构建的一个目标文件(通常是可执行文件)
    • 依赖test.c
      • 这个目标文件依赖于源文件 test.c。如果 test.c 发生变化,mytest 需要重新构建。
  • gcc -o mytest test.c

    • 这是构建 mytest 的具体命令。

第二部分:伪目标 .PHONY

.PHONY: clean
  • .PHONY: clean
    • 伪目标(Phony Targets):这是一个特殊的伪目标声明,告知 make,目标 clean 不是一个文件,也不应被与文件名相混淆。
    • 这样做可以防止在有同名文件(如 clean 文件)存在时,引起误解和错误。
      在这里插入图片描述

第三部分:清理规则

clean:rm -f mytest
  • 目标clean
  • 命令rm -f mytest
    • rm -f mytest:删除生成的可执行文件 mytest
    • -f:强制删除文件,不显示文件不存在的错误。

整体描述:

  • 目标文件 mytest
    • 依赖于 test.c 源文件。
    • 构建命令:gcc -o mytest test.c
    • 当执行 make mytest 或单纯 make如果 mytest 是第一个目标)时,make 会检查 test.c
    • 如果test.c 更新过或 mytest 不存在,会执行 gcc -o mytest test.c

make工具使用文件的时间戳来决定哪些目标需要重新构建。具体来说,make会比较目标文件和其依赖文件的修改时间戳。如果依赖文件比目标文件更新,则目标文件需要重新构建。这个机制是通过以下步骤实现的:

  • 依赖关系解析:make读取Makefile并解析目标文件及其依赖文件的关系。
  • 时间戳比较:make比较目标文件和依赖文件的修改时间戳。如果依赖文件的时间戳比目标文件新,则认为目标文件需要重新构建。
  • 清理目标 clean

    • 伪目标声明,确保 clean 仅作为命令,不是物理文件。
    • 当执行 make clean 时,命令 rm -f mytest 会运行,删除 mytest
    • 这用于清理生成的文件,使工作目录恢复到干净状态。
  • 构建可执行文件

    make
    

    或者

    make mytest
    

    这会依据 test.c 编译 mytest

  • 清理生成文件

    make clean
    

    这会删除 mytest,使目录重新变得干净。

自动推导

  1 code.exe:code.o2   gcc code.o -o code.exe3 code.o:code.s4   gcc -c code.s -o code.o5 code.s:code.i6   gcc -S code.i -o code.s7 code.i:code.c8   gcc -E code.c -o code.i9 10 .PHONY:clean11 clean:12   rm -f code.i code.s code.o code.exe   

用 .PHONY 修饰,伪目标的特性是,总是被执行的。

makefile/make会自动根据文件中的依赖关系,进行自动推导,帮助我们执行所有相关的依赖方法

这个 Makefile 使用了变量来定义构建目标和源文件路径,以及自动化构建和清理过程。让我们逐行解析这个 Makefile 的内容。

bin=mycode
src=test.c$(bin):$(src)@gcc -o $@ $^@echo "compiler $(src) to $(bin)...".PHONY: clean
clean:@rm -f $(bin)@echo "clean project..."
  1. 定义目标文件和源文件的变量
    bin=mycode
    src=test.c
    
    • bin:存储生成的可执行文件名 mycode
    • src:存储源文件名 test.c
    • 使用变量可以提高 Makefile 的可读性和维护性,尤其是在需要变更文件名时,只需修改变量定义即可

目标和依赖关系

  1. 定义构建目标和依赖关系

    $(bin): $(src)@gcc -o $@ $^@echo "compiler $(src) to $(bin)..."
    
    • $(bin): $(src)
      • 目标$(bin) 展开为 mycode,即 make 将生成的可执行文件。
      • 依赖$(src) 展开为 test.c,即生成可执行文件 mycode 需要依赖源文件 test.c
    • 生成目标文件的命令
      • @gcc -o $@ $^
        • @:抑制命令回显,使得在执行这条命令时不输出命令本身。可以使输出更加整洁。
        • -o $@$@ 是自动化变量,代表目标文件 mycode
        • $^:所有的依赖文件,即 test.c
      • @echo "compiler $(src) to $(bin)..."
        • $(src) 展开为 test.c
        • $(bin) 展开为 mycode
        • 显示编译信息,告知用户当前在进行的操作。

自动化变量:

$@:代表规则中的目标文件。 $<:第一个依赖文件。 $?:所有比目标文件新的依赖文件。

伪目标和清理规则

  1. 定义伪目标和清理规则
    .PHONY: clean
    clean:@rm -f $(bin)@echo "clean project..."
    
    • 伪目标声明 .PHONY: clean
      • clean 被声明为伪目标,表示它只是一个标签,不对应实际文件名。确保即使有同名文件 clean,也不会造成误会。
    • 清理规则
      • clean: @rm -f $(bin)
        • @rm -f $(bin):删除生成的可执行文件 mycode$(bin) 展开为 mycode
      • @echo "clean project...":显示清理信息,告知用户当前在进行的清理操作。
  • 变量的使用

    • bin=mycodesrc=test.c 定义了构建可执行文件和源文件的变量。使用变量可以增加 Makefile 的灵活性和可读性。
  • 构建过程

    • 依赖链:mycode <- test.c
    • 当源文件 test.c 变化时,目标文件 mycode 会重新生成。

    构建命令

    make
    

    这会触发以下操作:

    • 使用 gcc 命令编译 test.c,生成 mycode
    • 使用 echo 命令输出编译信息。

    整个过程如下:

    • @gcc -o mycode test.c
    • @echo "compiler test.c to mycode..."
  • 清理过程

    • 清理生成的可执行文件 mycode

    清理命令

    make clean
    

    这会触发以下操作:

    • 使用 rm 命令删除 mycode
    • 使用 echo 命令输出清理信息。

    整个过程如下:

    • @rm -f mycode
    • @echo "clean project..."

通过这个 Makefile,用户可以方便地编译和清理项目,确保构建过程的自动化和高效性。使用变量不仅使得 Makefile 更加灵活,还提高了可读性和可维护性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54682.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

828华为云征文|使用Flexus X实例创建FDS+Nginx服务实现图片上传功能

一、Flexus X实例 什么是Flexus X实例呢&#xff0c;这是华为云最新推出的云服务器产品&#xff0c;如下图&#xff1a; 华为云推出的Flexus云服务器X系列&#xff0c;是在华为顶尖技术团队&#xff0c;特别是荣获国家科技进步奖的领军人物顾炯炯博士及其团队的主导下精心研发…

通过document获取节点元素

1.层级节点 <ul><li id"li1">1</li><li>2</li><li id"li3">3</li><li>4</li><li>5</li></ul><script>//获取id名为li1的元素赋值给li1let li1document.getElementById(li…

Java语言程序设计基础篇_编程练习题**18.34 (游戏:八皇后问题)

目录 题目&#xff1a;**18.34 (游戏:八皇后问题) 代码示例 代码解析 输出结果 使用文件 题目&#xff1a;**18.34 (游戏:八皇后问题) 八皇后问题是要找到一个解决方案&#xff0c;将一个皇后棋子放到棋盘上的每行中&#xff0c;并且两个皇后棋子之间不能相互攻击。编写个…

基于C#+SQL Server2005(WinForm)图书管理系统

图书管理系统 一、 首先把数据库脚本贴出来(数据库名为library) USE [library] GO /****** Object: Table [dbo].[books] Script Date: 06/12/2016 11:27:12 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[books]([bNum] [nvarchar](10…

宝塔部署vue项目出现的各种问题

使用宝塔面板&#xff0c;网站页面&#xff0c;构建php静态网页 问题一&#xff1a;图片等静态资源无法加载 找到真正请求的url&#xff0c; 然后在项目目录下面创建对应的目录&#xff0c;将资源放入 问题二&#xff1a;刷新出现404 在这里任意位置添加 ## 添加上这个配…

socket.io-client实现实前后端时通信功能

这里我使用的后端 基于node.js的koa框架 前端使用的是vite {"name": "hou","version": "1.0.0","description": "","main": "app.js","scripts": {"test": "echo …

ARM单片机的内存分布(重要)

ARM单片机的内存分布&#xff08;重要&#xff09; 一、S32K344的内存布局 MEMORY {int_pflash : ORIGIN 0x00400000, LENGTH 0x003D4000 /* 4096KB - 176KB (sBAF HSE)*/int_dflash : ORIGIN 0x10000000, LENGTH 0x00020000 /* 128KB …

BUUCTF [SCTF2019]电单车详解两种方法(python实现绝对原创)

使用audacity打开&#xff0c;发现是一段PT2242 信号 PT2242信号 有长有短&#xff0c;短的为0&#xff0c;长的为1化出来 这应该是截获电动车钥匙发射出的锁车信号 0 01110100101010100110 0010 0前四位为同步码0 。。。中间这20位为01110100101010100110为地址码0010为功…

不靠学历,不拼年资,怎么才能月入2W?

之前统计局发布了《2023年城镇单位就业人员年平均工资情况》&#xff0c;2023年全国城镇非私营单位和私营单位就业人员年平均工资分别为120698元和68340元。也就是说在去年非私营单位就业人员平均月薪1W&#xff0c;而私营单位就业人员平均月薪只有5.7K左右。 图源&#xff1a;…

两数之和、三数之和、四数之和

目录 两数之和 题目链接 题目描述 思路分析 代码实现 三数之和 题目链接 题目描述 思路分析 代码实现 四数之和 题目链接 题目描述 思路分析 代码实现 两数之和 题目链接 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 题目…

EfficientFormer实战:使用EfficientFormerV2实现图像分类任务(一)

摘要 EfficientFormerV2是一种通过重新思考ViT设计选择和引入细粒度联合搜索策略而开发出的新型移动视觉骨干网络。它结合了卷积和变换器的优势&#xff0c;通过一系列高效的设计改进和搜索方法&#xff0c;实现了在移动设备上既轻又快且保持高性能的目标。这一成果为在资源受…

Redis-01 入门和十大数据类型

Redis支持两种持久化方式&#xff1a;RDB持久化和AOF持久化。 1.RDB持久化是将Redis的数据以快照的形式保存在磁盘上&#xff0c;可以手动触发或通过配置文件设置定时触发。RDB保存的是Redis在某个时间点上的数据快照&#xff0c;可以通过恢复RDB文件来恢复数据。 2.AOF持久化…

力扣P1706全排列问题 很好的引入暴力 递归 回溯 dfs

代码思路是受一个洛谷题解里面大佬的启发。应该算是一个dfs和回溯的入门题目&#xff0c;很好的入门题目了下面我会先给我原题解思路我想可以很快了解这个思路。下面是我自己根据力扣大佬写的。 我会进行详细讲解并配上图辅助理解大家请往下看 #include<iostream> #inc…

初始MYSQL数据库(7)—— 视图

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; MYSQL 引言 前面我们学习MySQL数据库时&#xff0c;创建表之后&#xff0c;会在表中插入数据&#xff0c;在需要的时候&#xff0c;也会进行…

python文字转wav音频

借鉴博客 一.前期准备 1. pip install baidu-aip 2. pip install pydub 3. sudo apt-get install ffmpeg 二.代码 from aip import AipSpeech from pydub import AudioSegment import time#input your own APP_ID/API_KEY/SECRET_KEY APP_ID 14891501 API_KEY EIm2iXtvD…

示例:WPF中Grid显示网格线的几种方式

一、目的&#xff1a;介绍一下WPF中Grid显示网格线的几种方式 二、几种方式 1、重写OnRender绘制网格线&#xff08;推荐&#xff09; 效果如下&#xff1a; 实现方式如下&#xff1a; public class LineGrid : Grid{private readonly Pen _pen;public LineGrid(){_pen new P…

【Linux】深度解析与实战应用:GCC/G++编译器入门指南

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;Linux系统编程 这里将会不定期更新有关Linux的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目…

RabbitMQ08_保证消息可靠性

保证消息可靠性 一、生产者可靠性1、生产者重连机制&#xff08;防止网络波动&#xff09;2、生产者确认机制Publisher Return 确认机制Publisher Confirm 确认机制 二、MQ 可靠性1、数据持久化交换机、队列持久化消息持久化 2、Lazy Queue 惰性队列 三、消费者可靠性1、消费者…

速通LLaMA3:《The Llama 3 Herd of Models》全文解读

文章目录 概览论文开篇IntroductionGeneral OverviewPre-TrainingPre-Training DataModel ArchitectureInfrastructure, Scaling, and EfficiencyTraining Recipe Post-TrainingResultsVision ExperimentsSpeech Experiments⭐Related WorkConclusionLlama 3 模型中的数学原理1…

细说硫酸钙防静电地板的材质结构和优势特点

防静电地板有全钢基材的、硫酸钙基材的、铝合金基材的&#xff0c;在一些防静电要求、承载要求、铺设要求、铺装效果要求很高的场合&#xff0c;如银行、电信机房、移动机房、智能化办公室、部队指挥中心&#xff0c;通常都会使用硫酸钙防静电地板。那么什么是硫酸钙防静电地板…