Linux下C的编写和执行


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 
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 
int main(void){
    printf("Hello World. \n");
    thank_you();
}

[gang@www]$ thank_you.c

#include 
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)

相关内容

    暂无相关文章