易语言怎么做ifa网站填表,wordpress修改主题插件,天津建设执业资格注册中心网站,无锡网站维护#x1f525;个人主页#xff1a;Quitecoder
#x1f525;专栏#xff1a;linux笔记仓 目录 01.gcc如何完成02.gcc选项03.函数库与动静态链接静态链接动态链接库文件特点和用途动态链接版本和兼容性 04.makefile自动推导 01.gcc如何完成 预处理(进行宏替换) 预处理功能主要…
个人主页Quitecoder
专栏linux笔记仓 目录 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.sgcc -c test.s -o test.o03.函数库与动静态链接 在软件开发中链接是将一个或多个编译后的目标文件.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 hellogcc默认生成的二进制程序是动态链接的这点可以通过 file 命令验证 在软件开发中链接是将一个或多个编译后的目标文件.o 文件和库文件合并生成可执行文件或更大的库文件的过程。链接可以是静态的static或动态的dynamic并且涉及到库文件这些库可以是静态库.a 文件或动态库.so 文件或在Windows上的.dll 文件。 静态链接 定义在静态链接中链接器如GNU的 ld将所有用到的库文件的内容复制到最终的可执行文件中。这意味着运行程序时不需要这些库在系统中存在因为所有必需的代码都已经包含在单个可执行文件中了。 优点 独立性生成的可执行文件不依赖于外部的库文件因此更易于在没有安装这些库的系统上运行。性能在某些情况下静态链接的应用程序启动和运行速度可能会更快因为避免了运行时解析库符号的开销。 缺点 文件大小可执行文件会包含所有静态链接的库的代码这会显著增加文件大小。更新和维护如果库需要更新例如修复安全漏洞则必须重新编译和链接整个应用程序。
动态链接 定义在动态链接中程序使用的库在编译时不被复制到可执行文件中。相反库留在独立的文件中动态库在程序启动或运行时由动态链接器如Linux上的 ld.so加载。 优点 内存和磁盘空间效率多个程序可以共享内存中同一个库的单个副本减少了内存和磁盘的使用。易于更新更新库文件后所有使用该动态库的程序都会自动使用更新后的版本无需重新链接。 缺点 运行时依赖程序运行时必须能够访问它所依赖的动态库。共享动态库但是一旦动态库缺失所有的动态链接这个库的程序都无法执行了!启动时间由于需要在运行时加载外部库动态链接的应用程序可能启动较慢。
库文件 静态库通常以 .a (Archive) 格式存储是多个目标文件的集合。使用静态库时其内容在编译时整合到最终的可执行文件中。 动态库通常以 .so (Shared Object) 或 .dll (Dynamic Link Library) 格式存储。动态库在运行时被加载可以被多个程序共享。
[dyxVM-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
[dyxVM-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)
[dyxVM-8-13-centos ~]$ ls /lib64/libc.so.6
/lib64/libc.so.6
[dyxVM-8-13-centos ~]$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Mar 23 2023 /lib64/libc.so.6 - libc-2.17.solibc-2.17.so 是 Linux 系统中的一个非常核心的动态库也被称为 C 标准库。这个库提供了标准 C语言的许多基本功能和服务包括输入输出操作、字符串处理、内存分配、数学计算等。此外它还提供了操作系统级别的接口如系统调用的封装例如文件操作、进程控制等。 特点和用途
标准C功能libc 包含标准 C 函数如 printf, malloc, strncpy 等。系统级接口提供 POSIX 标准定义的各种系统调用的接口如 open, read, write, fork, exec 等。本地化和时间管理处理各种与地区、文化、时间和日期相关的功能。
动态链接
动态链接libc.so.6 是最常见的符号链接名称它指向系统中当前 C 标准库的具体版本比如 libc-2.17.so。这种符号链接机制允许系统在保持相同库名libc.so.6的情况下升级到新版本的库而不会打断依赖它的应用程序。
版本和兼容性
版本号libc-2.17 指的是 glibcGNU C Library的特定版本。glibc 是大多数 Linux 发行版使用的 libc 实现。向后兼容性新版本的 glibc 设计时通常会考虑到向后兼容性使得旧的应用程序仍然可以在新版本的库上运行。
libc-2.17.so 是系统中的标准 C 库实现的一个版本它是许多 Linux 程序运行不可或缺的组成部分。通过 libc.so.6 这样的符号链接系统能够方便地管理库的版本而不影响依赖这些库的应用程序。 默认情况Linux上一般静态库都是默认没有安装的
sudo yum install -y glibc-static libstdc-static04.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.cmytest: 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 的内容。
binmycode
srctest.c$(bin):$(src)gcc -o $ $^echo compiler $(src) to $(bin)....PHONY: clean
clean:rm -f $(bin)echo clean project...定义目标文件和源文件的变量binmycode
srctest.cbin存储生成的可执行文件名 mycode。src存储源文件名 test.c。使用变量可以提高 Makefile 的可读性和维护性尤其是在需要变更文件名时只需修改变量定义即可。
目标和依赖关系 定义构建目标和依赖关系 $(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。显示编译信息告知用户当前在进行的操作。 自动化变量 $代表规则中的目标文件。 $第一个依赖文件。 $?所有比目标文件新的依赖文件。 伪目标和清理规则
定义伪目标和清理规则.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...显示清理信息告知用户当前在进行的清理操作。 变量的使用 binmycode 和 srctest.c 定义了构建可执行文件和源文件的变量。使用变量可以增加 Makefile 的灵活性和可读性。 构建过程 依赖链mycode - test.c。当源文件 test.c 变化时目标文件 mycode 会重新生成。 构建命令 make这会触发以下操作 使用 gcc 命令编译 test.c生成 mycode。使用 echo 命令输出编译信息。 整个过程如下 gcc -o mycode test.cecho compiler test.c to mycode... 清理过程 清理生成的可执行文件 mycode。 清理命令 make clean这会触发以下操作 使用 rm 命令删除 mycode。使用 echo 命令输出清理信息。 整个过程如下 rm -f mycodeecho clean project...
通过这个 Makefile用户可以方便地编译和清理项目确保构建过程的自动化和高效性。使用变量不仅使得 Makefile 更加灵活还提高了可读性和可维护性