用C编译器编译源文件:gcc 源文件 -o 可执行文件名
详细步骤:

  • gcc -E a.c -o a.i预处理器将头文件展开,宏替换,去掉注释
  • gcc -S a.i -o a.s编译器将C文件变成汇编文件
  • gcc -c a.s -o a.o汇编器将会变文件变成二进制文件
  • gcc a.o -o a链接器进行链接

ESc+链接
如果不使用参数-o 则自动生成a.out

制定头文件的路径gcc a.c -I 头文件的目录 -o 生成可执行文件的名字在比较旧的版本上-I和头文件目录之间不能有空格,现版本无所谓
指定宏-D 宏名
优化-O1/O2/O3O3优化速度最高
输出警告信息-Wall
生成调试信息-g

静态库

  1. 命名规则
    lib+库的名字+.a
  2. 制作步骤
    生成对应的.o文件,直接使用参数-c得到.o文件,记得不要使用-o参数,否则将会直接生成可执行文件
    将生成的.o文件进行打包,需要使用软件ar.o打包为.a
ar rcs 静态库名称 所有的.o
  1. 发布和使用静态库
    打包静态库和头文件,将所有的静态库放到lib文件夹中,将所有的头文件放到include文件夹中,制作好静态库以后可以发送这两个文件夹。
    用户通过头文件知道有哪些函数接口。通过直接和源文件编译静态库使用。
gcc 源文件 静态库 -o 可执行文件 -Iinclude
gcc 源文件 -Iinclude -L lib -l 静态库文件名(去掉头部lib和尾部.a) -o 可执行文件
  1. 静态库的优缺点
nm 静态库文件 //查看静态库

打包的最小单元为.o
优点:

  1. 库已经打包在程序中,不需要再提供
  2. 库的加载速度比较快
    缺点:
  3. 可执行文件会比较大
  4. 如果库发生了改变需要重新编译

动态库/共享库

  1. 命名规则
    lib+名字+.so
  2. 制作步骤
    (1) 生成与位置无关的代码(.o)
gcc -fPIC -c *.c -Iinlcude

(2) 将.o打包成共享库
Linux每一个运行的程序操作系统都会为其分配一个0-4G的地址空间。Linux下可执行文件格式:ELF

gcc -shared -o libname.so *.o -Iinclude

再讲lib中的.so文件和include中的头文件发送给用户

  1. 用户使用
gcc main.c lib/libname.so -o main -Iinclude
gcc main.c -Iinclude -L lib -l name -o main//需要注意的是这里的name是不包含lib和后缀.so的

使用ldd查看可执行文件所依赖的所有的共享库的名字

动态库的使用需要动态链接器帮助。我们需要让动态链接器找到我们自己的动态链接库

正常情况下使用会出现动态库无法找到的问题。然后就需要我们去解决。
可是我自己尝试的时候没有遇到这个情况。。。我也不清楚为什么,可能是现在版本的gcc已经智能地解决这个问题了。

(1)将动态库放到系统的lib文件夹中
(2) 配置环境变量LD_LIBRARY_PATH(如果你的动态库没有在默认的环境变量中,会先在这个环境变量中查找)
用于临时测试

echo $LD_LIBRARY_PATH //$从环境变量中取值  查看环境变量
export LD_LIBRARY_PATH=./lib //将当前目录下的lib文件夹导入到环境变量中

关掉终端后失效
(3)

ls -a
vi .bashrc
在里面加上export LD_LIBRARY_PATH=动态库目录
重启终端

永久
(4)工作中更加常用的方法

  • 找到动态链接器的配置文件
    /etc/ld.so.conf
    需要使用管理员权限

  • 将动态库的路径写到配置文件中

  • 更新sudo ldconfig -v -v是提示信息

动态库没有加载到源文件中,而是在需要使用的位置加上了一个标记,在使用的时候才进行访问。
优点:

  1. 执行程序很小
  2. 动态库更新方便
    缺点:
  3. 需要将动态库发布给用户
  4. 加载库的时候速度较慢

gdb 调试

  • l 默认展示包含main()的文件
  • l 文件名:行号 展示以行号为中心上下文件的内容
  • l 文件名:函数名 展示文件中的函数,输入l继续展示后面的内容,然后后面再直接按回车,会继续向下展示文件,一次展示10行
  • break 行号在某一行打断点b 行号
  • b 行号 if 条件条件断点,条件断点只能设置在循环内部,如果设置在边界不会停止
  • b filename:行号在某个文件的某一行设置断点
  • info break i b查看断点信息
  • start gdb开始运行程序,每次运行一行,n单步调试,c继续执行到断点
  • s下一步,会进入函数体内部(step)
  • n下一步,不会进入函数内部
  • run直接运行到断点,如果没有断点直接运行结束
  • p 变量 展示某个变量的值
  • ptype 变量 展示变量的类型
  • display 变量追踪某个变量的值
  • undisplay 变量编号取消追踪某个变量
  • info display 打印所有追踪变量的信息
  • u将循环运行结束,结束循环
  • finish 跳出当前函数,需要将函数中的断点消除
  • d 断点编号删除断点(del)
  • set var 变量=x直接运行到变量为x的时候
  • quit退出gdb

makefile

makefile项目管理工具,用于管理源代码

简单makefile文件

  1. 命名规则
    (1) makefile
    (2) Makefile

  2. 编写规则
    makefile 一般情况下要和.c文件在一个文件夹中,如果不在需要绝对路径
    三要素:

目标:依赖        //目标就是想要生成文件的名字  依赖:`.c`文件命令(必须要有Tab缩进):gcc a.c b.c c.c -o 目标
  1. 使用
    make

进阶makefile文件

当一些文件修改以后需要重新编译,为了解决这个问题:
例如:

app:main.o add.o sub.o mul.o     //终极目标,默认第一条语句是终极目标gcc main.o add.o sub.o mul.o -o app
//如果依赖中的文件没有发现,就去下面的子目标中查找有没有相关的规则用于生成文件
main.o:main.c gcc main.c -c
add.o:add.cgcc add.c -c
sub.o:sub.cgcc sub.c -c
mul.o:mul.cgcc mul.c -c

上面的写法会自动查找文件是否修改,如果没有修改就不会编译,从而提高效率
工作原理:通过比较修改时间,目标应该比依赖的修改时间迟,如果发现目标比依赖的修改时间早则重新生成目标。

进进阶makefile文件

上面的写法有些冗余,通过变量来将写法变得简洁

obj=main.o add.o sub.o mul.o
target=app
$(target):$(obj)    //$取obj变量中的值gcc $^ -o $@
//模式规则
%.o:%.cgcc -c $< -o &@

makefile中的自动变量:

  • $<规则中的第一个依赖
  • $@规则中的目标
  • $^规则中的所有依赖
  • 只能够在规则中的命令来使用
    makefile自己维护的变量:
  • 都是大写,例如CC,CPPFLAGS,CFLAGS,LDFLAGS

进进进阶makefile文件

在makefile中的函数都是有返回值的

  • 获取指定目录下所有的.c文件
src=$(wildcard 所需要查找的目录/*.c)
  • 获取指定目录下所有的.o文件
obj=$(patsubst ./%.c , ./%.o , $(src))      #模式匹配
  • 自动删除以前生成的目标文件
clean:rm $(target) -f    #如果不存在也会强制删除,不会弹出提示信息

生成文件 时候:

make clean   #会删除目标文件,只会执行生成clean的语句

如果目录中真的存在clean目标,则会提示目标是最新的而不会运行。

.PHONY:clean  #声明clean为伪目标,不会与目录中的目标进行比较

在命令前面加上-,则命令执行失败以后也不会停下来,继续向后执行

Linux命令【三】gcc编译+静态库+动态库+makefile+gdb调试相关推荐

  1. Linux gcc编译过程及动态/静态库制作

    Linux库概念及如何制作静态库和动态库 1: gcc编译的过程 2: 分文件编程 3: 库(静态库和动态库) 3.1: 库的基本介绍 3.2: 静态和动态库的区别 3.3: 库的制作及使用 3.3. ...

  2. 编译c语言动态库,使用gcc、g++编译C/C++源程序,静态库和动态库创建方式

    后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序: 后缀为.cpp的,两者都会认为是c++程序. 注意,虽然c++是c的超集,但是两者对语法的要求是有区别的. 编译阶段,g++会调用gc ...

  3. linux centos 编译Lua5.2.0 静态库 动态库

    一 lua下载 lua5.2.0下载地址 :http://download.csdn.net/download/yzf279533105/10109818 二 笔者这里linux环境为centos6. ...

  4. Linux下的vim编辑器与gcc编译器及静动态库的制作

    1.vim编辑器的使用: (1)vim的三种模式: 命令模式:打开文件默认进入命令模式 编辑模式:需要输入一些命令切换到编辑模式 末行模式:在末行模式可以输入一些命令 命令模式aios和AIOS都可以 ...

  5. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    0. 引言 UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统.linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统. ...

  6. Linux学习---静态库 动态库

    今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情. 在Linux操作系统中,普遍使用E ...

  7. GCC编译静态库的-fPIC选项

    GCC编译静态库的-fPIC选项 背景 通常在linux下用gcc编译动态库时都会加上一个-fPIC选项来生成位置无关代码,但是从来没有人明确的说过是不是要在编译静态库时也加上-fPIC选项.我在这篇 ...

  8. Linux-(C/C++)生成并使用静态库/动态库

    静态库/动态库概要 在Windows下静态库的后缀为:.lib.动态库后缀为:.dll:而在Linux下静态库的后缀为:.a.动态库的后缀为:.so. 那么什么是静态库呢? 首先我们来看看程序编译的大 ...

  9. NDK01-打包静态库 动态库在mk和cmake环境配置使用

    动态库和静态库 动态库: libxxx.so 运行的时候,才会去加载,加载一次就在内存中存在副本,其他地方使用就都是公用的.使用场景就是 高德百度sdk对外开房 静态库: libxxx.a 编译期把静 ...

  10. 在Linux下gcc缺省编译,在Linux下用gcc编译hello world

    1. 确保Linux系统里已经装好了gcc 测试:输入gcc后是如下的结果就说明已经安装成功 2. 创建HelloWorld.c 使用 touch 创建一个空文件; 用vim编辑 按下A或者I 插入 ...

最新文章

  1. 《需求设计:构建用户想要和需要的产品》——3.7 品质
  2. 内存缓存之memcache的使用
  3. List去重复——多个复杂字段判断去重
  4. 2012年度IT博客大赛【星光评委】申请说明
  5. 海拨3000点位的岛型堰塞湖
  6. Asp.net如何截屏
  7. 计算机一级考试题组成,计算机一级考试试题汇总
  8. java面试题——java基础(四),java初级面试笔试题
  9. JAVA中GridBagLayout布局管理器应用详解
  10. 把excel每一行中的数据输出为一个txt文档的VBA函数
  11. leetcode之旋转链表
  12. Linux内核部件分析 更强的链表klist
  13. 武大计算机考研 932教材,2018武汉大学考研官方指定参考书目
  14. 汽车维修企业管理【1】
  15. caffe入门学习(5):绘制网络结构图
  16. html中几何图形代码,HTML5实现绘制几何图形
  17. OCR(图片识别)之 百度 VS 谷歌
  18. vuex的模块化管理~~~狂徒李四
  19. 有哪些好用的App云测试平台
  20. 火狐html显示黑点

热门文章

  1. 在Ajax方式产生的浮动框中,点击选项包含某个关键字的选项
  2. width:100vh与min-height:calc(100vh + 51px)
  3. Java12题:发奖金问题
  4. Windows MobileCE 开发书籍大全
  5. CodePage简介(转)
  6. qt商业版和开源版的区别_微擎商业版系统V2.0.9全开源版纯净框架
  7. iview 级联选择组件_使用 element-ui 级联插件遇到的坑
  8. mysql5.7运行按钮_MySQL 5.7.* 启动问题
  9. avframe转byte数组_C# amp; VB6.0 图像与二维数组 互转
  10. C语言开发笔记(一)自动转换和强制转换