# 第七阶段：程序开发与源码阅读（选学）

## 程序开发基础

C Programming Language

Edit/Compile/Link/Run

gcc for C program compiling in Linux

gdb for debugging

gprof for performance tuning

make and makefile

程序的编译过程

![](7588519c7f12e96c163525f9b3409ce4a08a894a2f7e00d9e8483feb1b56118b.jpg)

编译，链接和运行

编译器

Gcc gnu compiler collection

Gnu 计划创建一个 unix-like 操作系统，免费软件。推动了在程序员之间的自由和合作"GNU C Compiler“  "GNU Compiler Collection"

support many languages such as C (gcc), ${ \mathsf { C } } ^ { + + } \left( { \mathsf { g } } ^ { + + } \right) ,$ , Objective-C, Objective- $C ^ { + + }$ , Java (gcj), Fortran (gfortran), Ada (gnat), Go (gccgo), OpenMP, Cilk Plus, and OpenAcc.

gcc 是一个开发应用和写操作系统的。也叫做 gnu toolchain

1、 编译器 gcc such as $\subset / \subset + +$ and Objective- $\cdot \mathsf { C } / \mathsf { C } + +$   
2、 Gnu make  
3、 Gnu binutils  
4、Gnu debugger   
5、Gnu autotools   
6、Gnu bison

Gcc是可移植的、交叉编译器，可以跨平台

也支持 windows（cygwin（unix emulator under windows） 、mingw（minimalistgnu forwindows）。、mingu-w64）

Windows/intel 包括 x86 32 位指令集 i868 ‘x86——64 64 位指令集

32 位编译器能运行在 32 位、64 位向后兼容

但是64位编译器、程序只能运行在64位上

Cygwin 需要依赖

Mingw 更加简单

gcc

gcc [options] [filenames]

- options 为编译选项

filenames为需要编译的文件名

gcc test.c # create “a.out” file

gcc –o test test.c # create “test” file

gcc test.c –o test

gdb

gcc –g –o test test.c

gdb test

Example:

gcc hello.c //生成可执行文件 a.out

gcc hello.c -o hello //生成可执行文件 hello

gcc -c hello.c -o hello.o //生成目标文件 hello.o

gcc hello1.c hello2.c -o hello //多文件编译

gcc -E hello.c -o hello.i //预处理后生成 hello.i

gcc -S hello.c -o hello.s //生成汇编代码 hello.s

gcc -c -I /usr/dev/mysql/include test.c -o test.o

gcc -L /usr/dev/mysql/lib -lmysqlclient test.o -o test

-o 生成可执行文件

-c 生成目标文件.o

-E 预处理后生成 hello.i

-S 生成汇编代码 hello.s

-I 头文件

-L 库的路径

## Make 与 Makefile

Make

一个程序包含多个源文件

全部重新编译需要花费时间，你只需要编译一些文件

![](07f7e876812d3d2040cc068589e6f5b764af4928a1f778c518f0de6415391b0e.jpg)

![](a3f02bc1bbab3e899095c75e781d8ad6c53769d1d6375a308dc8ab99d4af3d18.jpg)

makefile 的结构

objfile: files…

 文件依赖

(tab)[commands]

 执行命令

(tab)[commands]

### Makefile 示例

myprog : foo.o bar.0

gcc foo.o bar.o -o myprog

foo.o : foo.c foo.h bar.h

gcc -c foo.c -o foo.o

bar.o : bar.c bar.h

gcc -c bar.c -o bar.o

Myprog依赖于foo.o和bar.o

两个文件。

生成myprog文件使用的命令。

### Makefile 完整示例

calc: add.. sub.. mult.. div.o main.c

gcc -o calc main.c add.o sub.o mult.o div.o

add.o: defs.h add.c

gcc -c add.c

sub.o: defs.h sub.c

gcc -c sub.c

mult.o: mult.c

gcc -c mult.c

div.o: div.c

gcc -c div.c

增加 clean

clean:

rm calc add.o sub.o mult.o div.o

How to use ‘make’?

make

make –f myfile #"myfile" is makefile

make clean #delete all object file

Default rules

Simplify the makefile

C program  object file

```txt
calc: main.c add.o sub.o mult.o div.o gcc -o calc main.c add.o sub.o mult.o div.o   
add.o sub.o: defends.h   
clean: rm add.o sub.o mult.o div.o main.o 
```

#ifndef

#dendif

objfile：files

Tab command

Myprog

Clean 并非真正的依赖目标而是伪目标

编写完成后

Make

Make -f myfile

Make clean 所有目标文件清除

默认的规则

.c 文件->.o 文件

为了简化内容，宏变量

可以 macros

```txt
TAB][commands] Myprog依赖于foo.o和bar.o两个文件。   
myprog:foo.o bar.o gcc foo.o bar.o -o myprog 生成myprog文件使用的命令。   
foo.o:foo.c foo.h bar.h gcc-c foo.c -o foo.o   
bar.o:bar.c bar.h gcc-c bar.c -o bar.o
```

![](5c897ead6015a9ea32e36c645cec30039c0d68e53f25276691c381be70acbc89.jpg)

Cc c 编译器

Cflags 特殊的选项

$\$ 0$ 当前目标的名字 依赖项的第一个文件 依赖项的所有文件

![](da21cf6b9617a2ac6a35ad40827509244d8a0e0c05e7d500493476960e72be7b.jpg)

Example

${ \mathsf { C } } { \mathsf { C } } { \mathsf { = } } { \mathsf { g } } { \mathsf { + } } { \mathsf { + } }$

#LD=/usr/bin/ld

INCLUDES=-I /usr/include/mysql

-I /usr/include

LIBS ${ \bf \Pi } = { \bf \cdot }$ -L/lib –L /usr/lib/mysql

-lmysqlclient -lpthread

CPPFLAGS $\mathbf { \alpha } _ { \mathbf { - } } \mathbf { \alpha } _ { \mathbf { - } }$ -DLINUX -D_DEBUGE -O0

-w -g –I ./src

libsrcs=$(wildcard src/*.cpp)

libobjs $= \$ 5$ (libsrcs:.cpp=.o)

des_libsrcs=$(wildcard src/*.c)

des_libobjs ${ \ : = } \$ 9$ (des_libsrcs:.c=.o)

静态方式定义宏

```makefile
server.exe: $(libobjs)gnu-md5.o
server.o $(des_libobjs)
$(CC)-DDEBUGE -g -o $@ $^ -lptrhead
$(INCLUDE) $(LIBS) 
```

%.o:%.cpp $(CC)$ (CPPFLAGS) -g -c -o $@$ <

```txt
%.o:%.c
gcc -g -c -o $@ $< 
```

```typescript
server.o: server.c server.h 
```

$(CC) -c -w -g -DLINUX -o$ @ $<$ $(INCLUDES)$

```css
gnu-md5.o:gnu-md5.cgnu-md5.h 
```

```makefile
$(CC) -c -g -o $@ $<
```

```txt
lean: 
```

```txt
rm -f server.exe server.o gnu-md5.o $(libobjs) $(des_libobjs) 
```

### 远程拷贝到服务器

```txt
install: 
```

```txt
scp server.exe schkui@www.hostname.com:/var/bin_path/ 
```
