源文件的编译
在Linux下,如果要编译C源程序,我们要使用GNU的gcc编译器,下面的一个例子是用来说明如何使用gcc编译器
如下,是我们的一个C语言的源程序main.c
#include <stdio.h>
int main(int argc,char ** argv){
printf("hello world");
}
如果想要编译这个文件,我们需要直接在终端中执行如下命令
gcc -o main main.c
gcc编译器会为我们生成一个main的可执行文件,执行./main
就可以看到输出的结果,内容比较简单,我就不贴图了。命令中gcc表示我们使用gcc来编译我们的源程序,-o
表示我们要求编译器给我们输出的可执行文件名为main,而main.c是我们的源程序文件
gcc编译器有很多选项,一般来说我们只要知道其中的几个,就可以了
-o
表示我们要求输出的可执行文件名-c
表示wo’men’zhi’yao求编辑器输出目标代码,不用输出可执行文件-g
表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息
Makefile的编写
假如我们有下面的应用程序
main.c文件
#include <stdio.h>
#include "mytool1.h"
#include "mytool2.h"
int main(int argc,char ** argv){
mytool1_print("hello");
mytool2_print("hello");
}
mytool1.h文件
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif
mytool1.c文件
#include <stido.h>
#include "mytool1.h"
void mytool1_print(char *print_str){
printf("this is mytool1 %s\n",print_str);
}
mytool2.h文件
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif
mytool2.c文件
#include <stdio.h>
#include "mytool2.h"
void mytool2_print(char *print_str){
printf("this is mytool2 %s\n",print_str);
}
这个程序相对而言比较简单,如果我们想要对这个项目进行编译的话,需要执行一下的命令
gcc -c main.c
gcc -c mytool1.c
gcc -c mytool2.c
gcc -o main main.o mytool1.o mytool2.o
通过这样的方式,我们可以产生main程序,但是会比较麻烦,特别是如果我们的代码量非常多的时候,这样一个个文件的编译会非常的繁琐。当然我们可以编写一个shell脚本,但是这样的方式肯定不是我们想要的。在Linux中为我们提供了Makefile,可以解决这样的问题
如下,我们的makefile文件可以是下面的
#写一个Makefile文件
main: main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o: main.c mytool1.h mytool2.h
gcc -c main.c
mytool1.o: mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o: mytool2.c mytool2.h
gcc -c mytool2.c
有了Makefile文件,我们只需执行make
命令,我们的编译器就回去编译我们的文件
关于Makefile文件的书写,不是这里的关键,我们就不去详细介绍了
简写方法
下面为大家提供几个简写的方式
$@
目标文件,我们需要生成的目标文件$^
所有的依赖文件,我们生成目标所需要的所有以来文件$<
第一个依赖文件
那么我们上面的Makefile文件就可以修改成如下的样式
#修改之后的样式
main: main.o tool1.o too;2.o
gcc -o $@ $^
main.o: main.c mytool1.h mytool2.h
gcc -c $<
tool1.o: mytool1.c mytool1.h
gcc -c $<
tool2.o: mytool2.c mytool2.h
gcc -c @<
除了这种简化之外,我们还有另外一种
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
.c.o:
gcc -c $<
几个变量赋值号的使用区别
= 最基本的赋值
:= 覆盖之前的值
?= 如果没有被复制过的就赋值,如果赋值过,就不要执行操作
+= 追加操作