使用传统程序语言进行编译的简单范例

单一程序:印出 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
# 注意看到上面最后一行,会有个错误信息,代表没有成功!
  • 编译时加入额外函式库连结的方式:
    [root@www ~]# gcc sin.c -lm -L/lib -L/usr/lib  <==重点在 -lm 
    [root@www ~]# ./a.out                          <==尝试运行新文件!
    1.000000
    
    使用 gcc 编译时所加入的那个 -lm 是有意义的,他可以拆开成两部份来看:
    -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 之后,程序的编译会变的较为严谨一点,
# 所以警告信息也会显示出来!