Linux环境下的C++编程基础

目录

一、工具准备

二、程序的编译及调试

1、程序的编译及常用命令

2、gdb调试

三、Makefile文件基础

1、Makefile介绍

2、Makefile编写

3、make的运行和退出


一、工具准备

gcc是GNU的C编译器(GNU C Compiler)

g++是GNU的C++编译器(GNU C++ Compiler)

gdb是Linux下常用的调试工具,主要功能如下

  • 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
  • 可让被调试的程序在你所指定的调置的断点处停住(断点可以是条件表达式)。
  • 当程序被停住时,可以检查此时你的程序中所发生的事。
  • 你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。

Makefile文件:Makefile是程序编译的规则,makefile记录着整个工程的编译规则(如源文件的编译顺序、依赖关系等),通过make工具进行编译。make根据makefile定义的规则将源代码编译成二进行文件。在跨平台(特别是类Unix系统中)的程序中,一般都会通过makefile来进行编译。

二、程序的编译及调试

1、程序的编译及常用命令

$ g++ main.cpp     #编译程序,在当前目录自动生成一个a.out的可执行文件

$ ./a.out     # 执行可执行文件,即运行程序

$ g++ main.cpp -o test        # 指定自己想要生成的可执行程序的别名 (test)

$ g++ -c main.cpp      # 将源代码编译成目标文件(main.o),不进行链接

$ g++ main.o -o test1($ g++ -o test1 main.o)     #g++接编译后的(*.o)文件进行链接,生成可执行程序 (test1)

$ ldd test1       #该命令可以看到可执行程序 (test1)所链接的库

$ g++ -o test1 main.cpp -L /usr/Lib -l /usr/include      #将依赖的函数库和库路径加入

  • -L 指定连接的动态库或者静态库路径 ;

  • -I(大写i) 指定头文件路径 ,即include文件(也就是包含的*.h头文件)所在的目录;

  • -l(小写L) 指定需要链接的库的名称

$ gcc -g main.c -o test      #使用gdp调试C/C++程序, 在编译时,必须要把调试信息加到可执行文件中

$ g++ -g main.cpp -o test

注: 编译过程包括预处理、编译,链接 ;linux系统上的编译生成.o文件,windows系统上的编译生成.obj文件 ;linux系统上生成没有后缀的可执行文件,windows系统中生成.exe文件 ; linux系统下的静态函数库的后缀是.a,动态库是.so ; windows系统下的静态函数库的后缀是.lib,动态库是.dll。

2、gdb调试

GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。可以用来调试C,C++程序。

gdp功能及其常用命令

命令形式 功能解释
gdb -g main.cpp -o test 编译代码时的命令,要把调试信息加到可执行文件中
gdb 进入gdb调试命令
help 显示帮助信息,例:help quit,显示quit命令的信息
q/quit 退出GDB调试
file test 加载被调试的可执行程序文件test;或者直接使用gdb ./test进行debug调试命令
l/list 列出文件的内容
b/break <line number> 在某一行设置普通断点,运行到该行即停止,例:b 7
b/break <line number> if condition 在某一行设置条件断点,运行到该行满足条件即停止,例:b 7 if index=2
b/break <function name> 在某一个函数调用处设置断点,运行到函数调用出即停止,例:b getSum
r/run 运行调试的程序(如果程序中没有设置断点,则程序会一直运行到结束或者出现异常结束,如果设置断点,则会在断点处停止)
d/delete <break number> 删除断点编号对应的断点,例:d 1
clear 清空所有的断点信息
start 开始调试
c/continue 继续执行程序直到下一个断点或者程序结束
n/next 逐行调试
s/step 遇到函数时进到函数内部调试
p/print <value> 显示变量的值,即查看变量数据,例:p index

gdb调试技巧总结下载 

三、Makefile文件基础

1、Makefile介绍

Makefile文件关系到了整个工程的编译规则,它定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

Makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释makefile中指令的命令工具, 在终端中输入make命令,会自动搜索当前路径下的makefile或者是Makefile文件 。

2、Makefile编写

(1)Makefile示例1及分析

edit:main.o test.o          #需要生成的目标:生成目标的依赖项
    g++ main.o test.o -o test       #以Tab键开始,具体要执行的命令
test.o:
    g++ -c test.cpp
main.o:
    g++ -c main.cpp

clean:
    rm main.o test.o
  • makefile书写规则包含两个部分,一个是依赖关系,一个是生成目标的方法。
  • 我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中(最好使用 “Makefile”这个文件名),然后在该目录下直接输入命令“make”就可以生成执行文件edit。
  • 如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下“make clean”就可以。
  • 在Makefile中使用“#”字符,表示注释。

通过示例1看make的工作过程:

  • 首先,输入make命令,make会在当前目录下找名字叫“Makefile”或“makefile”的文件;
  • 如果找到,它会找文件中的第一个目标文件,即“edit”文件,并把这个文件作为最终的目标文件;
  • 如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件;
  • 如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程);
  • 然后再用 .o 文件生成make的终极任务,也就是执行文件edit。

这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在寻找的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make 就会直接退出,并报错,而对于所定义的命令的错误或是编译不成功,make根本不理。make 只管文件的依赖性。

(2)Makefile示例2及分析

#################################################
# Example for call LTP libraries under UNIX     #
#################################################
cc=g++
ccflags=-O2
all: cws \
	pos

cws: cws.cpp
	${cc} ${ccflags} -o cws cws.cpp -I./ \
		-I../include/ \
		-I../thirdparty/boost/include \
		-L../lib/ -lsegmentor -lboost_regex

pos: pos.cpp
	${cc} ${ccflags} -o pos pos.cpp -I./ \
		-I../include/ \
		-L../lib/ -lpostagger

.PHONY: clean

clean:
    rm cws
    rm pos
  • 反斜杠(\)是换行符的意思。这样比较便于Makefile的阅读;
  • -I../include/表示依赖的头文件路径,-L../lib/表示依赖的库路径;
  • -O2:表示编译时使用二级优化
  • makefile中使用变量,比如:cc=g++,makefile中以“$(cc)”的方式来使用这个变量;变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等)。变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。
  • 清空目标文件的规则:为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。只要有“.PHONY : clean ”这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只需“make clean” 即可。

(3)Makefile编写规则

  • 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
  • 隐晦规则。由于make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
  • 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
  • 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。
  • 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。

注:在Makefile中的命令,必须要以[Tab]键开始。

(4)make工作时执行过程

  • 读入所有的Makefile;
  • 读入被include的其它Makefile;
  • 初始化文件中的变量;
  • 推导隐晦规则,并分析所有规则;
  • 为所有的目标文件创建依赖关系链;
  • 根据依赖关系,决定哪些目标要重新生成;
  • 执行生成命令。

(5)makefile文件中使用通配符

我们想定义一系列比较类似的文件,可以使用通配符。make支持三种通配符:“*”,“?”和“[...]”;通配符可以代替一系列的文件,如“*.cpp”表示所有后缀为cpp的文件。一个需要我们注意的是,如果我们的文件名中有通配符,如:“*”,那么可以用转义字符“\”,如“\*”来表示真实的“*”字符。

(6)Makefile中的-Wall -O2 -Os -g等选项介绍

  • -Wall:选项可以打印出编译时所有的错误或者警告信息。这个选项很容易被遗忘,编译的时候,没有错误或者警告提示,以为自己的程序很完美,其实,里面有可能隐藏着许多陷阱。变量没有初始化,类型不匹配,或者类型转换错误等警告提示需要重点注意,错误就隐藏在这些代码里面。没有使用的变量也需要注意,去掉无用的代码,让整个程序显得干净一点。下次写Makefile的时候,一定加-Wall编译选项。
  • -O0: 表示编译时没有优化。
  • -O1: 表示编译时使用默认优化。
  • -O2: 表示编译时使用二级优化。
  • -O3: 表示编译时使用最高级优化。
  • -Os:相当于-O2.5优化。

3、make的运行和退出

(1)make的运行

直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的。

(2)make的退出

make命令执行后有三个退出码:

  • 0 —— 表示成功执行。
  • 1 —— 如果make运行时出现任何错误,其返回1。
  • 2 —— 如果你使用了make的“-q”选项,并且make使得一些目标不需要更新,那么返回2。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章