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

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

邮箱:[email protected]  

QQ:1494713801

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

编辑器(emacs, vim)用来进行编辑程序的

调试器(gdb) 用来调试程序

编译器(GCC) 用来编译和链接程序的

性能分析工具(gcov, gprof) 用来优化程序的

文档生成器(doxygen)
用来生成文档的

同时,还有一些系统工具和系统知识,我们是很有必要了解的:

makefile  程序自动化机制

shell  系统粘合剂

grep, locate, find 
系统查找工具

其它的工具(例如ctags, OCI公司的MPC等等)

以一个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) $<

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

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

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 [email protected]

clean:

  -rm main *.o

.PHONY: clean

sources = main.c stack.c maze.c

include $(souces: .c = .d)

%.d: %.c

  set -e; rm -f [email protected];\

  $(CC) -MM $(CPPFLAGS) $< > [email protected]$$$$;\      # $$$$相当于两个$ , 表示进程

  ....略...

时间: 2024-10-05 07:24:00

【Linux&C++】Linux环境下C++编程的相关文章

如何一步一步删除(linux &amp; UNIX)环境下 oracle 11g 集群节点

 Deleting a Cluster Node on Linux and UNIX Systems 1.确定要删除的节点,是否active,pinned $ olsnodes -s -t 如果 pinned ,则crsctl unpin css  -n <nodename>  unpinned 相应的节点 2.禁用相应集群节点的应用资源,进程 先停掉 em: emctl stop dbconsole 以root 用户运行 在要删除节点的 $Grid_home/crs/install 路径

Linux 14.04lts 环境下搭建交叉编译环境arm-linux-gcc-4.5.1

交叉编译工具链是为了编译.链接.处理和调试跨平台体系结构的程序代码,在该环境下编译出嵌入式Linux系统所需要的操作系统.应用程序等,然后再上传到目标板上. 首 先要明确gcc 和arm-linux-gcc的区别,gcc是x86架构的C语言编译器,编译出来的程序在本地执行,而arm-linux-gcc是跨平台的C语言编译 器,编译出来的程序在目标班上执行,嵌入式开发应该使用交叉编译工具链,下面给出详细的 Linux 14.04lts 环境下搭建交叉编译环境arm-linux-gcc-4.5.1安

Linux和Ubuntu环境下B2G(Firefox OS)安装、编译、测试教程集合

1在ubuntu上测试Firefox OS(B2G)系统 Firefox OS,项目代号为"Boot 2 Gecko",是一个开放的完全基于WEB标准的智能手机操作系统,由Mozilla公司开发.Firefox OS 底层属于Linux,开放的Web技术,而不是特定于平台的原生API,用HTML5 编写应用程序.Firefox OS 每日构建版目前可在电脑桌面上试用. 安装过程非常简单,下面是详细的步骤说明: 点 这里 下载 ... 2在 ubuntu系统上建立b2g系统(翻译) 你已

OpenStack 环境下 SHELL 编程练习(持续更新中)

须知: 1.本次 Shell 主要是针对于 OpneStack 环境下的编程练习 2.欢迎大家留言讨论 3.持续更新 练习1:将文件内容打印输出到屏幕上,并在每一行前面加上字符串"nova delete ",示例如下: 文件内容为: aaaa bbbb cccc 屏幕上输出为: nova delete aaaa nova delete bbbb nova delete cccc #!/bin/bash #文件功能:文件内容打印输出到屏幕上,并在每一行前面加上字符串"nova

在linux与windows环境下配置JDK

一.准备     下载新版JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html 所有版本请戳:http://www.oracle.com/technetwork/java/archive-139210.html 二.安装与配置     先说说在linux环境下.为了方便,以下操作均以root用户执行 jdk有3种形式的包,分别是rpm,rpm.bin,tar.gz,下面分别说     1. 这里我下载jdk-

一、VS2015update2环境下DirectX11编程说明(2016.5.5更新)

本文索引: 一 关于龙书 二 在vs2015u2环境下编写DirectX11程序 三 关于MSDN帮助文档 四 官方示例项目 五 自己尝试编写一个小项目 1 创建一个win32项目 2 配置依赖库 3 添加源文件 4 完成 六 总结 一. 关于龙书 相信很多看想要学习DirectX编程的小伙伴都有听说过龙书,也就是官方推出的<Introduction to 3D Game Programming with Directx 9>这本书,从DirectX9开始,龙书作为最权威.详尽的DirectX

Linux环境下网络编程杂谈&lt;&lt;转&gt;&gt;

今天我们说说“Pre-网络编程”.内容比较杂,但都是在做网络应用程序开发过程中经常要遇到的问题. 一.大端.小端和网络字节序 小端字节序:little-endian,将低字节存放在内存的起始地址: 大端字节序:big-endian,将高字节存放在内存的其实地址. 例如,数字index=0x11223344,在大小端字节序方式下其存储形式为: 上图一目了然的可以看出大小端字节序的区别. 还有另外一个概念就是网络字节序.网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型.操作

linux和window环境下安装ruby和sass

linux下安装ruby 下载linux的ruby安装包    http://www.ruby-lang.org/en/downloads/ 将ruby安装包在linux环境下解压    tar -xvzf ruby-2.5.1.tar.gz 进入ruby安装文件夹                     cd ruby-2.5.1.tar.gz 编译源代码(安装ruby)      ./configure      make && make install 安装成功,检测ruby版本 

linux centos6.5 环境下安装redis的过程

过程还是挺折磨人的!谢谢许正同学一直耐心给我指导,虽然他也很忙.废话不多说: 首先,确保linux虚拟机联网: vm虚拟机>设置>Network Adapter 设置>网络配置设置成NAT window+r>services.msc查看服务项确保 进程 VMware DHCP Service, VMware NAT Service 启动状态 进入到CentOS,输入reboot命令重启下系统 然后查看虚机的右上角是否连接,eth0是虚拟机的默认网关. 然后安装gcc: yum in