GCC的简单指令

GCC  [OPTION]  [FILENAME]

GCC主要经过四个步骤,预处理、编译、汇编、链接的四个过程。

以一个hello.c为例,如果GCC -C hello.c  则会生成一个目标文件hello.o。

-O选项,则会对整个程序进行优化。这个是大O,还有O2。

GCC  hello.c  -o   hello  这个会生成一个hello的文件,通过执行./hello会得到程序的结果。

-I   dirname加入这个程序所依赖的头文件所在的目录位置去寻找  GCC -I /home/use   hello.c   -o hello  //hello所依赖的头文件在/home/usr目录下存在  这样就可以找到。这个是在gcc进行编译的时候发生的,包含头文件。

-L  dirname去指定库文件所在的路径。多一个可以寻找库文件的位置。跟-I意思一样,这个是在链接时候发生的。需要链接库文件。如线程库、数学库等。这个选项告诉链接程序,首先到-L指定的目录中去寻找,然后再到系统预设路径中寻找。

-l小L,默认的情况下会链接C库,在链接时,装载名字为"libname.a"的函数库,该函数库位于系统预设的目录或者由-L选项确定的目录下。例如-lm表示连接名为"libm.a"的数学函数库,一般会把前面的lib和.a后缀去掉。gcc  foo.c -L /home/lib -lfoo -o foo。

-static  静态链接,在运行时会包含在一起,多个程序会有多个拷贝。动态链接库则是在运行时进行调用,而不包含,多个程序共享一个拷贝。默认的时候是采用动态链接方式。

-wall   生成所有的警告信息。

-w   不生成警告信息。

-DMACRO  -D相当于define的作用,定义一个宏。


gcc   -g tst.c -o tst这个编译生成可执行文件

启动GDB   gdb  tst

在main函数处设置断点  break main



运行程序  run

单步执行   nexrt 

c连续运行  直到下一个断点或者结束。

退出  quit

list显示程序  一次10行

GNU的make能够使整个软件工程的编译、连接只需要一个命令就可以完成。linux内核大概1W个文件,使用make的作用就非常明显。make在执行时,需要一个命名为Makefile的文件。Makefile文件描述了整个工程的编译、连接等规则。其中包括:工程中的哪些源文件需要编译以及如何编译;需要创建哪些库文件以及如何创建这些苦文件,如何最后产生我们想要的可执行文件。


hello:main.o func1.o func2.o

        gcc main.o func1.o func2.o -o hello

main.o:main.c

    gcc -c main.c

func1.o:func1.c

   gcc -c func1.c

func2.o:func2.c

    gcc -c func2.c

.PHONY:clean

clean:

   rm -f hello main.o func1.o func2.o

Makefile的术语:

规则:用于说明如何生存一个或多个目标文件,规则格式如下

targets:prerequisites

   command

目标  依赖  命令(需要tab键开始)

func2.o:func2.c

    gcc -c func2.c

make命令默认在当前目录下寻找名字为makefile的工程文件。当名字部位makefile时,通过makefile -f  文件名进行指定。

.PHONY表示的是一个伪目标,没有任何依赖,只有命令没有依赖的目标。

在此我们可以使用SHELL编程指定变量:obj=main.o func1.o func2.o func3.o

hello:$(obj)

gcc  $(obj)  -o  hello

指定obj一个变量,编译的时候取得obj变量的值就行。方便使用。使用变量的好处就是如果依赖条件增加,只需要在obj后面进行添加,执行命令的指令不需要改变。

gcc   $^  -o $@   $^代表的是依赖目标  %@代表的是目标文件

加一个@符进行取消回显。

obect = *.o上面这个例子表示了,通符同样可以用在变量中。Objects的值就是"*.o"。makefile中的变量其实就是C/C++中的宏,如果你要让通配符在变量中展开,可以使用

object :=$(wildcard *.o)

在一些大的工程中,有大量的源文件,我们通常的做法是把着许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的以来关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。

makefile文件中的特殊变量"VPATH"就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。

VPATH=src:../headers

上面的定义指定两个目录,"src"和"../headers",make会按照这个顺序进行搜索,目录由"冒号"分隔,当然,当前目录永远是最高优先搜索的地方。


如果一个比较大型的工程,你必须清楚哪些C文件包含了哪些头文件,并且,你在加入或删除头文件时,也需要小心地修改makefile,这是一个很没有维护性的工作。为了避免这种繁重而又容易出错的事情,我们可以使用C/C++编译的一个功能,大多数的C/C++编译器都支持一个“-M”的选项,即自动找寻源文件中包含的头文件,并生成一个依赖关系。例如,如果我们执行下面的命令:

CC -M main.c

其输出是:main.o:main.c defs.h

于是由编译器自动生成的依赖关系,这样一来,你就不必再手动书写若干文件的依赖关系,而由编译器自动生成了。需要提醒一句的是,如果你使用GNU的编译器,你得用“-MM”参数,不然"-M"参数会把一些标准库的头文件也包含进来。

为了避免变量的无限递归,我们使用make中的另一种变量来定义变量的方法,这种方法使用的是“:=”操作符,如x:=foo

y:=$(x)bar

x:=later

其等价于:

y:=foo bar

x:=later

这种方法,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。

还有一种比较有用的操作符“?=”

FOO?=bar

其含义是,如果FOO没有被定义过,那么变量FOO的值就是"bar",如果FOO先前被定义过,那么这条语句将什么也不做。

系统变量“CFLAGS”可以控制编译时的编译器参数。

下面是所有隐含规则中会用到的变量:

1  关于命令的变量

AR   函数库打包程序,默认命令是“ar”

AS  汇编语言编译程序。默认命令是"as"

CC  C语言编译程序,默认命令是"cc"

CXX  C++语言编译程序,默认命令是"g++"

2 关于命令参数的变量:

下面的这些变量都是相关上面的命令的参数:

ARFLAGS  函数库打包程序AR命令的参数 。默认值时"rv"

ASFLAGS  汇编语言编译器参数

CFLAGS  C语言编译器参数

CXXFALGS  C++语言编译器参数

COFLAGS  RCS命令参数

定义模式规则:

模式规则介绍:模式规则中,至少在规则的目标定义中要包含"%",否则,就是一般的规则。目标中的"%"定义表示对文件名的匹配。"%"表示任意的非空字符串。

%.o:%.c:

其含义是之处了怎么从所有的.c文件中生成相应的.o文件的规则。

自动化变量:$@ 表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。

$%   仅当目标是函数库文件中,表示规则中的目标成员名。

$<   依赖目标中的第一个目标名字。如果依赖目标是以模式"即%"定义的,那么"$<"将是符合模式的一系列的文件集。注意,其实一个一个取出来的。

$?   所有比目标新的依赖目标的集合。以空格分隔。

$^   所有的依赖目标的集合,以空格分隔。如果在依赖目标中由多个重复的,那么这个变量会去除重复的依赖目标,只保留一份。

$+    这个变量很像“$^”。也就是所有依赖目标的集合。只是它不去除重复的依赖目标。

老式风格的"后缀规则"

后缀规则是一个比较老式的定义隐含规则的方法,后缀规则会被模式规则逐步取代。为了和老版本的makefile兼容,GNU make同样兼容于这些东西,后缀规则有两种方式:“双后缀“和"单后缀"。

双后缀:.c.o相当于"%o:%c"

你可能感兴趣的:(linux编程)