【Linux&C++】Linux环境下C++编程

在阅读的过程中有任何问题,欢迎一起交流

邮箱:1494713801@qq.com  

QQ:1494713801

 

在linux下,开发工具被切割成一个个独立的小工具。各自处理不同的问题。例如:

编辑器(emacs, vim)用来进行编辑程序的
调试器(gdb)
用来调试程序
编译器(GCC)
用来编译和链接程序的
性能分析工具(gcov, gprof)
用来优化程序的
文档生成器(doxygen) 用来生成文档的

同时,还有一些系统工具和系统知识,我们是很有必要了解的:
makefile  程序自动化机制
shell  系统粘合剂
grep, locate, find  系统查找工具
其它的工具(例如ctags, OCI公司的MPC等等)

 

一、gcc编译器

以一个C++源文件为例:

//test.c:

#include <stdio.h>

int main(int args,char **argv)

{

  printf("hello world!");

  return 0;

}

======================================

1. 编译过程:.c -- 预处理(processing)->.i  -- 编译(compilation)->.s -- 汇编(assembly) - >.o -- Linking --

 

2. 预处理:

gcc -E test.c -o test.i  /  gcc -E test.c

预处理的结果就是将stdio.h文件中的内容插入到test.c中, -o表示输出汇编代码文件。

 

3.编译为汇编代码:

gcc -S test.i -o test.s

-S选项表示生成汇编代码

 

4. 汇编:

gcc -C test.s -o test.o

汇编器将汇编代码编译成目标文件

 

5. 链接:

gcc test.o -o test

 

二、

1.对多个文件进行编译:

gcc test1.c test2.c -o test

 

2.检错

gcc -pedantic illcode.c -o illcode

-pedantic 帮助程序员发现不符合ansi/iso标准代码。

-Wall 使gcc产生尽可能多的警告信号

-Werror会在警告的地方停止编译,迫使程序员对自己代码进行修改

 

三、库文件的链接:

       函数库是由一些头文件(.h)和库文件(.so, .lib, .dll)的集合。 LINUX默认将头文件放在/usr/include/, 库文件放在/usr/lib/; 如果我们要用的库不在这些目录下,所以在gcc编译的时候必须用自己的办法来查找所需要的头文件和库文件。

例: test.c链接mysql,我们要下载mysql的库——MySQL Connectors, 下下来以后由个include的文件夹, 里面包含头文件, 还有一个lib的文件夹,里面包含二进制so文件libmysqlclient.so,其中include的路径是/usr/dev/mysql/include, lib的文件夹是/usr/dev/mysql/lib

1. 编译成目标文件:

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

2. 链接:最后我们把所有的目标文件链接成可执行文件。

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

linux下动态链接库用so结尾,静态链接库由a结尾。

3.强制链接时使用静态链接库:

加-static

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

静态库搜索顺序

(1). ld 会去找gcc命令中参数-L

(2)再找gcc环境变量library_PATH

 (3)再找内定目录/lib, /usr/lib, /usr/local/lib

 

动态链接搜索顺序:

(1)编译目标代码时候指定的搜索路径

(2)环境变量LD_LIBRARY_PATH

(3)配置文件/etc/ld.so.con

(4)/lib, /usr/lib

 

二、GDB调试器

1. gcc -g main.c -o main

在用gcc时候,加上-g表示在生成的目标文件中加入源代码信息以便调试。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用
-g把调试信息加入之后,并成功编译目标代码以后,即可以使用gdb来调试他。

2. l, list 从第一行开始列出源代码

3. start, 开始执行程序,第一行break

4. n, next下一行

5. s, step进入函数

6. bt, backtrace查看函数栈

7. i locals, 用info命令查看局部变量

8. f 1, 到栈帧1

9. p sum, print出sum的值

10. finish, 运行到返回点——如果是从s进来的函数

11. set var sum=0, 调试过程中给变量sum赋值

12. p result[2]=33, 用p赋值

13. display sum, 每次程序停止的时候显示sum的值

14. b, break当前的循环

15. b 9, 在第9行设置断点

16. c, 连续运行continue

17. i breakpoints, 查看所有断点

18. delete breakpoint 2, 删除断点2

19. disable breakpoint 2 , 禁用断点2

20. enable breakpoint 2 , 启用

21. break 9 if sum!=0 , 当满足条件时候断点激活

22. r , 从头开始执行run

示例:

编译生成执行文件:(Linux下)
hchen/test> cc -g tst.c -o tst
使用GDB调试:
hchen/test> gdb tst <---------- 启动GDB
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-suse-linux"...
(gdb) l <-------------------- l命令相当于list,从第一行开始例出原码。
1 #include
2
3 int func(int n)
4 {
5 int sum=0,i;
6 for(i=0; i 7 {
8 sum+=i;
9 }
10 return sum;
(gdb) <-------------------- 直接回车表示,重复上一次命令
11 }

12
13
14 main()
15 {
16 int i;
17 long result = 0;
18 for(i=1; i<=100; i++)
19 {
20 result += i;
(gdb) break 16 <-------------------- 设置断点,在源程序第16行处。
Breakpoint 1 at 0x8048496: file tst.c, line 16.
(gdb) break func <-------------------- 设置断点,在函数func()入口处。
Breakpoint 2 at 0x8048456: file tst.c, line 5.
(gdb) info break <-------------------- 查看断点信息。
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048496 in main at tst.c:16
2 breakpoint keep y 0x08048456 in func at tst.c:5
(gdb) r <--------------------- 运行程序,run命令简写
Starting program: /home/hchen/test/tst
Breakpoint 1, main () at tst.c:17 <---------- 在断点处停住。
17 long result = 0;
(gdb) n <--------------------- 单条语句执行,next命令简写。
18 for(i=1; i<=100; i++)
(gdb) n
20 result += i;
(gdb) n
18 for(i=1; i<=100; i++)
(gdb) n
20 result += i;
(gdb) c <--------------------- 继续运行程序,continue命令简写。
Continuing.
result[1-100] = 5050 <----------程序输出。
Breakpoint 2, func (n=250) at tst.c:5
5 int sum=0,i;
(gdb) n
6 for(i=1; i<=n; i++)
(gdb) p i <--------------------- 打印变量i的值,print命令简写。
$1 = 134513808
(gdb) n
8 sum+=i;
(gdb) n
6 for(i=1; i<=n; i++)

(gdb) p sum
$2 = 1
(gdb) n
8 sum+=i;
(gdb) p i
$3 = 2
(gdb) n
6 for(i=1; i<=n; i++)
(gdb) p sum
$4 = 3
(gdb) bt <--------------------- 查看函数堆栈。
#0 func (n=250) at tst.c:5
#1 0x080484e4 in main () at tst.c:24
#2 0x400409ed in __libc_start_main () from /lib/libc.so.6
(gdb) finish <--------------------- 退出函数。
Run till exit from #0 func (n=250) at tst.c:5
0x080484e4 in main () at tst.c:24
24 printf("result[1-250] = %d /n", func(250) );
Value returned is $6 = 31375
(gdb) c <--------------------- 继续运行。
Continuing.
result[1-250] = 31375 <----------程序输出。
Program exited with code 027. <--------程序退出,调试结束。
(gdb) q <--------------------- 退出gdb。
hchen/test> 

 

三、Makefile基础:

1. Makefile 是由一组rule组成, 每条rule信息如下:

target ...: prerequistites ...

<tab>command1

<tab>command2

例:

main: main.o stack.o maze.o

  gcc main.o stack.o maze.o -o main

只要有一个prerequisities更新了,目标也会被更新,就是执行command

 

2. clean规则

用于清除编译产生的二进制文件,保留源文件:

clean:

  @echo "cleaning project"

  -rm main *.o

  @echo "clean completed"

如果命令前加@则不显示命令本身,只显示结果。 如果加-表示即使命令出错也不会停止。 通常rm或者mkdir前面要加-,因为可能没有这个文件,或者已经有了这个文件。

如果存在有文件名字就叫做clean,则会出错,那么就要添加一行,将clean关键字申明成伪目标

.PHONY:clean 

 

3. 4个规则关键字:

install:将可执行文件、配置文件、docs分别拷贝到不同安装目录

all:执行主要编译工作,通常用作缺省目标

clean:删除编译生成的二进制文件

distclean:不仅删除二进制文件,还删除其他的,只留下源文件。

 

4. 隐含规则和模式规则:

其中有一条

%.o: %.c

  $(compile.c) $(output_option) $<

$@为规则中的target, $<为规则中的第一个条件,上面那句相当于 cc -c $@ $<

进而相当于所有符合这样的依赖关系:

main.o:main.h statk.h maze.h

可以隐含

main.o: main.c

  cc -c o main.o main.c

 

5. 变量:

main.o: main.c

  $(CC) $(CFLAGS) $(CPPFLAGS) -c $<

CC = gcc

CFLAGS = -o -g

CPPFLAGS = -Iinclude

 

:=, 立即赋值

?=, 如果没有赋过值才进行赋值

+=, 追加赋值

$^, 表示将所有条件组成的列表

$?, 表示所有比目标新的条件组成的列表

 

6. 自动处理依赖关系:

例:

all: main

main: main.o stack.o maze.o

  gcc $^ -o $@

clean:

  -rm main *.o

.PHONY: clean

sources = main.c stack.c maze.c

include $(souces: .c = .d)

%.d: %.c

  set -e; rm -f $@;\

  $(CC) -MM $(CPPFLAGS) $< > $@.$$$$;\      # $$$$相当于两个$ , 表示进程

  ....略...

 


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一门linuxc++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值