Linux_CPP

Linux开发环境搭建

gcc、g++的安装

gcc和g++是GUN的C&C++编译器,这两个本质上区别不大,gcc默认下使用C编译器,g++默认使用C++编译器。

1
2
3
yum install gcc

yum install gcc-c++

编译流程

  • 源文件生存可执行程序:
1
2
3
4
5
6
7
8
>$ g++ helloworld.cpp -o helloworld


// 如果用gcc编译器,不会包含标准库信息,需要在命令行中包含
>$ gcc -lstdc++ helloworld.cpp -o helloworld

//-wall可以看到警告信息
>$ g++ -Wall helloworld.cpp -o helloworld

GCC命令的编译选项:

参数 解释
-ansi 只支持ANSI标准的C语法。这一选项将进制GNU C的某些特色,例如asm或者typeof关键字
-S 只激活预处理和编译,就是指把文件编译成为汇编代码
-c 只编译并生成目标文件
-g 生成调试信息。GNU调试器可利用该信息
-o FILENAME 生成指定的输出文件。用在生成可执行文件时
-O0 不进行优化处理
-O或-O1 优化生成代码
-O2或-O3 进一步优化
-shared 生成共享目标文件。通常用在建立共享库时
-static 禁止使用共享连接
-w 不生成任何警告信息
-Wall 生成所有警告信息
-IDIRECTORY 指定额外的头文件搜索路径DIRECTORY
-LDIRECTORY 指定额外的函数库搜索路径DIRECTORY
-ILIBRARY 链接时搜索指定的函数库LIBRARY
-m486 针对486进行代码优化
-E 只运行C预编译器

make和Makefile

  make是一个批处理工具,本身其实没什么功能。make工具就根据Makefile中的命令进行编译和链接。其实Windows系统中也有这些步骤,只不过微软已经把这些嵌入到了编译器中,不需要程序员去关心。Linux系统也有一些IDE可以帮助我们完成这些工作,比如CMake。

makefile的作用

工程中可执行文件的产生过程如下:

  1. 配置环境(系统环境)
  2. 确定标准库和头文件的位置
  3. 确定依赖关系(源代码之间编译的依赖关系)
  4. 头文件预编译
  5. 预处理
  6. 编译
  7. 链接
  8. 安装
  9. 和操作系统建立联系
  10. 生成安装包

  大型工程中需要确定代码之间的依赖关系(第三步),当依赖关系复杂的时候,make命令工具诞生了,而Makefile文件正是为make工具所使用的。Makefile描述了整个工程文件的编译顺序、编译规则。

make流程

  假设我们有一个简单的demo,reply.h、reply.cpp两个文件定义了一个类,输出“helloworld”,main.cpp是主函数文件,生成类对象。这三个文件有依赖关系。我们编译的步骤如下:

  1. 写Makefile文件
1
2
3
4
5
6
main: reply.o main.o    //左侧main是目标,依赖右侧的两个文件
g++ reply.o main.o -o main //使用g++命令,用reply.o、main.o生成main
reply.o: reply.cpp //reply.o,依赖reply.cpp
g++ -c reply.cpp -o reply.o //用g++命令生成reply.o,只编译
main.o: main.cpp //main.o,依赖main.cpp
g++ -c main.cpp -o main.o //用g++命令生成main.o,只编译

  可以看到,先表明最终生成文件的依赖关系,然后生成。其次挨个写被依赖文件自身的依赖关系。从上往下是倒置的依赖关系。

  1. 用make命令

$ make

  类似于批处理,make命令会去调用makefile文件,完成Makefile文件中的各项命令。

makefile文件格式

  • makefile的基本规则:
1
2
目标(target)...: 依赖(prerequisites)
命令(command)

注意:每个命令前必须是Tab字符。

  • makefile的简化规则:

    1. 变量定义: 变量 = 字符串
    2. 变量使用: $(变量名)
1
2
3
4
5
6
7
8
9
10
11
//上面的makefile文件可以做如下简化:

TARGET = main
OBJS = reply.o main.o
$(TARGET): $(OBJS)
g++ $(OBJS) -o $(TARGET)
reply.o: reply.cpp
main.o: main.cpp

clean:
rm $(TARGET) $(OBJS) //生成完成后

  • 清空操作
1
2
3
4
5
6
7
8
9
//在makefile文件中可以加上清理操作:

TARGET = main
OBJS = reply.o main.o

.PHONY: clean //.PHONY关键字,表示clean不存在,否则目录下存在"clean"同名文件的话,clean会失败

clean:
rm $(TARGET) $(OBJS)

执行$ make clean命令后,可以根据makefile中定义的删除操作把文件删掉。

makefile的扩展用法

  1. make工程的安装和卸载
1
2
3
4
5
6
7
8
9
10
TARGET = main
OBJS = reply.o main.o

//安装可以简化为拷贝操作
//把main拷贝到/user/local/bin/mainTest
install:
cp ./main /user/local/bin/mainTest

uninstall:
rm /user/local/bin/mainTest

  1. Makefile中的变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
一、用户自定义变量
变量 = 字符串,使用的时候就用$()括起来。就类似于C++中的宏定义。注意变量的大小写敏感。



二、变量中的变量
变量可以先使用再声明:
foo = $(bar) //还没声明bar,但可以先直接用
bar = $(ugh)
ugh = Hug

这样可以使变量定义更加灵活,但如果工程过于复杂不建议用,因为这样定义需要make来推导
定义的层级过多,会导致编译速度很慢。

如果希望只能使用声明过的变量,那么可以使用":="来替换"="
":="如果使用了还没有声明的变量,会失效



三、追加变量
可以使用"+="来追加变量



四、多行变量
define two-lines
第一行命令
第二行命令
endif



五、环境变量
就是操作系统的环境变量,Windows和Linux下都有


六、自动变量



七、模式变量



八、自动匹配