赞
踩
格式:
gcc [选项] 要编译的文件 [选项] [目标文件]
常用选项:
-E
:让gcc
在预处理结束后停止编译过程,输出.i
的C语言原始文件。-S
:该选项只是进行编译而不是进行汇编,最终生成汇编代码的.s
文件。-o <filename>
:指定输出目标文件名。-c
:仅编译,不链接,输出.o
二进制目标文件。程序从源代码到可执行文件,经过预处理、编译、汇编与链接四个步骤:
.i
文件。示例:
gcc -E hello.c -o hello.i
- 1
.s
文件。示例:
gcc -S hello.i -o hello.s
- 1
.s
汇编代码转换为机器码,生成.o
目标文件。示例:
gcc -c hello.s -o hello.o
- 1
.out
)。示例:
gcc hello.o -o hello
- 1
程序流程图:
graph LR;
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2281bed57cab457e98467f0bf078fbcb.jpeg#pic_center)
A[源代码文件 .c] --> B[预处理 .i]
B --> C[编译 .s]
C --> D[汇编 .o]
D --> E[链接 可执行文件]
在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时
链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为.so
。
静态链接时,程序包含所有依赖库的代码,生成的可执行文件较大,但无需外部库即可独立运行。其后缀名一般为.a
。
可以使用
file
命令查看文件是动态链接还是静态链接:$ file /path/to/your/program /path/to/your/program: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=0x4a00b217499069528e862542e52e31418370a71b, not stripped
- 1
- 2
上述输出中的“statically linked”表明该文件是静态链接的。对于动态链接的文件,输出中则会显示“dynamically linked”。
此外可以使用
ldd
命令查看所使用的库函数:$ ldd /path/to/your/program linux-vdso.so.1 => (0x00007fffe3ff9000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f93b7d67000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f93b79ab000) ...
- 1
- 2
- 3
- 4
- 5
从
libc.so
中去掉lib
前缀和.so
后缀,可以看出它是调用了C语言的标准库。
在 Linux 或 Unix 系统中,Makefile 是一种用于自动化构建过程的脚本文件,它告诉 make
程序如何编译和链接源代码来创建可执行文件。Makefile 文件可以命名为 makefile
、Makefile
或者任何其他名字,但是使用大写的 Makefile
是一个常见的约定。
在 Makefile 中,规则是构建过程的核心,它们告诉 make
如何以及何时更新目标文件。规则的基本语法如下:
target: dependencies
commands
以下是一个简单的 Makefile 示例,用于编译 change.c
并生成可执行文件 mycode
:
mycode: change.c
gcc -o mycode change.c
在这个示例中,mycode
是一个目标,change.c
是它的依赖项。当 make
运行时,如果 change.c
比 mycode
新或者 mycode
不存在,那么 make
将执行规则中定义的命令来编译 change.c
。
.PHONY
伪目标用于执行非文件相关的任务,如清理或初始化等。由于伪目标并不对应于文件系统中的文件,因此不会受到时间戳的影响,每次都会执行其命令。使用 .PHONY
关键字可以显式地将目标标记为伪目标:
.PHONY: clean
clean:
rm -f *.o mycode
这里 clean
目标用于删除所有 .o
文件和 mycode
文件,即使这些文件不存在,make
也会尝试执行这个目标。
在 Makefile 中,命令必须使用 Tab 字符来缩进,而不是空格。这是因为 make
解释器期望 Tab 来标识命令行。
make
会检查目标和依赖项的修改时间戳。如果任何一个依赖项的修改时间比目标晚,或者目标不存在,那么 make
将执行相应的命令来更新目标。
为了触发重新编译,可以使用 touch
命令更新文件的时间戳。例如,如果修改了 change.c
文件的内容,但是时间戳没有改变,可以运行:
touch change.c
这将更新 change.c
的时间戳,使 make
认为文件已经被修改,并触发重新编译。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。