1. Linux下可执行文件
Linux系统上面,一个文件要执行首先要有可执行权限,具有 x 权限。
Linux系统上真正识别可执行文件其实是二进制文件。
查看文件是否为二进制程序用 file 命令
[gang@www]$ file /bin/ls
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), stripped
ELF 64-bit LSB executable 表示可执行文件
uses shared libs 表示是否使用共享库
2. C可执行文件生成流程
通过4个步骤
编辑
编译
链接
执行
2.1 编辑
文件命名为 *.c
[gang@www]$ vim hello.c
#include <stdio.h>
int main(void){
printf("Hello World !");
}
2.2 编译
linux使用gcc编译,
[gang@www]$ gcc hello.c
[gang@www]$ ll
total 8
-rwxrwxr-x 1 work work 6772 May 31 14:22 a.out
-rw-rw-r-- 1 work work 1496 May 31 13:36 hello.o
生成执行文件a.out
编译生成目标文件 object file
目标文件扩展名为 .o
[gang@www]$ gcc -c hello.c
[gang@www]$ ll
total 8
-rw-rw-r-- 1 work work 66 May 31 13:36 hello.c
-rw-rw-r-- 1 work work 1496 May 31 13:36 hello.o
gcc -o 重新名称生成执行文件
[gang@www]$ gcc -o hello hello.o
[gang@www]$ ll
total 16
-rwxrwxr-x 1 work work 6772 May 31 14:14 hello
-rw-rw-r-- 1 work work 66 May 31 13:36 hello.c
-rw-rw-r-- 1 work work 1496 May 31 13:36 hello.o
运行
[gang@www]$ ./hello
Hello World !
2.3 链接
链接器(linker)将源代码文件中由编译器产生的各个模块组合起来,再从C语言提供的程序库中添加必要的代码模块,将它们组合成一个可执行文件。
如果程序太大,也可以拆成几个源代码文件,再用链接器连接起来。
[gang@www]$ vim hello.c
#include <stdio.h>
int main(void){
printf("Hello World. \n");
thank_you();
}
[gang@www]$ thank_you.c
#include <stdio.h>
void thank_you(void){
printf("Thank you.\n");
}
编译
[gang@www]$ gcc -c hello.c thank_you.c
[gang@www]$ ll
total 16
-rw-rw-r-- 1 work work 85 May 31 14:45 hello.c
-rw-rw-r-- 1 work work 1560 May 31 14:46 hello.o
-rw-rw-r-- 1 work work 71 May 31 14:46 thank_you.c
-rw-rw-r-- 1 work work 1504 May 31 14:46 thank_you.o
[gang@www]$ gcc -o hello hello.o thank_you.o
[gang@www]$ ll
total 24
-rwxrwxr-x 1 work work 6978 May 31 14:47 hello
-rw-rw-r-- 1 work work 85 May 31 14:45 hello.c
-rw-rw-r-- 1 work work 1560 May 31 14:46 hello.o
-rw-rw-r-- 1 work work 71 May 31 14:46 thank_you.c
-rw-rw-r-- 1 work work 1504 May 31 14:46 thank_you.o
[gang@www]$ ./hello
Hello World.
Thank you.
3. gcc简易用法
gcc -c hello.c 生成目标文件,不生成可执行文件
gcc-O hello.c -c 生成目标文件,并进行优化
gcc sin.c -lm -L/usr/lib -I/usr/include
-lm: -l 加入某个函数库, m表示libm.so这个库, lib和扩展名(.a或.so)不需要写
-L 表示引入函数库的搜索目录, 默认为 /lib 或 /usr/lib/
-I 指源代码 include所在的目录, 默认为 /usr/include/
gcc -o hello hello.c
-o 后面为要输出的二进制文件名
gcc -o hello hello.c -Wall
-Wall 程序编译会变得较为严谨一点, 所以警告信息会显示出来。
通常-Wall或-O 这些非必要参数称为标志 FLAGS,C语言中简称为 CFLAGS。
4. 函数库
linux函数库分为静态函数库和动态函数库。
静态(Static) 函数库
扩展名:
.a , 通常命名 libXXX.a
编译:
编译时直接整合到执行程序,生成的文件会大一点
独立执行:
可以独立执行,不需要向外读取函数库
升级难易度:
函数库升级时,整体要重新编译。
动态(Dynamic)函数库
扩展名:
.so, 通常名称libXXX.so
编译:
编译时,程序只记录一个“指向”(Pointer)位置, 动态函数库内容没有被整合到执行文件中,
执行需要时,程序才会读取函数库内容。 文件会比较小。
独立执行:
程序不能独立执行, 必须有函数库文件存在才行,并且位置目录不能变
升级难易度:
函数库升级时,函数库不需要重新编译,
目前,Linux倾向于使用动态函数库。
查看可执行文件使用了什么动态函数库,使用ldd命令
[gang@www]$ ldd /bin/ls
librt.so.1 => /lib64/tls/librt.so.1 (0x000000302bc00000)
libacl.so.1 => /lib64/libacl.so.1 (0x000000302b600000)
地址: http://blog.csdn.net/yonggang7/article/details/46287777