Linux gcc编译器

Linux操作系统认识的语言是二进制文件。具体的从编程到执行的过程是:首先利用高级语言(例如c语言)在文本编辑器(例如vim)写好源程序,再利用编译器(例如gcc)进行编译,再链接到已存在的函数库,最终产生可以执行的可执行文件。如图:

          

下面对c语言代码编译来逐步了解如何利用gcc编译程序

1.单个程序

#include<stdio.h>
int main()
{
    printf("Hello World!");
    return 0;
}

看看编译过程:

可以指定可执行文件的名称。有两个参数重要的参数 -c——生成目标文件(.o文件)  -o——生成可执行文件。看下面执行过程

2.多个程序

//main.c文件
#include<stdio.h>
int main()
{
        int x, y;
        printf("Input the x:"); 
        scanf("%d", &x);        //输入x
        printf("Input the y:");
        scanf("%d", &y);        //输入y

        printf("%d\n", sum1(x, y));
        return 0;
}

//sum1.c文件
int  sum1(int a, int b)
{
        return a + b;
}

问题来了:既然可以直接生成可执行文件,那为嘛要生成那中间的目标文件(.o)?

原因是这样的:当源码文件有很多时,编译大量的源码文件需要大量的时间,但是如果生成目标文件的话,就可以在编译的时候编译改变的目标文件。

3.调用函数库

#include<stdio.h>
#include<math.h> int main() { int x, y; printf("Input the x:"); scanf("%d", &x); printf("%.3f\n", sqrt(x)); //调用函数库函数sqrt()函数开方 return 0; }

看到程序出现错误,说没有定义sqrt。此时头文件#include<math.h>是无济于事的。因为查看/usr/include/目录下的math.h没有对sqrt()的定义。C语言的数学函数大部分写在libm.so函数库中,此函数库主要放在/lib、/usr/bin.所以要在编译时的链接过程

声明:-L/lib、-L/usr/lib

4.makefile文件

现在问题又来了:为了以后修改不至于大幅度的编译源文件,生成了目标文件,但是有大量的目标文件,那不有大量的gcc -c .......很麻烦,为了比比按这种重复的工作,就要用的了makefile(Makefile)文件。还是利用2中的例子。编写makefile如下

main: main.o sum1.o
    gcc -o main main.o sum1.o
clean:
    rm main.o sum1.o main

编译过程:

编写makefile规则:

执行文件名: 1.o 2.o ...
<tab> gcc -o 执行文件名 1.o 2.o ...

注意:第二行开头一<tab>键开头,颜色是高亮的。

5.优化makefile文件

在书写makefile时可以看到有很多重复的内容,这样就可以把重复的内容用一个变量代替。例如上边的makefiel可以改写如下:

OBJS = main.o sum1.o
main: ${OBJS}
    gcc -o main ${OBJS}
clean:
    rm ${OBJS}

注意:

  • 变量常用大写表示
  • 此时变量赋值可以有空格(不像shell)
  • 下边调用变量的时候用格式${OBJS}
  • 数学函数不要在gcc 最后竹山 -lm

$@可以表示当前的可执行文件名称,那么上边的makefile改写如下:

OBJS = main.o sum1.o
main: ${OBJS}
    gcc -o $@ ${OBJS}
clean:
    rm ${OBJS}

 

 

posted @ 2013-03-27 08:55  jihite  阅读(798)  评论(2编辑  收藏  举报