1 linux系统编程入门-linux gcc 静态库 动态库 Makefile GDB

标题: linux gcc 静态库 动态库 Makefile GDB

 

1.1linux开发环境搭建

1 linux系统

虚拟机 云服务器

sudo apt-install openssh-server

   

2 xshell xftp

ifconfig ip地址 端口22 用户名 密码

   

3 vscode

安装插件 Chinese、Remote Develoment、c++

远程资源管理器 SSH Targets 点击configure(齿轮) 默认地址(点第一个)

Host 随便填 HostName ip地址 User 用户名

   

ssh-keygen -t rsa

生成ssh公钥 每次连接不用输密码

 

1.2 gcc

支持c、c++、object-c、java、go等

安装

sudo apt-install gcc g++

查看版本

gcc/g++ -v/--version

 

编译

gcc xxx.c -o xxx

运行

./xxx

   

gcc工作流程:

源代码.h .cpp-(预处理)-预处理后的源代码.i-(编译器编译)-汇编代码.s-(汇编器)-目标代码.o-(链接器+启动代码、代码库、其他代码)-最终可执行文件

   

 

   

 

   

 

   

 

1.3静态库

好处:1代码保密 2方便部署和分发

   

命名规则:

linux

libxxx.a

windows

libxxx.lib

   

制作:

1 gcc获得.o文件

2 .o文件打包,使用ar工具(archive)

ar rcs libxxx.a xxx.o xxx.o

r 将文件插入备存文件中 c 建立备存文件 s 索引

   

使用:使用-l参数 和 -L参数

gcc main.c -o app -L ./lib -l calc

注意头文件也要导入

   

 

1.4动态库

  • 命名规则:

linux

libxx.so

windows

libxxx.dll

   

   

  • 制作:

    1 gcc得到.o文件,得到和位置无关的代码

gcc -c -fpic/-fPIC a.c b.c

2gcc得到动态库

gcc -shared a.o b.o -o libcalc.sp

   

  • 使用:

gcc main.c -o app -L ./lib -l calc

编译没错,但是运行 ./app 时会报错,原因见下面动态库工作原理

ldd app可以查看app程序 动态库依赖、加载情况;需要系统的动态载入器来获取绝对路劲加载动态库,查找路径见下

要解决,将动态库加入到这些路径中其一就行

evn 显示环境变量,将动态库的路径加入到LD_LIBRARY,加入方法:

  • 方法一(1当次终端有效):export LD_LIBRARY=$LD_LIBRARY_PATH:xxx(动态库的绝对路径)

    2一直有效,用户层面):cd ./ vim ./.bashrc 最后一行插入export LD_LIBRARY=$LD_LIBRARY_PATH:xxx(动态库的绝对路径) source ~/.bashrc

    3一直有效,系统级别):sudo vim /etc/profile 然后和方法二一样插入 source /etc/profile

  • 方法二:修改 /etc/ld/so.cache 具体不写了
  • 方法三(不建议):将文件放到 /lib 或 /usr/lib

       

    20225720:30:54 根据经验 使用第二种方法比较好,具体过程可以看ns3-vscode配置调试 笔记里有写动态库加入系统

   

   

静态库和动态库的工作原理:

   

 

   

 

1.5静态库和动态库对比

   

   

 

   

   

   

   

   

 

每个程序使用静态库都需要加载到内存里,所以更加消耗系统资源;而动态库加载一次,可以供多个程序使用。

   

   

 

   

   

   

   

 

1.6Makefile

一个工程中源文件很多,按类型、功能、模块分目录保存,Makefile文件定义了一系列规则来指定哪些文件要先编译,哪些后编译。

自动化编译,指导我们的源文件怎么进行编译

make nmake

   

   

  • 文件命名:

    makefile 或者 Makefile

       

  • Makefile 规则:

    一个makefile文件可以有一个或者多个规则

    目标 … : 依赖

    命令 (shell命令)

    • 目标:最终要生成的文件(伪目标除外)
    • 依赖:生成目标所需要的文件或是目标
    • 命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)

         

  • 例子:

touch makefile

app:sub.c add.c mult.c div.c main.c

gcc sub.c add.c mult.c div.c main.c -o app

make

./app

   

  • 工作原理
    • 命令执行前,需要先检查规则中的依赖是否存在
      • 如果存在,执行命令
      • 如果不存在,向下检查其他的规则,检查有没有一个规则是用来生成这个依赖的,

        如果找到了,则执行该规则中的命令

      • 检测更新,在执行规则中的命令时,会比较目标和依赖文件的时间
        • 如果依赖的时间比目标的时间晚,需要重新生成目标
        • 如果依赖的时间比目标的时间早,目标不需要更新,对于规则中的命令不需要被执行

             

  • 变量
    • 自定义变量
      • 变量名= 变量值 var = hello
    • 预编译变量
      • AR:归档维护程序的名称,默认值为ar
      • CCC编译器的名称,默认值为cc
      • CXXC++编译器的名称,默认值为g++
      • $@:目标的完整名称
      • $<:第一个依赖文件的名称
      • $^:所有依赖文件
    • 获取变量的值
      • $(变量名)

           

  • 模式匹配

    %.o:%.c

    • %:通配符,匹配一个字符串
    • 两个%匹配的是同一个字符串

   

  • 函数
    • $(wildcard OATTERN…)
      • 功能:获取指定目录下指定类型的文件列表
      • 参数:PATTERN指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
      • 返回:得到的若干个的文件列表,文件名之间使用空格间隔
      • 示例:
        • $(wildcard *.c ./sub/*.c)
        • 返回值格式:a.c b.c c.c d.c e.c f.c
    • $(patsubst <pattern>,<replacement>,<text>)
      • 功能:查找<text>中的单词(单词以"空格"、"Tab"或者"回车"、"换行"分隔)是否符合模式<pattern>,

        如果匹配的话,则以<replacement>替换

        • <pattern>可以包括通配符 `%`,表示任意长度的字串。如果<replacement>中也包含 `%`,那么 ,<replacement>中的这个% 将是<pattern>中的那个

          %所代表的字串。(可以用\%来转义,以\%来表示真实含义的%字符)

        • 返回:函数返回被替换过后的字符串
        • 示例:

          %(patsubst %.c, %.o, x.c bar.c)

          返回值格式:x.o bar.o

             

  • clean
    • clean:

      rm -f xxx

      • make clean
      • 如果同目录有clean文件,则不能进行正常运行clean,要在makefile文件中设置clean为伪目标文件
        • .PHONY:clean

       

 

1.7GDB

   

  • 什么是GDB:
    • GDB 是由GNU 软件系统社区提供的调试工具,同GCC 配套组成了一套完整的开发环境,GDB Linux 和许多类Unix 系统中的标准开发环境。
    • 一般来说,GDB 主要帮助你完成下面四个方面的功能:
      • 启动程序,可以按照自定义的要求随心所欲的运行程序
      • 可让被调试的程序在所指定的调置的断点处停住(断点可以是条件表达式)
      • 当程序被停住时,可以检查此时程序中所发生的事
      • 可以改变程序,将一个BUG 产生的影响修正从而测试其他BUG

   

  • 准备工作:
    • 通常,在为调试而编译时,我们会()关掉编译器的优化选项( -O ), 并打开调试选项( -g )。
    • 另外, -Wall 在尽量不影响程序行为的情况下选项打开所有warning,也可以发现许多问题,避免一些不必要的BUG

gcc -g -Wall program.c -o program

  •  -g  选项的作用是在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,

    但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb 能找到源文件。

       

  • 启动、退出、查看代码

     

       

       

  • 断点操作

     

   

   

  • 调试命令

     

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

 

   

 

   

 

   

 

   

 

   

 

   

 

-fpic 用于编译阶段,产生的代码没有绝对地址,全部用相对地址,这正好满足了共享库的要求,共享库被加载时地址不是固定的。如果不加-fpic ,那么生成的代码就会与位置有关,当进程使用该.so文件时都需要重定位,且会产生成该文件的副本,每个副本都不同,不同点取决于该文件代码段与数据段所映射内存的位置。

来自 <https://www.nowcoder.com/study/live/504/1/6?autoplay=1>

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

   

 

posted @ 2022-08-31 12:07  atomxing  阅读(80)  评论(1编辑  收藏  举报