使用传统程序语言进行编译的简单范例
单一程序:印出 Hello World
- 编辑程序码,亦即原始码
[root@www ~]# vim hello.c <==用 C 语言写的程序扩展名建议用 .c #include <stdio.h> int main(void) { printf("Hello World\n"); }
开始编译与测试运行
[root@www ~]# gcc hello.c [root@www ~]# ll hello.c a.out -rwxr-xr-x 1 root root 4725 Jun 5 02:41 a.out <==此时会产生这个档名 -rw-r--r-- 1 root root 72 Jun 5 02:40 hello.c [root@www ~]# ./a.out Hello World <==呵呵!成果出现了!
在默认的状态下,如果我们直接以 gcc 编译原始码,并且没有加上任何参数,则运行档的档名会被自动配置为 a.out 这个文件名称。 在默认的状态下,如果我们直接以 gcc 编译原始码,并且没有加上任何参数,则运行档的档名会被自动配置为 a.out 这个文件名称,可以将上面的第 2 个步骤改成这样:
[root@www ~]# gcc -c hello.c [root@www ~]# ll hello* -rw-r--r-- 1 root root 72 Jun 5 02:40 hello.c -rw-r--r-- 1 root root 868 Jun 5 02:44 hello.o <==就是被产生的目标档 [root@www ~]# gcc -o hello hello.o [root@www ~]# ll hello* -rwxr-xr-x 1 root root 4725 Jun 5 02:47 hello <==这就是可运行档! -o 的结果 -rw-r--r-- 1 root root 72 Jun 5 02:40 hello.c -rw-r--r-- 1 root root 868 Jun 5 02:44 hello.o [root@www ~]# ./hello Hello World
主、副程序连结:副程序的编译
撰写所需要的主、副程序
# 1. 编辑主程序: [root@www ~]# vim thanks.c #include <stdio.h> int main(void) { printf("Hello World\n"); thanks_2(); } # 上面的 thanks_2(); 那一行就是呼叫副程序啦! [root@www ~]# vim thanks_2.c #include <stdio.h> void thanks_2(void) { printf("Thank you!\n"); }
进行程序的编译与连结 (Link)
# 2. 开始将原始码编译成为可运行的 binary file : [root@www ~]# gcc -c thanks.c thanks_2.c [root@www ~]# ll thanks* -rw-r--r-- 1 root root 76 Jun 5 16:13 thanks_2.c -rw-r--r-- 1 root root 856 Jun 5 16:13 thanks_2.o <==编译产生的! -rw-r--r-- 1 root root 92 Jun 5 16:11 thanks.c -rw-r--r-- 1 root root 908 Jun 5 16:13 thanks.o <==编译产生的! [root@www ~]# gcc -o thanks thanks.o thanks_2.o [root@www ~]# ll thanks* -rwxr-xr-x 1 root root 4870 Jun 5 16:17 thanks <==最终结果会产生这玩意儿 # 3. 运行一下这个文件: [root@www ~]# ./thanks Hello World Thank you!
如果有一天,你升级了 thanks_2.c 这个文件的内容,则你只要重新编译 thanks_2.c 来产生新的 thanks_2.o ,然后再以连结制作出新的 binary 可运行档即可!而不必重新编译其他没有更动过的原始码文件。
呼叫外部函式库:加入连结的函式库
计算出三角函数里面的 sin (90度角):
[root@www ~]# vim sin.c
#include <stdio.h>
int main(void)
{
float value;
value = sin ( 3.14 / 2 );
printf("%f\n",value);
}
[root@www ~]# gcc sin.c
sin.c: In function 'main':
sin.c:5: warning: incompatible implicit declaration of built-in function 'sin'
/tmp/ccsfvijY.o: In function `main':
sin.c:(.text+0x1b): undefined reference to `sin'//没有 sin 的相关定义参考值!
collect2: ld returned 1 exit status
# 注意看到上面最后一行,会有个错误信息,代表没有成功!
- 编译时加入额外函式库连结的方式:
使用 gcc 编译时所加入的那个 -lm 是有意义的,他可以拆开成两部份来看:[root@www ~]# gcc sin.c -lm -L/lib -L/usr/lib <==重点在 -lm [root@www ~]# ./a.out <==尝试运行新文件! 1.000000
-l :是『加入某个函式库(library)』的意思, m :则是 libm.so 这个函式库,其中, lib 与扩展名(.a 或 .so)不需要写
gcc 的简易用法 (编译、参数与链结)
# 仅将原始码编译成为目标档,并不制作连结等功能:
[root@www ~]# gcc -c hello.c
# 会自动的产生 hello.o 这个文件,但是并不会产生 binary 运行档。
# 在编译的时候,依据作业环境给予最佳化运行速度
[root@www ~]# gcc -O hello.c -c
# 会自动的产生 hello.o 这个文件,并且进行最佳化喔!
# 在进行 binary file 制作时,将连结的函式库与相关的路径填入
[root@www ~]# gcc sin.c -lm -L/usr/lib -I/usr/include
# 这个命令较常下达在最终连结成 binary file 的时候,
# -lm 指的是 libm.so 或 libm.a 这个函式库文件;
# -L 后面接的路径是刚刚上面那个函式库的搜寻目录;
# -I 后面接的是原始码内的 include 文件之所在目录。
# 将编译的结果输出成某个特定档名
[root@www ~]# gcc -o hello hello.c
# -o 后面接的是要输出的 binary file 档名
# 在编译的时候,输出较多的信息说明
[root@www ~]# gcc -o hello hello.c -Wall
# 加入 -Wall 之后,程序的编译会变的较为严谨一点,
# 所以警告信息也会显示出来!