编译之gcc

gcc

gcc的基本用法

  • c程序用gcc编译,c++程序用g++编译.
  1. 创建.c文件

    vim main.c

  2. 编译与链接

方法一:产生目标文件

写好.c文件之后,执行下边命令:

    gcc -c main.c

生成一个 main.o文件,然后执行如下命令(其中main是给输出文件命的名):

    gcc -o main main.o

则生成一个main,然后执行

     ./main

即可看到输出结果。

方法二:

编辑好c文件之后直接执行:

    gcc main

则生成一个a.out的文件,直接执行:

   ./a.out

即可看到main.c的输出结果。

下载源代码

下载源代码时用wget +[代码网址],得到一个*.tgz等格式的压缩文件,然后解压,解压命令:

tar -xvf *.tgz    

gcc编译主,子程序

假设我们有主程序thanks.c, 这个主程序去呼叫 thanks_2.c 这个子程序,编译方法如下:

gcc -c thanks.c thanks_2.c

生成thanks_2.o和 thanks_2.o两个目标文件。

接着执行:

gcc -o thanks thanks.o thanks_2.o

则生成thanks文件,直接执行如下档案:

./thanks

即可生成想要的结果。

gcc编译叫外部凼式库:加入连结的凼式库

对于包含了外部函式库的c文件,编译时需要加入额外凼式库连结的方式。

例:现有sin.c文件内容如下:


#include <stdio.h>
#include <math.h>
int main(void)
{
	float value;
	value = sin ( 3.14 / 2 );
	printf("%f\n",value);
}  

可以看到里边包含了math.h头文件,编译方法如下:

  gcc sin.c -lm -L/lib -L/usr/lib <

其中,lm表示使用 libm.so (戒 libm.a) 这个凼式库的意怃~至亍那个 -L 后面接的路径呢?这表示:『我要的凼式库 libm.so 请到 /lib 戒 /usr/lib 里面搜寻!』

生成a.out,执行。

 ./a.out  
例子

现有main.c,haha.c,sin_value.c,cos_value.c四个文件需编译连接,如下:

gcc -c main.c

gcc -c haha.c  

gcc -c sin_value.c

gcc -c cos_value.c  

然后执行:

gcc -o main main.o haha.o sin_value.o cos_value.o -lm -L/usr/lib -L/lib  

生成main,再执行:

 ./main

即可。

这里,加入了函式库的连接方式才行。

makefile

从上边例子可以看出,当有多个c文件需要编译时,编译的过程需要进行好多动作!而且如果要重新编译,则上述的流程得要重新来一遍,光是找出这些 指令就够烦人的了! 如果可以的话,能不能一个步骤就给他完成上面所有的劢作呢?那就利用makefile 和 make 这个工具吧!

makefile书写规则

假设我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是:

  1. 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
  2. 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
  3. 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
书写规则如下:
 标的(target): 目标文件 1 目标文件 2
 	<tab>   gcc -o 欲建立的执行文件 目标文件 1 目标文件 2

一. 先编辑makefile

先编辑 makefile 这个规则文件,内容只要作出 main 这个执行档

还用上边那个例子,我们先建makefile文件:

vim makefile  

文件类型:由哪个文件得到

例如,makefile里边的内容为:

main: main.o haha.o sin_value.o cos_value.o  
		  gcc -o main main.o haha.o sin_value.o cos_value.o -lm
		  

得到过程如下:

main: main.o haha.o sin_value.o cos_value.o //可执行文件main是由目标文件main.o haha.o sin_value.o cos_value.o得到。

gcc -o main main.o haha.o sin_value.o cos_value.o -lm //得到过程是将main.o haha.o sin_value.o cos_value.o -lm编译成main文件。

其中,第二行的 gcc 前的空格是 按键产生的空格!

然后进行编译,可先将生成的.文件删除:

rm -f main *.o  

执行如下命令编译:

make  

在不删除任何档案的情况下,重新执行一次编译的动作:

make  

则显示:

make: `main' is up to date.

说明make之进行更新的动作,只有发生改动的才可以make。

  • 在make的时候,新的目标文件会覆盖旧的目标文件,则我们需make clean 一下,来删除旧的目标文件。

  • 如果我想要有两个以上的执行动作时, 例如下达一 个指令就直接清除掉所有的目标文件不执行文件,该如何制作呢?

还拿上例子来说,则makefile改成

main: main.o haha.o sin_value.o cos_value.o

       gcc -o main main.o haha.o sin_value.o cos_value.o -lm  
       
clean:  

       rm -f main main.o haha.o sin_value.o cos_value.o  

则执行

make main

或者

make clean

或者

make clean main

则会删除相应的旧的目标文件。

错误及解决

如果出现如下错误信息,

makefile:2: *** missing separator. Stop.

对应的解决方法:

makefile文件里的第二行的空格要按tab建产生,不能用空格键产生。

posted @ 2018-04-30 17:22  moonok  阅读(488)  评论(0)    收藏  举报