Linux编程环境

2018-06-04  本文已影响0人  AmberXiao

本文内容:
1. 编译过程
2. GCC编译器
3. Makefile
4. 使用GDB调试程序


1. 编译过程

编译过程

2. GCC编译器

  1. 将源文件编译成可执行文件:
    $: gcc hello.c
    生成的可执行文件名默认为a.out
  2. 用 -o 参数指定输出文件名:
    $: gcc hello.c -o hello
    此时将会生成可执行文件hello
  3. 编译生成目标文件
    参数 -c 用于生成目标文件
    $: gcc -c hello.c
    将会生成目标文件 hello.o
  4. 也可以多文件编译:
    $: gcc -c hello.c test.c main.c
    将会生成目标文件 hello.o,test.o,main.o

3. Makefile

3.1 一个小例子

在sock/sock.h, sock/sock.cpp声明定义了类Sock,用于生成服务器端套接字,接受客户端连接;在process/process.h, process/process.cpp中声明定义了类Process, 用于创建新的进程;在main.c 中包含了以上两个头文件,并调用这两个类。
makefile的内容:

  main:main.o sock/sock.o process/process.o
    g++ -o main main.o sock/sock.o process/process.o
  sock.o:sock/sock.cpp sock/sock.h
    g++ -c -o sock/sock.o sock/sock.cpp
  process.o:process/process.cpp process/process.h
    g++ -c -o process.o process/process.cpp

  clean:
    rm -f main main.o process/process.o sock/sock.o

执行make:


执行make

执行结果:
在主目录下生成了main.o 和可执行文件main,在sock目录下生成sock.o,在process目录下生成了process.o。

3.2 Makefile规则

makefile的基本规则:

TARGET...:DEPENDEDS...
  COMMAND
  ...

以小例子中的第一条为例:
main是要生成的目标文件TARGET,
main.o sock/sock.o process/process.o是main的依赖文件DEPENDEDS,
g++ -o main main.o sock/sock.o process/process.o
是要执行的命令COMMAND。

  1. TARGET:可以是可执行文件或目标文件,也可以是一个命令,如clean;
  2. DEPENDS:执行命令需要的以来条件,若达不到以来条件则不会执行下面的命令,当依赖文件中有文件的时间戳比目标文件新时,就会执行COMMAND命令;
  3. COMMAND:命令,例如编译、生成库文件、进入目录等,每个命令占一行,每个命令必须以TAB键开始。

3.3 Makefile中的变量

1. 自动变量
常用的自动变量:

变量 含义
$* 表示目标文件名,不包含扩展名
$+ 表示所有的依赖文件,以空格分开,按顺序排列,包含重复文件
$< 表示依赖项中第一个依赖文件
$? 表示依赖项中所有比目标文件的时间戳晚的以来文件,以空格分开
$@ 目标文件名称
$^ 依赖项中所有不重复的依赖文件,以空格分开

2. 用户自定义变量
用户可以自定义变量,节省输入时间,而且便于修改,第一小节中的例子可以改为:

TARGET=main
OBJS=main.o sock/sock.o process/process.o
RM=rm -f

$(TARGET):$(OBJS)
  g++ -o $(TARGET) $(OBJS)
$(OBJS):%.o:%.c  #表示将OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件
  g++ -c $< -o $@
clean:
-$(RM) $(TARGET) $(OBJS)

执行过程:


image.png

3. 预定义变量
暂时不用,待补充

3.4 搜索路径

输入文件时,手动添加目录不仅麻烦而且容易出错,可以使用VPATH变量避免多次输入目录,则上节中的例子可以改为:

VPATH=sock:process
TARGET=main
OBJS=main.o sock.o process.o
RM=rm -f

$(TARGET):$(OBJS)
  g++ -o $(TARGET) $(OBJS)
$(OBJS):%.o:%.c  #表示将OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件
  g++ -c $< -o $@
clean:
-$(RM) $(TARGET) $(OBJS)

不同的目录之间用冒号:分隔,make会自动找到对应的文件并添加目录。
但以上方法编译出的目标文件都放在了当前主目录,因此可以用以下方法将目标文件放到一个目录:

VPATH=sock:process
OBJSDIR=objs
TARGET=main
OBJS=main.o sock.o process.o
RM=rm -f

$(TARGET):$(OBJSDIR) $(OBJS)
  g++ -o $(TARGET) $(OBJSDIR)/*.o
$(OBJS):%.o:%.c  #表示将OBJS中所有扩展名为.o的文件替换成扩展名为.c的文件
  g++ -c $< -o $(OBJSDIR)/$@
clean:
-$(RM) $(TARGET) 
-$(RM) $(OBJSDIR)/*.o

3.5 推导规则

使用make编译扩展名为.c的C语言文件时,将源文件编译成目标文件的命令不用给出,因为make编译时会使用默认的规则,只要在makefile里给出需要重建的目标文件名(.o文件),make就会自动为这个文件寻找对应的.c文件,并将其构建为目标文件。

3.6 递归make

暂时不用,待补充

3.7 Makefile中的函数

暂时不用,待补充

4. 使用GDB调试程序

待补充

参考文献

  1. 《Linux网络编程(第2版)》,宋敬彬等编著。
上一篇下一篇

猜你喜欢

热点阅读