【Linux系统学习】2. Linux下C语言开发过程

文章目录

    • 1. 编译
      •  1.1 编译源代码
      •  1.2 编译源程序
      •  1.3 头文件
      •  1.4 库文件
          • 用户创建自己的库文件
    • 2. make命令和makefile文件
      •  2.1 依赖关系
      •  2.2 创建规则
      •  2.3 宏
      •  2.4 内置规则
      •  2.5 多目标
      •  2.6 Linux内核中的makefile文件
    • 3. 调试

1. 编译

 1.1 编译源代码

hello.c

#include
int main(int argc, char *argv[])
{
	printf("hello, world\n");
	return 0;
}

 1.2 编译源程序

$ sudo apt-get isntall build-essential  #若没有安装GCC,安装
$ gcc -o hello hello.c  #转换成可执行文件hello
$ ./hello  #运行

      不加-o,编译器将可执行文件命名为a.out。
      在执行hello文件时,在hello前添加./,是让Shell在当前目录下寻找需要运行的可执行文件;如果不添加./,Shell会在PATH环境变量设置的目录中寻找可执行文件,这些目录中通常不会包含当前目录,也就无法找到hello文件。

 1.3 头文件

      头文件提供对常量的定义和堆库函数调用的声明。对C语言来说,这些头文件几乎总在/usr/include目录及其子目录下
      依赖特定Linux版本的头文件通常在/usr/include/sys和/usr/include/linux中。
      其他编程系统也有各自的include文件,并将其存储在能被相应编译器自动搜索到的目录里。例如,X视窗系统的/usr/include/X11目录和GNU C++的/usr/include/g++目录。
      在调用C语言编译器时,可使用-I选项来包含保存在子目录或非标准位置中的include文件。例如:

$ gcc -I/usr/openwin/include fred.c

      只是编译器不仅在标准位置,也在/usr/openwin/include目录中查找程序fred.c中包含的头文件。

 1.4 库文件

      标准库文件一般存储在/lib和/usr/lib目录中。默认情况下,C语言链接程序只搜索标准C语言库。
      库名字以lib开头,其后指明是什么库(例如,c代表C语言库,m代表数学库)
      文件名最后以“.”开始,然后给出库文件的类型:.a代表传统静态函数库, .so代表共享函数库

$ ls /usr/lib  #查看函数库

【Linux系统学习】2. Linux下C语言开发过程_第1张图片

用户创建自己的库文件

      创建库文件前,将需要的目标文件编译好,再将这些目标文件合并成单独的库文件。例如,用于拥有foo1.c和foo2.c两个源文件,希望将其打包成一个库文件:

$ gcc -c fool.c
$ gcc -c foo2.c
$ sudo ar crv libfoo.a foo1.o foo2.o

      通过执行该命令后,库文件就创建好了。
这里写图片描述

2. make命令和makefile文件

      make是用于自动化编译源文件的工具,使用make工具时,用户需要提供一个文件,用来说明源文件之间的依赖关系和构建规则,这个文件称为makefile。make命令会读取makefile文件的内容,先确定要创建的目标文件,然后比较该目标所依赖的源文件的日期和时间,以决定应该采用哪条规则来构造目标。

 2.1 依赖关系

      比如:有3个头文件:a.h,b.h和c.h,3个源文件:main.c,2.che 3.c,具体情况
      / *main.c* /
      #include “a.h”
      …
      /       *2.c* /
      #include       “a.h”
      #include “b.h”
      …
      / *3.c* /
      #include “b.h”
      #include “c.h”
      …
      依赖关系定义最终应用程序中的每个文件与源文件之间的关系。上面将依赖关系定义为最终应用程序依赖于文件main.o、2.o和3.o。同样main.o依赖于mian.c和a.h,2.o依赖于2.c、a.h和b.h,3.o依赖于3.c、b.h和c.h。
      makefile文件的写法是:先写目标名称,后面跟冒号,接着是空格或制表符,最后是用空格或制表符隔开的文件列表。
      上面可以写成:

myapp:main.o 2.o 3.o
main.o:main.c a.h
2.o:2.c a.h b.h
3.o:3.c b.h c.h

      如果要一次制作多个文件,可以利用名义上的目标all。假设应用程序有二进制文件myapp和使用手册myapp.1组成,可以用下面这行语句进行定义:

all:myapp myapp.1

 2.2 创建规则

      除了指定文件之间的依赖关系,还需要知道如何创建文件。例如2.c修改后,2.o用什么命令创建。makefile有默认规则,用户也可以指定规则。上例中,创建一个makefile,命名为Makefile1:

myapp:main.o 2.o 3.o
	gcc -o myapp main.o 2.o 3.o
main.o:main.c a.h
	gcc -c main.c
2.o:2.c a.h b.h
	gcc -c 2.c
3.o:3.c b.h c.h
	gcc -c 3.c
$ make -f Makefile1

 2.3 宏

      makefile文件中,
      宏作用:常用于设置编译器选项,设置编译器名称(如gcc、cc或c89)
      定义宏:MACRONAME=value。可在makefile内部定义,也可在调用make命令时定义。例如:make CC=c89
      引用宏:$(MACRONAME)或${MACRONAME}。
      宏为空:令等号后面无内容
      下面是一个使用宏的makefile

#Makefile2
all:myapp
CC = gcc
INCLUDE = 
CFLAGS = -g -Wall -ansi
myapp:main.o 2.o 3.o
	$(CC) -o myapp main.o 2.o 3.o
main.o:main.c a.h
	$(CC) -I$(INCLUDE)$(CFLAGS) -c main.c
2.o:2.c a.h b.h
	$(CC) -I$(INCLUDE)$(CFLAGS) -c 2.c
3.o:3.c b.h c.h
	$(CC) -I$(INCLUDE)$(CFLAGS) -c 3.c

 2.4 内置规则

      make自带内置规则,例如对源文件foo1.c,在没有makefile时,make命令也知道如何编译main.c
【Linux系统学习】2. Linux下C语言开发过程_第2张图片
make命令知道如何调用编译器,默认使用的编译器为cc。可以通过宏改变编译器名称。
【Linux系统学习】2. Linux下C语言开发过程_第3张图片
      通过make -p命令打印make命令的内置规则。比较重要的是:

OUTPUT_OPTION = -o $@
COMPILE.c = $(CC) -$(CFLAGS)$(CPPFLAGS)$(TARGET_ARCH) -c
$.o:$.c
	$(COMPILE.c)$(OUTPUT_OPTION)$

      大多数时候,用户只需在makefile中指定依赖关系,并且gcc能够自动编著用户创建这些依赖关系,通过gcc -MM命令可以导出项目中的依赖关系清单

$ gcc -MM main.c 2.c 3.c
main.o:main.c a.h
2.o:2.c a.h b.h
3.o:3.c b.h c.h

 2.5 多目标

      可以添加clean目标用于删除不需要的临时文件,通过install目标用于将编译后的应用程序安装到指定目录下。

$ sudo make  #编译
$ sudo make install  //安装
$ sudo make clean  //清除

???

 2.6 Linux内核中的makefile文件

      Linux内核中makefile文件包括5部分:
makefile                             /*顶层makefile文件*/
.config                                /*内核配置文件*/
arch/$(ARCH)/makefile     /*机器体现makefile文件*/
scripts/makefile.*               /*所有内核makefile共用定义和规则*/
kbuild makefiles                /*其他makefile文件*/
      通过内核配置操作产生.config文件,顶层makefile文件读取该文件的配置,它负责产生两个主要程序:内核映像(vmlinux image)和模块。
      每个子目录有一个makfefile文件,其任务是根据上级目录makefile文件命令启动编译。这些makefile文件使用.config文件配置数据构建各种文件列表,并使用这些文件列表编译内嵌或模块目标文件。      scripts/makefile.*包含了所有的定义和规则,与makefile文件一起编译出内核程序。

3. 调试

      调试器:adb、sdb和dbx和GNU的gdb。
gdb

$ gdb foo1.c

你可能感兴趣的:(linux)