gcc编译以及Makefile与GDB调试

一:编译选项:      
 

gcc常用编译的选项:
 

-c 表示编译源文件,只编译并生成目标文件。

-E 只运行 C 预编译器。

-o 表示输出目标文件

-g 表示在目标文件中产生调试信息, 用于 gdb 调试

-D<宏定义> 编译时将宏定义传入进去

-Wall 打开所有类型的警告。

-w 不生成任何警告信息。

-ansi 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色,

1、gcc 编译过程: 预编译--编译--汇编--链接
                                                                                   

2、编译过程包括下面几个阶段:
 

(1)预处理: 预处理器将对源文件中的宏进行展开。

(2)编译: gcc 将 c 文件编译成 汇编文件。

(3)汇编: as 将汇编文件编译成机器码。

(4)链接: 将目标文件和外部符号进行连接, 得到一个可执行二进制文

件。

3、gcc 编译常用选项
 

 
4、一般编译过程如下:
 

预处理阶段: 对包含的头文件( #include) 和宏定义( #define、 #ifdef等)               

            进行处理

            gcc  –E  hello.c  –o  hello.i

//-o 表示输出为指定文件类型 -E 将源文件(*.c) 转换为(*.i)

编译阶段: 检查代码规范性、 语法错误等, 在检查无误后把代码翻译成汇编语言

            gcc –S hello.i –o hello.s

            //-S 将已预处理的 C 原始程序(*.i) 转换为(*.s)

链接阶段: 将.s 的文件以及库文件整合起来链接为可执行程序

            gcc  hello.s –o hello.exe(或hello)

            //最后将汇编语言原始程序(*.s)和一些库函数整合成( *.exe)

5、条件编译
 

#include
 
main()
 
{
 
     #ifdef cjy
 
     //表示如果定义了 cjy, 即命令行参数传了cjy, 就执行下面的输出
 
     printf("cjy is defined!\n");
 
     #else
 
     printf("cjy is not defined!\n");
 
     #endif
 
     printf("main exit\n");
 
}
 

注:gcc –E project2.c –o project2.i –D cjy      //条件编译, 用-D 传递,

       或: gcc   project2.c  –o  project2  –D  cjy        

       如果没有传 cjy 则执行#else

       gcc  –S   project2.i  –o  project2.s

       gcc   project2.s       –o  project2

6、gcc 编译库选项
 

      

二、函数库(静态库以及动态库简述)
 

1、简述
 

静态库是目标文件.a 的归档文件( 格式为 libname.a)。

如果在编译某个程序时链接静态库, 则链接器将会搜索静态库并直接拷贝到该程序

的可执行二进制文件到当前文件中;

动态库( 格式为 libname.so[.主版本号.次版本号.发行号])。

在程序编译时并不会被链接到目标代码中, 而是在程序运行时才被载入。

2、创建静态库及动态库
 

静态库:

gcc -c add.c    //编译 add.c 源文件生成 add.o 目标文件
 
ar  crsv  libadd.a  add.o  //对目标文件*.o 进行归档, 生成 lib*.a,
 
此处 lib 必须要写的

然后就是在编译其他文件时,链接静态库。

gcc  -o mian  main.c  -L./  –ladd –I./

//不要忘记-L 后面的那个. (即在库文件的搜索路径中添加当前路径 -ladd 表示链接库文件 libadd.a/.so     -I./表示包含在当前目录中的头文件)

如果我们直接将编译完成的.o文件直接加入到了库的末尾,却并没有更新库的有效符号表。连接程序进行连接时,在静态库的符号索引表中无法定 位刚才加入的.o文件中定义的函数或者变量。这就需要在完成库成员追加以后让加入的所有.o文件中定义的函数(变量)有效,完成这个工作需要使用另外一个 工具“ranlib”来对静态库的符号索引表进行更新。

GNU工具中ar是用来制作库文件.a的,但同时还提供了一个ranlib,从手册上看ranlib相当于ar -s,为什么这样呢?

这是由于最早在Unix系统上ar程序是单纯用来打包多个.o到.a(类似于tar做的事情),而不处理.o里的符号表。Linker程序则需 要.a文件提供一个完整的符号表,所以当时就写了单独的ranlib程序用来产生linker所需要的符号信息。也就是说,产生一个对linker合 格的的.a文件需要做ar和ranlib两步 。

动态库:

gcc -fPIC -Wall -c add.c
 
gcc -shared -o libadd.so add.o
最后编译链接动态库: gcc -o main main.c -L. –ladd

在运行 main 前, 需要注册动态库的路径。常采用的方法有:

cp  libadd.so  /lib   //通常采用的方法, cp  lib*.so /lib  将其copy到系统的/lib文件夹下

创建动态链接库之后, 以后就可以使用该动态链接库了

例如在 test.c 里面调用了原来库中的函数, 则执行 gcc  test.c –o test    –ladd 就可以了。较方便

3、静态库与动态库的比较
 

动态库只在执行时才被链接使用, 不是直接编译为可执行文件, 并且一个动态库可以被多个程序使用故可称为共享库。

静态库将会整合到程序中,在程序执行时不用加载静态库。因此,静态库会使你的程序臃肿并且难以升级,但比较容易部署。而动态库使你的程序轻便易于升级但难以部署。

4、gcc --- 优化选项
 

gcc 对代码进行优化通过选项“-On”来控制优化级别(n是整数)。

优化选项“-O1”:主要进行线程跳转和延迟退栈两种优化。

选项“-O2” 除了完成所有“ -O1” 级别的优化之外,还要进行一些额外的调整工作,如处理其指令调度等。

“-O3” 则还包括循环展开或其他一些与处理器特性相关的优化工作。

注意:虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战,因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方, 循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都是不好的。所以在调试的时候最好不要使用任何的优化选项,只有当程序在最终发行的时候才考虑对其进行优化。

三、make工程管理器
 

1、简介
 

工程管理器指管理较多的文件,它是自动管理器能根据文件时间自动发现更新过的文件而减少编译的工作量,同时通过读入Makefile文件来执行大量的编译工作。(自动化)

2、Makefile基本语法及格式
 

target: dependency_files //目标项:依赖项

< TAB >command           //必须以 tab 开头, command为编译命令

编写好Makefile之后,就可以直接使用  make 编译了。若写了clean,可make clean 清理,重新编译。

如下:

                               

特殊处理与伪目标:

.PHONY 是 Makefile 文件的关键字, 表示它后面列表中的目标均为伪目标。伪目标通常用在清理文件、 强制重新编译等情况下。

eg:      

.PHONY:clean

clean:

     rm main  main.o

变量、 函数与规则

1、引言

    随着软件项目的变大、变复杂,源文件也越来越多,如果采用前面的方式makefile 文件,将会使makefile也变得复杂而难于维护。故通过make支持的变量定义、规则和内置函数,可以写出通用性较强的makefile文件,使得同一个makefile文件能够适应不能的项目是重要的。

2、变量: 用来代替一个文本字符串

    变量名:=变量值     简单变量展开(类似于 C++的赋值)   //通常采用这种形式

使用变量的一般方法: $(变量名)=??? 赋值        ???=$(变量名) 引用

例如:--下

                     

变量分为: 用户自定义变量, 预定义变量( CFLAGS), 自动变量, 环境变量

自动变量: 指在使用的时候, 自动用特定的值替换。

常见的有: $@ 当前规则的目标文件(重点) 

          $^ 当前规则的所有依赖文件, 以空格分隔(重点)

          eg:用自动变量      CFLAGS:= -Wall -O2 –fpic

预定义变量: 内部事先定义好的变量, 但是它的值是固定的, 并且有

些的值是为空的。

AR: 库文件打包程序默认为 ar             CC: c 编译器默认为 cc

CPP: c 预编译器, 默认为$(CC) –E        CFLAGS: c 编译器选项, 无默认

CXXFLAGS: c++编译器选项

                

规则分为: 普通规则, 隐含规则, 模式规则

隐含规则:  //*.o 文件自动依赖*.c 或*.cc 文件, 所以可以

省略main.o:main.cpp 等

模式规则: 通过匹配模式找字符串, %匹配 1 或多个任意字符串    %.o: %.cpp 任何目标文件的依赖文件是与目标文件同名的并且扩展名为.cpp 的文件

函数:

1. wildcard 搜索当前目录下的文件名, 展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。 SOURCES = $(wildcard *.cpp)把当前目录下所有'.cpp'文件存入变量 SOURCES 里。

2、 字符串替换函数:(patsubst 要查找的子串,替换后的目标子串, 源字符串)。 将源字符串(以空格分隔)中的所有要查找的子串替换成目标子串。 如

OBJS = $(patsubst %.cpp,%.o,$(SOURCES))   可以和上一步对应起来看。即把 SOURCES 中'.cpp' 替换为'.o' 。

3、(addprefix 前缀, 源字符串)函数把第二个参数列表的每一项前缀加上第一个参       

   数值

3、如下为一个较为通用的Makefile:

SOURCES:=$(wildcard *.c)

OBJS:=$(patsubst %.c,%.o,$(SOURCES))

ELF:=main

CC:=gcc

CFLAGS:=-g -Wall

$(ELF):$(OBJS)

        gcc $^ -o $@

.PHONY:clean

clean:

        rm $(OBJS) $(ELF)

四、Gdb程序调试
1、gdb 常用命令
 

首先程序编译时加 -g 选项才可打开调试选项 
eg:gcc –o filename –Wall filename.c –g //进入调试
gdb filename //进入调试
l    //显示代码 (list)
b  4    //在第四行设置断点 相当于 Windows 的 F9 (break)           //若为 b  main  则表示断点打在main处
r    //运行   相当于 Windows 的 F5 (run)
n //下一步不进入函数 相当于 Windows 的 F10  (next)
s //表示单步进入函数, 相当于 Windows 的 F11 (step)
p  I  //打印变量 I 相当于 Windows 的 Watch 窗口(print)
c     //运行到最后(continue)
bt   // 用于查看当前堆栈
f   4    // 进入第 4 层堆栈 
q     //退出 相当于 Windows 的   Shift+F5 (quit)
          

五、其他补充
 

1. 在 linux 中利用 system(“clear”);实现类似于 windows 里面的清屏函数 system(“cls”);

2. LINUX 中可以通过下面的方式可以实现 system("pause");功能:

printf(“Press any key to continue…”);
 
getchar();
 
getchar(); //要用两个 getchar()函数
3. linux 中如何刷新输入缓冲区, 利用 getchar()函数即可。 输出缓冲区可以利用 fflush(stdout);

4.命令 x 是用来检查内存情况, 英文是 examine 含义, 使用方法   x /20xb 变量首地址, 其中 20x 代表 16 进制的长度, b 代表字节的含义

5.针对段错误, 可以通过 ulimit -c unlimited 设置 core file size 为不限制大小, 设置完毕后, 可以通过 ulimit -a 进行查看是否设置 ok, 这时候再次运行程序,会产生 core 文件,通过 gdb 可执行程序 core 文件,

进行调试。 直接通过 bt 可以看到程序段错误时的现场, 通过 f  1 可以直接切换到程序现场(第一层堆栈)。

gdb ./test2 core

6.调试正在运行的程序, 通过 attach 进程 ID, 调试正在运行的程序

其他:更多操作可以参考: https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/gdb.html

GDB 优秀博文: https://www.cnblogs.com/life2refuel/p/5396538.html


smilejiasmile
关注

0


0

9


专栏目录
pandas对dataFrame中某一个列的数据进行处理的方法
09-19
主要介绍了pandas对dataFrame中某一个列的数据进行处理的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Makefile和gdb调试
ys5858588的博客
 1154
1.makefile的规则: target:prerequisites (tab键)commed target可以是一个object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。对于标签这种特性,在后续的“伪目标”章节中会有叙述。 prerequisites就是,要生成那个target所需要的文件或是目标。 command也就是make需要执行的命令。(任


GCC编译详解+Gdb调试器+Make工程管理器_rongwenxiao的专栏
8-31
用户可以使用”-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。 [root@localhost Gcc]# Gcc –S hello.i –o hello.s 以下列出了hello.s的内容,可见Gcc已经将其转化为汇编了,感兴趣的读者可以分析一下这一行...
...Code编译调试C++项目(gcc/g++、Makefile入门、vs co...
11-1
由于makefile文件中加了-g这一选项,于是可以通过gdb进行调试,并且会命中断点,这里感兴趣可以再了解一下gdb的使用。 接下来我们要说到如何通过VS Code进行调试。 三. 在VS Code中编译调试
GCC 编译详解
weixin_30416497的博客
 996
GNU CC(简称为Gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。Gcc不仅功能强大,而且可以编译如C、C++、Object C、Java、Fortran、Pascal、Modula-3和Ada等多种语言,而且Gcc又是一个交叉平台编译器,它能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译...
gcc-3.4.6.rpm完整包
10-15
当前本人在centos6.2_32安装成功 安装顺序 rpm -ivh glibc-kernheaders-2.4-9.1.103.EL.i386.rpm --nodeps --force rpm -ivh glibc-headers-2.3.4-2.43.i386.rpm --nodeps --force rpm -ivh glibc-devel-2.3.4-2.43.i386.rpm --nodeps --force rpm -ivh cpp-3.4.6-11.i386.rpm --nodeps --force rpm -ivh gcc-3.4.6-11.i386.rpm --nodeps --force rpm -ivh gcc-c++-3.4.6-11.i386.rpm --nodeps --force rpm -ivh libstdc++-devel-3.4.6-11.i386.rpm --nodeps --force rpm -ivh libstdc++-3.4.6-11.i386.rpm --nodeps --force
makefile文件和gcc g++ gdb编译_Happy Together的博客
10-5
gcc -c a.c 会编译生成目标文件 a.o 然后gcc -o a a.o 生出可执行文件 ./a 执行 c++ 采用g++ 对于调试 采用gdb gcc -o a-ga.c 加上-g后才可以采用gdb调试, 若是直接采用makefile文件,可以在makefile 中CXXFLAGS=-g...
Linux学习(vi编辑器 gcc工具链 make和Makefile gdb调试工具)
11-11
(2) 多个程序文件的编译:gcc test1.c test2.c -o test 三、1、make和Makefilemake(命令运行时,须要一个 Makefile 文件,以告诉make命令须要怎么样的去编译和链接程序。) 2、一个Makefile文件包含五个方面的内容: 具体规则 隐含...
Linux系统Makefile编写与GCC编译实验报告.pdf
09-03
实 验 报 告 实验题目 Linux 系统 Makefile 编写与 GCC编译实验 姓名 学号 课程名称 所在学院 专业班级 任课教师 实验项目名称 Linux 系统 Makefile 编写与 GCC编译实验 一实验目的与要求 1通过实验学习 gcc 编译器编译 c 程序的方法 熟悉 gcc 编译程序的各个阶 段 2 通过对包含多文件的 Makefile 的编写熟悉各种形式的 Makefile
1小时点击量破千万,阿里巴巴首发Java面试笔记,全是技术重点
Java白叔的博客
 196
多数的公司总体上面试都是以自我介绍+项目介绍+项目细节/难点提问+基础知识点考核+算法题这个流程下来的。有些公司可能还会问几个实际的场景类的问题,这个环节阿里是必问的,这种问题通常是没有正确答案的,就看个人的理解,个人的积累了。剩下的就没啥了,都是换汤不换药,聊项目就看你自己对你自己的项目是否理解的透彻,比如经常问你你为什么选择这个技术,为什么这么处理之类的,常考的基础的知识点就那么多,最后算法就是靠刷题。今天分享给大家的是一份前段时间爆火的JAVA面试笔记,有需要可以点击文末名片免费领取,也都是
C与C++区别 makefile文件 gdb调试_偶然i的博客
10-8
C与C++区别 makefile文件 gdb调试 C与C++区别 gcc .cpp -> c++语法 编译 不能链接c++库 .c ->c语法 g++ .cpp 都通过c++语法编译 .c 预编译 编译 汇编 链接(《程序员自我修养》中有总结)...
gcc编译选项与gdb调试_ITxiaoxiaobai的博客
10-26
gcc test.c -o test -g g++ test.cpp -o test -g 启动gdb调试的方法有以下三种: gdb gdb core // core是程序core dump产生的文件,产生core文件,需设置栈大小无线使用ulimit -c unlimited ...
Linux下调试器GDB、makefile的使用
leap的博客
 8038
前面的几篇博客中我们讲解了Linux下的编辑器vim、编译器gcc和g++,今天我们来介绍一下其他常用的三种工具,它们分别是程序调试器:GDB、代码查看器:ctags、还有一个辅助工程的工具:Makefile程序调试器:GDB在windos下我们常用vs编辑器中自带的调试工具进行程序的调试,对于程序员来说,调试自己写的程序时必须的;在Linux中,我们可以使用GDB来调试已经编译好的可执行程序;注意
面试题:深克隆和浅克隆的实现方式
Java大将军的博客
 38
面试题:深克隆和浅克隆的实现方式面试官考察点考察目的:深克隆和浅克隆,考察的是Java基础知识的理解。考察人群:2到5年开发经验。背景知识详解先了解下浅克隆和深克隆的定义: 浅克隆:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。 深克隆:除去那些引用其他对象的变量,被复制对象的所有变量都含有与原来的对象相同的值。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用.
gcc gdb makefile 总结
jianglu1210的博客
 164
随着编程语言技术的不断发展,应用程序的开发过程也越来越简化。然而功能越是强大的工具,其内部结构也越复杂。高级编程语言的背后是一套复杂的编译系统。编译系统的任务是把高级语言编写的程序翻译成计算机可以直接运行的二进制文件。 GCC 在 Linux 平台上,最流行的编译系统是 GCC(GNU Compile Collection)。GCC 也是 GNU发布的最著名的软件之一。GCC 的功能非常强大
AppServiceForLinux部署SpringBoot应用之后,查看日志文件时的疑惑
gp16674213804的博客
 67
编写Java Spring Boot应用,通过配置logging.path路径把日志输出在指定的文件夹中。第一步:通过VS Code创建一个空的Spring Boot项目第二步:在application.properties中添加输入日志的级别和指定路径logging.path=mylogslogging.level.root= INFOlogging.level.org.springframework.web= INFOlogging.level.org.springframewo
makefile和gdb的使用
Euthanazia的博客
 518
一、make工具和makefile文件   1.显示规则   【语法】 target: prerequisites...          [tab]command Tips:可以有多行命令。同一行多命令需要用&&或者;连接,\续行。cd只影响所在的命令行。 依赖关系: e.g:hello:hello.c or:hello:hello.o hello.o:hello.c 编
知道你和高薪的距离在哪里吗?这份“并发编程笔记”请你收好
Java白叔的博客
 32
事情是这样的...面试官:你好!你的一些信息我们已经初步了解了,咱们直接进入正题吧!程序员:好的!面试官:嗯,对多线程有一些深入了解是吧?程序员:是的,多线程本身是学习Java语言入门到高级的必备能力,所以平时看得比较多面试官:入门?呵呵~好那我就来好好问问,多线程有什么用?程序员:一,发挥多核CPU 的优势;二,防止阻塞;三,便于建模面试官:说说Java 实现线程的几种方式程序员:继承 Thread 类实现多线程;实现 Runnable 接口方式实现多线程;使用 Exe
Makefile中加入gdb调试选项
技术人生
 870
Makefile文件示例: target = hello.o example.o main : $ (target) cc -c main $(target) -----tab缩进开头 main.o : your.h clean.o : your.h .PHONY : clean clean : -rm $(target) -----tab缩进开头,以下同理 加入-g在cc后面不起效。 遂...
不是科班出身,工作 15 年,从刚开始的 2800 到如今的年薪 150 万
m0_60720471的博客
 94
现在虽然物质富足,年轻人不用再为吃穿发愁,但是大环境的竞争压力也在逐渐提高,从幼儿园就开始的读书军备竞赛,到求职阶段水涨船高的用工要求,再到定居时面对的天价楼市,现在的孩子从一出生就开始竞争,这大概就是内卷吧,我相信这些都是都是导致现在年轻人丧的原因。一个时代有一个时代的烙印,作为一个“过来人”,我觉得需要了解年轻人的难处和时代背景,多倾听,保持同理心,而不是急于否定。最后希望对于求职阶段的一些社会性讨论问题,建议开辟一个专区,让大家去讨论,可以基于年龄层、性别、职级、工种去做分层统计,也算是做社会
全面学习make工具,学写makefile,gcc全部的选项详解
05-05
全面学习make工具教程,使用MAKE。学写makefile,对项目工程进行管理;gcc全部的选项详解,绝对最全面的翻译英文版编译手册。所有GCC选项都可找到详细解释.
7年Java老后端不能说的秘密:怎么样更好的优化Redis性能?
最新发布
Java白叔的博客
 223
大家好,我是一名Java后端程序员,每天开心的撸CRUD;你猜这次我又要写个啥没有卵用的知识点呢?不好意思,问的稍微有点早了,啥提示都没给,咋猜呢,对吧?今天早上老板把我叫到办公室,对我说,“公司最近接了个电商小程序单子,你和王二狗,张SD参与下需求分析和设计,然后下个月开发,3个月内完成测试,上线交付”。WC,WC,WC。。。。。。。“老板,老板,我没学过微信小程序,我是个Java后端程序员,你再招一个前端微信小程序开发吧”,我很低声的跟老板说。老板很大声的吼道,“不会的东西,
python3读取excel文件只提取某些行某些列的值方法
09-20
今天小编就为大家分享一篇python3读取excel文件只提取某些行某些列的值方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
Linux GCC编译、gdb调试、makefile、动态链接库的创建
cuixuange的博客
 764
学习了一段时间的Linux 系统编程来总结总结,GCC的一些相关知识。比如GCC编译,gdb调试器的使用,makefile的编写等等知识点。这些都是最最基础的知识了,hh。还有出现segment fault段错误是gdb的用处就很大了,gdb core能直接定位到段错误发生位置。1.GCC编译1.预处理编译汇编链接 预处理: gcc -E main.c 得到文件main.i,是将define的宏定
Linux下vim编辑、makefile编译、GDB调试
张一西的博客
 559
Linux环境下C语言编程 1 .序        笔者又来更新博客了,每次立下Flag说要一周一次更新博客,但总是拖,最后奈何4月份只更新了一次,说明四月份又浑浑噩噩度过了一个月,不过值得可喜的是笔者在4月份找了一份实习工作,在里面做嵌入式软件开发,目前负责QT的开发。       &n...
makefile以及用gcc进行C编译
zhangzhi2ma的博客
 5014
C编译过程: 预处理 .c -> .i 汇编    .i -> .s 编译    .s -> .o 链接    .0 -> 可执行文件   gcc编译器: gcc [选项]  [文件名] 选项包括:     假设源程序文件名为test.c。 1. 无选项编译链接 用法:#gcc test.c 作用:将test.c预处理、汇编、编译并链接形成可执行文件...
gcc、gdb、Makefile的使用
 

你可能感兴趣的:(makefile,vim)