Linux C/C++开发
首先就是要熟练在vim里面写代码,其实就是没有提示和自动补全了,这个问题并不大。
我服务器gcc版本是4.8.5,所以就按照这个来了 https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/
其实我的开发者环境是最新的9.1.0,非常不建议哦。生产环境和开发环境尽量相同,不同的话一定要进行大量的测试
然后就是编译,先cd到工程文件夹,然后使用编译命令编译
一、编译
编译:当前源代码编译成二进制目标文件(.obj文件)
链接(link):将生成的.obj文件与库文件.lib等文件链接,生成可执行文件
一个现代编译器的主要工作流程如下:
源程序(source code)→预处理器(preprocessor)→编译器(compiler)→汇编程序(assembler)→目标程序(object code)→连接器(链接器,Linker)→可执行程序(executables)
执行过程 虽然我们称gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶
1.预处理(也称预编译,Preprocessing):命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。
2.编译(Compilation):接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。
3.汇编(Assembly):汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。
4.链接(Linking):当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到 的库函数也从各自所在的档案库中连到合适的地方。
实例:
1.编写hello.c文件
2.预编译过程:
gcc -E ./hello.c -o hello.i //.i 为后缀的文件,是已经预处理过的C源代码文件,可以省略这一步。
cat hellp.c | wc -l //查看hello.c文件内容的行数。
cat hellp.i | wc -l //查看hello.i文件内容的行数。
3.汇编过程:
gcc -S hello.i -o hello.s //.s为后缀的文件,是汇编语言源代码文件;可以省略这一步。
4.编译过程
gcc -c ./hello.c //在当前文件夹下生成hello.o .o为后缀的文件,是编译后的目标文件;
gcc -c hello.c -o hello.o //在当前文件夹下生成hello.o
5.链接过程:
gcc hello.o -o hello
6.直接在终端输入文件路径或者把hello文件拖动到终端即可执行
用g++编译c++源程序
用g++编译c++源程序和c语言类似,可将gcc改为g++逐个尝试。以下只提供一些简单介绍:
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o Place the output into
-g Use of extra debugging information
-w 关闭编译时的警告
-o 参数谨慎使用,也许开了编译优化会出现问题,但是开了编译优化代码真的会变快,做好测试就行
二、gdb调试
assert断言函数 如果参数expression等于零,一个错误消息将会写入到设备的标准错误集并且会调用abort函数,就会结束程序的执行。这个虽然可以找到错误,但是我们有更厉害的东西
gdb的其实是一个可执行文件,所以我们需要先编译出这个文件
#include <stdio.h>
int main()
{
int a = ;
printf("%d\n", a++);
printf("%d\n", a--);
printf("%d\n", ++a);
printf("%d\n", --a);
}
A.c
gcc -g A.c -o A
命令中出现了-g参数,这个不仅可以创建符号表,符号表包含了程序中使用的变量名称的列表,而且可以关闭所有的优化机制,以便程序执行过程中严格按照原来的C代码进行。
一定要记得加入这个参数
输入gdb就可以有了,当然你可能不想看到那一坨,可以加-q参数得到一个清爽的界面
gdb后可以file 跟上文件名,也可以进入之后再指定
[root@BobHuang ~]# gdb -q A
Reading symbols from /root/A...done.
(gdb) file A
想回过头看看以前的代码,就用list,一次可以显示十行,继续list可以显示接下来的十行
(gdb) list
1 #include<stdio.h>
2 int main()
3 {
4 int a=0;
5 printf("%d\n",a++);
6 printf("%d\n",a--);
7 printf("%d\n",++a);
8 printf("%d\n",--a);
9 }
10
list默认参数可以用show listsize来查看,如果感觉10行太多或者太少,还可以用set listsize <count>来更改。
但是我有时候只是想部分,就可以给list加上参数
list 还可以加上其他参数,比如:
list 5,10 显示第5行到第10行的代码;
list func 显示func函数周围的代码,显示范围和list参数有关;
list test.c:5,10 显示源文件test.c第5行到第10行的代码,一般用于调试含多个源文件的程序。
gdb 还支持字符串查找,search str,从当前行开始,向前查找含str的字符串;
reverse-search str,从当前行开始,向后查找含str的字符串。
在gdb里也可以使用shell+命令,比如
shell clear
就会完成清屏
然后就可以设置断点了,和在图形界面类似,可以设置在某一行断点。甚至可以直接写一个判断表达式
(gdb) break 5
Breakpoint 1 at 0x40052c: file A.c, line 5.
(gdb) break 6 if a==1
Breakpoint 2 at 0x400546: file A.c, line 6.
(gdb) break 7 if a==1
Breakpoint 3 at 0x400560: file A.c, line 7.
然后可以通过info breakpoints来查看断点
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040052c in main at A.c:5
2 breakpoint keep y 0x0000000000400546 in main at A.c:6
stop only if a==1
3 breakpoint keep y 0x0000000000400560 in main at A.c:7
stop only if a==1
Num表示断点的编号;Type表示断点的断点的类型,第二个断点类型还加上了条件;Disp表示中断点在执行一次之后是否失去作用,dis为是,keep为不是;Enb表示当前中断点是否有效,y为是,n为否;Address表示中断点所处的内存地址;What指出断点所处的位置。
(gdb) run
Starting program: /root/A
Breakpoint 1, main () at A.c:5
5 printf("%d\n",a++);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-260.el7_6.5.x86_64
(gdb) continue
Continuing.
0
Breakpoint 2, main () at A.c:6
6 printf("%d\n",a--);
(gdb) continue
Continuing.
1
1
0
[Inferior 1 (process 32035) exited with code 02]
但是他提示我软件没装啊,我们装一下
(gdb) shell debuginfo-install glibc-2.17-260.el7_6.5.x86_64
再次运行,没有变化,也就是没有经过breakpoint3,也就证明了,执行断点3时a!=1,所以这个判断非常好用啊,能检测出某些异常,不过bug复现是不太好实现
接下来就是删除断点了。如果不需要程序在该断点暂停时,有两种方法,一种是使该断点失效,一种是直接删除该断点。使断点失效用的是Num,删除断点用的是行,这样就巧妙完成了需求
(gdb) disable 2
(gdb) info breakpoints
Num Type Disp Enb Address What
2 breakpoint keep n 0x000000000040052c in main at A.c:5
(gdb) clear 5
Deleted breakpoint 1
delete命令后面的参数也为Num;可以一次删除多个断点,断点编号之间用空格隔开;如果delete后没有参数,默认删除所有断点,会给出提示选择是否操作。
上面虽然展示了一下,但是我们需要更多的演示,才展示他的强大
run,开始运行程序;
continue,程序暂停时继续运行程序的命令;
print 变量名或表达式,打印该变量或者该表达式的值。whatis 变量名或者表达式,可以显示该变量或表达式的数据类型。
print 变量=值,这种形式还可以给对应的变量赋值;类似的还有set variable 变量=值。作用和用print赋值相同。
next,继续执行下一条语句;
还有一条命令step,与之类似,不同的是,当下一条语句遇到函数调用的时候,next不会跟踪进入函数,而是继续执行下面的语句,而step命令则会跟踪进入函数内部。
(gdb) run
Starting program: /root/A Breakpoint , main () at A.c:
printf("%d\n",a++);
(gdb) next //继续执行下一条语句,只执行一条 printf("%d\n",a--);
(gdb) continue //让程序继续运行,直到下个断点或者结束
Continuing. [Inferior (process ) exited with code ]
直接赋值的结果
(gdb) run
Starting program: /root/A Breakpoint , main () at A.c:
printf("%d\n",a++);
(gdb) print a=
$ =
(gdb) continue
Continuing. [Inferior (process ) exited with code ]
还有nexti和stepi命令,这两个是单步执行一条机器指令,比如(i=0;i<n;i++)这条语句需要输入多个nexti才能执行完;两个的区别和上面相同。
quit,退出gdb调试,如果调试中想要退出,可以直接输入该命令,会出现提示选择是否退出。kill命令,结束当前程序的调试,(不会退出gdb)。
三、makefile编写
makefile带来直接好处就是——“自动化编译”。一旦写好,只需要一个make命令,整个工程完全自动编译,所以十分方便。而Makefile文件就是告诉make命令怎么样地去编译和链接程序。但是想要比较灵活的运用它,还是先要熟悉一些关于系统对程序编译和链接的知识。
Linux C/C++开发的更多相关文章
- Linux下c开发 之 线程通信(转)
Linux下c开发 之 线程通信(转) 1.Linux“线程” 进程与线程之间是有区别的,不过Linux内核只提供了轻量进程的支持,未实现线程模型.Linux是一种“多进程单线程”的操作系统.Linu ...
- 只有文本编辑器才是王道, 什么ide都是evil的浮云, 看看linus linux的内核开发工具vim emacs
只有文本编辑器才是王道, 什么ide都是evil的浮云, 看看linus linux的内核开发工具vim emacs [ide is evil] (http://i.cnblogs.com/EditP ...
- 热烈庆祝华清远见2014嵌入式系统(Linux&Android)开发就业培训课程全面升级
近日,华清远见公开宣布:2014嵌入式系统 (Linux&Android)开发就业培训课程再次升级!据悉,华清远见如今已经持续10年,一直保持课程每年2次的更新的频率.华清远见的每 次课程更新 ...
- linux应用程序开发-文件编程-系统调用方式
在看韦东山视频linux驱动方面有一些吃力,究其原因,虽然接触过linux应用程序编程,但是没有深入去理解,相关函数用法不清楚,正好看到国嵌视频对这一方面讲的比较透彻, 所以把学习过程记录下来,也作为 ...
- 嵌入式Linux应用程序开发详解------(创建守护进程)
嵌入式Linux应用程序开发详解 华清远见 本文只是阅读文摘. 创建一个守护进程的步骤: 1.创建一个子进程,然后退出父进程: 2.在子进程中使用创建新会话---setsid(): 3.改变当前工作目 ...
- 将linux用在开发环境中
我是如何将linux用在开发环境中的 1.为什么不直接安装Linux在主机 一直想深入学习一下linux的使用,于是将家里的笔记本装了linux系统,但是要将自己的系统打造一个适合开发的环境确实是一件 ...
- 【转载】Visual Studio 2015 for Linux更好地支持Linux下的开发
原文:Visual Studio 2015 for Linux更好地支持Linux下的开发 英文原文:Targeting Linux Made Easier in Visual Studio 2015 ...
- Linux设备驱动开发环境的搭建(转)
经过两周的摸索,终于对Linux设备驱动开发有了个初步的认识,下面对Linux设备驱动开发环境的搭建做个小结,以方便自己以后查询,同时也能给同道的初学者一点帮助. 刚接触Linux设备驱动时,初学者往 ...
- Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建
1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...
- 在桌面Linux环境下开发图形界面程序的方案对比
在Linux下开发GUI程序的方法有很多,比如Gnome桌面使用GTK+作为默认的图形界面库,KDE桌面使用Qt作为默认的图形界面库,wxWidgets则是另一个使用广泛的图形库,此外使用Java中的 ...
随机推荐
- XStream JavaBean对象转换成XML!
代码实例: 1.javaBean类: package com.hsinfo.web.Demo.XStream; public class City { private String name; pub ...
- Odoo使用jsonrpc协议
在controller添加一个test方法, 不需参数 @http.route('/test', type = 'json', auth = 'public') def test(self): pha ...
- 阿里云 Aliplayer高级功能介绍(八):安全播放
基本介绍 如何保障视频内容的安全,不被盗链.非法下载和传播,阿里云视频点播已经有一套完善的机制保障视频的安全播放: 更多详细内容查看点播内容安全播放,H5的Aliplayer对于上面的安全机制都是支持 ...
- KeyOnlyFilter(2)
主要用来过滤剩下行键计数一类 KeyOnlyFilter 官方API解释如下: A filter that will only return the key component of each KV ...
- Latex报错: Could not start the command: xelatex.exe -synctex=1 -interaction=nonstopmode?
Latex报错: Could not start the command: xelatex.exe -synctex=1 -interaction=nonstopmode 网上还有很多说出Could ...
- Luogu P2831 愤怒的小鸟(状压+记忆化搜索)
P2831 愤怒的小鸟 题意 题目描述 Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于\((0,0)\)处,每次Kiana可以用它向第一象限发射 ...
- 生成中国地区随机IP
#随机生成IP 中国区 public function randip($member){ if($member['user_ip']){ if($member ...
- MongoDB命令的简单操作(一)
MongoDB是工作在集合和文档上的一种概念. 1.创建数据库 use name2.查看所以的数据库列表 show dbs3.查看当前数据库 db4.向数据库插入数据 db.items.insert( ...
- PHP实现微信小程序支付完整版,可以借鉴!
本文实例为大家分享了php实现小程序支付的具体代码,供大家参考,具体内容如下 环境: tp3.2.3 + 小程序 微信支付功能开通 Step1: 下载PHP 支付SDK(下载地址) 放到Libr ...
- fixed和absolute的区别
今天在实际项目中,写首页一屏的时候,发现页脚定位(position:absolute:)没有达到我想要的效果(不管屏幕大小,页脚始终相对浏览器底部定位).于是我觉得有点奇怪,然而我旁边的小哥说:很明显 ...