Linux中gcc的编译、静态库和动态库的制作

3 篇文章 0 订阅
订阅专栏

gcc是文本编译器,就是编译代码的工具,下面介绍gcc编译C语言(.c文件)的流程。

1 gcc的编译过程

1.1 gcc的编译过程

在这里插入图片描述

gcc的编译分为以下四个阶段:

  • gcc预处理器:把.c文件编译成预处理.i文件
  • gcc编译器:把预处理.i文件编译成.s的汇编文件
  • gcc汇编器:把.s汇编文件编译成.o二进制文件
  • gcc链接器:把.o二进制文件链接成一个可执行文件

四个阶段的编译命令:

  • 预处理:gcc -E hello.c -o hello.i
  • 编译:gcc -S hello.i -o hello.s
  • 汇编:gcc -c hello.s -o hello.o
  • 链接:gcc hello.o -o hello

上面的四个过程也可以用一个命令执行,直接生成可执行的文件:

gcc hello.c -o hello
# 或
gcc hello.c    # 没有指定输出问价名,默认是生成一个a.out可执行文件。

注意:

1、记忆参数可以用ESc-o参数是指定输出文件的名字
2、在windows下,如果gcc hello.c,默认生成的可执行文件为a.exe;如果gcc hello.c -o myapp,会直接生成可执行文件myapp.exe,自动添加后缀。
3、在第二阶段把预处理.i文件编译成.s汇编文件浪费时间
4、即使是直接生成可执行文件,但是也是经过了预处理编译汇编链接这些过程,只是没有生成中间的这些文件。


四个阶段的具体功能:

  • 预处理:1)把.c文件中的头文件展开添加到.i预处理文件的开头;2)然后把.c文件代码添加到.i的头文件内容之后;3)把宏定义的量值替换为具体的值,去掉原代码中的注释

  • 编译:把c文件翻译汇编文件,就是两种程序语法的转化。

  • 汇编:把汇编文件编程二进制文件,此时的文件已经看不出具体的内容。

  • 链接:将函数库中相应的代码组合到目标文件中。

1.2 gcc的常用参数

下面具体实例:

一、执行文件和头文件同级目录

1、创建一个sum.c文件,内容如下:

#include <stdio.h>
// 双引号导入的头文件是自己写的
#include "head.h"
#define DEBUG

// main是入口函数
int main(void)
{
    int a = NUM1;
    int aa;
    int b = NUM2;
    int sum = a + b;
    // 这是一个加法运算
#ifdef DEBUG
    printf("The sum value is : %d + %d = %d\n", a, b, sum);
#endif
    return 0;   
}

2、在sum.c的同级创建head.h头文件,内容如下:

#ifndef __HEAD_H_
#define __HEAD_H_

#define NUM1 10
#define NUM2 20
#endif

两个文件的层级结构,同级目录:

├── head.h
├── sum.c

3、预处理:gcc -E sum.c -o sum.i

执行完之后用vi sum.i查看预处理之后sum.i内容,如下:

在这里插入图片描述

从文件中可以看到,文件内容很长,之前的导入的头文件,被替换为具体的头文件代码内容,代码中的宏定义量被替换为具体的值,代码中的注释去掉。(相当于做菜食材的准备阶段)

4、编译:gcc -S sum.i -o sum.s

编译就是把预处理的.i文件编译成.s的汇编语言,编译之后的sum.s内容,如下:

在这里插入图片描述

从文件中可以看出,这个文件显示的已经不是C语言编写的代码,已经被转换为汇编语言的代码,如果你对单片机了解,你可能也对汇编语言的语法有所了解。(编译:就是把C语言翻译成汇编语言

5、汇编:gcc -c sum.s -o sum.o

汇编就是把汇编文件变成二进制文件,汇编之后的sum.o内容,如下:

在这里插入图片描述

从文件中可以看出,汇编成二进制文件之后,里面的内容已经看不出来了。

6、链接:gcc sum.o -o sum

使用gcc链接器二进制文件链接成一个可执行文件,将函数库中相应的代码组合到目标文件中。通过./sum即可执行该可执行文件,执行结果如下:

在这里插入图片描述

如果你打开可执行文件sum,显示的内容和sum.o差不多。

二、执行文件和头文件同级目录

目录层级结构:

├── include
│   └── head.h
├── sum.c

如果直接编译(gcc sum.c -o sum),会提示找不到头文件,如下:
在这里插入图片描述

找不到头文件有两种解决方法:

  • 直接在程序编写的时候指定头文件的位置
  • 在编译的时候用-I参数,指定头文件所在的文件夹位置

gcc sum.c -I ./include -o sum

三、gcc的其他参数使用

1、参数-D:指定一个宏定义

上面的程序中有printf()打印程序调试的log信息,但是程序发布的时候,我们是不需要这些log信息的,当然我们可以通过加调试的#define DEBUG宏的声明,但是,程序中需要调试输出的log信息比较多的时候,这种方法显然不合适。

现在我们把DEBUG的宏定义注释掉

#include <stdio.h>
// 双引号导入的头文件是自己写的
#include "head.h"
//#define DEBUG

// main是入口函数
int main(void)
{
    int a = NUM1;
    int aa;
    int b = NUM2;
    int sum = a + b;
    // 这是一个加法运算

// 程序有 DEBUG宏定义,程序才会执行prinf()
#ifdef DEBUG
    printf("The sum value is : %d + %d = %d\n", a, b, sum);
#endif
    return 0;   
}

然后再执行:

>>>gcc sum.c -o sum
>>>./sum

结果:

并不会输出print打印的信息了,如果再次打印出信息呢,此时可以通过参数-D,在执行命令的时候给程序指定一个宏,如下:

>>>gcc sum.c -o sum -D DEBUG
>>>./sum

此时就可以打印出printf()信息了。

总结:

-D参数的作用:不在程序中定义宏,在程序编译的时候定义。不指定,在程序预处理的时候,printf()就会被删掉了。

2、-O参数:程序预处理的时候对代码优化

在程序预处理的时候对代码进行优化,把冗余的代码去掉,有三个优化等级:

  • -O1:优化等级低
  • -O2:优化等级中
  • -O3:优化等级高

举个例子:

int a = 10
int b = a
int c = b
int d = c

# 优化完之后就是
int d = 10  // 就是对d的一个赋值操作

3、-Wall参数:输出程序中的警告信息

例如我们在程序中定义一个变量int aa;,但是没有使用,此时就会输出警告信息。

4、-g参数:在程序中添加一些调试信息

gcc sum.c -o sum -g

  • -g参数之后,输出的可执行文件会比不加的大(因为包含调试信息)
  • 程序发布是不需要加-g参数
  • 调试需要加-g参数,否则没有调试信息不可以调试。(gdb调试的时候必须加此参数

总结:
在这里插入图片描述
参数:-E-S,不是很重要,-c比较重要,后面我们在制作静态库和动态库的时候需要用到生成的.o二进制值文件

2 gcc 静态库的制作

比如你和别人做项目合作,你不可能直接把源代码给别人,那样别人就可以自己开发,因为源代码就是你的核心技术。你不应该卖给他源代码,而是应该是程序,这样你就可以根据他有什么需求进行改或添加什么功能模块等,就可以改一次就可以收费一次,这样就可以有一个长期合作。

那应该给到客户的是什么呢?

  • 生成的库
  • 头文件

这样把生成的库头文件给客户也能够使用,只是他不知道里面具体怎么实现的。这样二者才能维持一个长期的合作

头文件对应的.c文件都被打包到了静态库动态库里面了。

2.1 静态库的制作流程

一、静态库的制作

1、命名规则

  • 1)lib + 库的名字 + .a
  • 2)例如:libmytest.a

2、制作步骤:

  • 1)生成对应的.o二进制文件 .c --> .o eg:gcc sum.c -c sum.o
  • 2)将生成的.o文件打包,使用 ar rcs + 静态库的名字(libMytest.a) + 生成的所有的.o
  • 3)发布和使用静态库:
    • 发布静态库
    • 头文件

说明:

  • .c文件,也就是源代码转化成.o二进制文件之后,客户就不知道到你的核心技术具体是怎么实现的了。
  • ar是对.o的二进制文件进行打包rcs是打包参数,把所有.o二进制文件打包成一个.a文件,即:静态库。因此:静态库是一个打包了二进制文件的集合
  • 接口API是在头文件中体现出来的。

实例:

目录结构:

Calc
├── include
│   └── head.h
├── lib
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mul.c
    └── sub.c

说明:

  • include文件夹:存放头文件,提供给用户调用的接口API
  • lib文件夹:存放库文件,即:生成的静态库、动态库
  • src文件夹:存放源文件
  • main.c程序:是用户调用head.h头文件里面的接口,然后在调用静态库里面我们实现的算法(只不过已经不是源码,而是被编译成二进制文件)

下面开始吧:

源代码 src/add.c实现的是加法运算:

#include "head.h"

int add(int a, int b)
{
    int result = a + b;
    return result;
}

头文件 include/head.h实现是对源代码调用的接口API

#ifndef __HEAD_H_
#define __HEAD_H_
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
#endif

main.c是对头文件调用,然后调用静态文件,对算法的使用,但是并不知道算法的具体实现源代码

#include <stdio.h>
#include "head.h"

int main(void)
{
    int sum = add(2, 24);
    printf("sum = %d\n", sum);
    return 0;
}

用户在main.c中引入头文件#include "head.h",即在./include/head.h,就可以使用./include/head.h中定义的接口int add(int a, int b);,当main.c程序执行到add(int a, int b);接口时,就会到./src文件夹下找静态文件(打包的二进制文件——即:加法算法的具体实现)


下面是具体的制作流程:
在这里插入图片描述

shliang@shliang-vm:~/shliang/gcc_learn/Calc$ tree
.
├── include
│   └── head.h
├── lib
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mul.c
    └── sub.c

3 directories, 6 files
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ cd src
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ls
add.c  div.c  mul.c  sub.c

1、源代码生成二进制文件(.o文件)
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ gcc *.c -c -I ../include
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ls
add.c  add.o  div.c  div.o  mul.c  mul.o  sub.c  sub.o

2、对生成的二进制文件(.o文件),打包成静态文件(.a文件),并移动到lib目录下
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ar rcs libMyCalc.a *.o
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ls
add.c  add.o  div.c  div.o  libMyCalc.a  mul.c  mul.o  sub.c  sub.o
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ mv libMyCalc.a ../lib
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ cd ..
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ ls

3、调用include目录下的头文件(即:封装的API接口)
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ gcc main.c lib/libMyCalc.a -I ./include -o sum
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ ls
include  lib  main.c  src  sum
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ ./sum
sum = 26
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ 

主要:

  • 制作好的静态文件要放到lib目录下
  • 调用头文件中的接口API,然后用gcc编译的自己调用的main.c文件,需要加上静态文件(.a文件)
  • 程序发布的时候只需要给用户的文件:
    • 1)include目录下的头文件(head.h):封装的是具体算法实现的接口API
    • 2)lib目录下的静态文件(.a文件):是源代码编译的之后的二进制文件(.o文件),然后被打包成静态文件(.a文件)

用于另外一种调用静态库的方法为:

gcc main.c -Iinclude -L lib -l MyCalc -o myapp

在这里插入图片描述

参数说明:

  • -I参数:指定头文所在的文件夹名,文件夹名可以和参数贴着写在一起
  • -L参数:指定静态库的文件夹名
  • -l参数:指定静态库的名字,但名字要掐头去尾,eg:原静态库名字为libMyCalc.a,在指定-l参数值的时候为:-l MyCalc
  • -o参数:输出编译之后可执行文件的名字

注意:

之所以用-l指定静态库的名字,是因为lib目录下可能有多个静态库文件,但是我们只需要使用其中的某一个,此时可以用这种方法指定相应的静态库文件。

二、静态库相关文件查看

1、nm命令查看静态库

可以使用nm命令查看静态库文件中具体打包了哪些二进制文件.o文件

在这里插入图片描述

2、nm命令查看生成的可执行文件

在这里插入图片描述

T:代表的含义是把add代码会被放到代码区

2.2 静态库的优缺点

1、通过静态库生成可执行文件

在这里插入图片描述

  • 静态库中封装了多个.o文件
  • main.c 中调用静态库中相应可执行文件(二进制文件)中的函数
  • 图中只调用了add.o和sub.o中的函数,因此main.c在生成可执行文件的时候只会把静态文件中的add.osub.o两个文件打包到可执行文件中,静态文件中的其他没有用到的.o文件不会被打包进可执行文件中。
  • 在生成可执行文件的时候也是以.o可执行文件单位打包的,并不会把整个静态文件.a都打包到可执行文件中。

静态库的优点:

  • 1)发布程序的时候,不需要提供对应的库了,因为库已经被打包到了可执行文件中去了。
  • 2)库的加载速度比较快,因为库已经被打包到可执行文件中去了。

静态库的缺点:

  • 1) 库被打包到应用程序(最后生成的可执行文件)中,如果库很多的话就会导致应用程序的体积很大。
  • 2)库发生了改变,需要重新编译程序,如果源代码比较多,可能编译一遍一天就过去了。

3 gcc 动态库 / 共享库 的制作

动态库也叫共享库,在windows中对用.dll文件

3.1 动态库 / 共享库的制作流程

一、动态库相关说明

1、命名规则:

  • 1)lib + 名字 + .so
  • 2)例如:libMyCalc.so

2、制作步骤:

  • 1)生成与位置无关的代码 (生成与位置无关的.o)
  • 2)将.o打包成共享库(动态库)
  • 3)发布和使用共享库:

注意:

  • 静态库生成的.o文件是和位置有关的
  • gcc生成和位置无关的.o文件,需要使用参数-fPIC(常用) 或 -fpic

二、动态库制作相关实例

在了解什么叫生成和位置无关的.o文件,我们来先了解一下虚拟地址空间
在这里插入图片描述

linux上打开一个运行的程序进程),操作系统就会为其分配一个(针对32位操作系统)0-4G的地址空间虚拟地址空间),虚拟地址空间不是在内存中,而是来自硬盘的存储空间。

从下到上:

0-3G:是用户区

  • .text 代码段:存放的是代码
  • .data :存放的是已初始化的变量
  • .bss:存放的是未初始化的变量
  • 堆空间:
  • 共享库:动态库的空间,每次程序运行的时候把动态库加载到这个空间
  • 栈空间:我们定义的局部变量都是在栈空间分配的内存
  • 命令行参数
  • 环境变量

在往上 3-4G是内核区

  • 静态库生成与位置有关二进制文件(.o文件)

虚拟地址空间是从0开始的,生成的二进制文件(.o文件)会被放到代码段,即.text代码区。生成的.o代码每次都被放到同一个位置,是因为使用的是绝对地址

  • 动态库生成与位置无关二进制文件(.o文件)

动态库 / 共享库 在程序打包的时候并不会把.o文件打包到可执行文件中,只是做了一个记录,当程序运行之后才去把动态库加载到程序中,也就是加载到上图中的共享库空间,但是每次加载到共享库空间的位置可能不同
还是和上面静态库制作同样的目录结构:


动态库制作实例

Calc
├── include
│   └── head.h
├── lib
├── main.c
└── src
    ├── add.c
    ├── div.c
    ├── mul.c
    └── sub.c

在这里插入图片描述

shliang@shliang-vm:~/shliang/gcc_learn/Calc$ cd src/
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ls
add.c  div.c  mul.c  sub.c

1、把源码生成和位置无关的二进制文件
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ gcc -fPIC -c *c -I ../include
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ls
add.c  add.o  div.c  div.o  mul.c  mul.o  sub.c  sub.o

2、使用gcc把生成的二进制文件(.o文件),打包成动态库(.so文件)
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ gcc -shared -o libMyCalc.so *o -Iinclude
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ ls
add.c  add.o  div.c  div.o  libMyCalc.so  mul.c  mul.o  sub.c  sub.o

3、把生成的动态库文件移动到lib目录下
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$  mv libMyCalc.so ../lib
shliang@shliang-vm:~/shliang/gcc_learn/Calc/src$ cd ..
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ ls
include  lib  main.c  src
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ 

参数说明:

  • -PIC:生成和位置无关的.o文件
  • -shared:共享,就是把.o文件,打包成动态库 / 共享库

上面就已经完成动态库的制作,然后把下面的两个文件发布用户即可调用

  • include/head.h: 头文件,定义接口API
  • lib/libMyCalc.so:动态库,封装了编译之后的源代码二进制文件

用户使用动态库

用户使用动态库和静态库一样有两种方法:

  • 用户使用动态库方法一:

gcc main.c lib/libMyCalc.so -o app -Iinclude

在这里插入图片描述

  • 用户使用动态库方法二:

gcc main.c -Iinclude -L lib -l MyCalc -o myapp

在这里插入图片描述

3.2 动态库查找不到解决方法

我们可以看到,第二种方法,至执行可执行程序的时候,提示找不到动态库,这并不一定是动态库文件不存在,可能是由于链接不到

是不是真的链接不到,我们可以通过一个命令ldd:查看可执行文件执行的时候,依赖的所有共享库/动态库(.so文件)

ldd命令使用:

ldd 可执行文件名

在这里插入图片描述

shliang@shliang-vm:~/shliang/gcc_learn/Calc$ ldd myapp 
	linux-vdso.so.1 =>  (0x00007fff59d26000)  # 后面的数字是库的地址
	# 提示我们自己的动态库 / 共享库 libMyCalc.so没有找到
	libMyCalc.so => not found
	# libc.so.6 是linux下的标准C库 (写C程序都会调用标准C库里的一些函数)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1e27462000)
	# 动态链接器,动态链接器的本质就是一个动态库
	/lib64/ld-linux-x86-64.so.2 (0x00007f1e2782c000)
shliang@shliang-vm:~/shliang/gcc_learn/Calc$ 

在这里插入图片描述

如上图:可执行程序./a.out在执行的时候,调用需要调用动态库libmytest.so,但是实际上这个调用是通过动态链接器的来调用的。动态库就是通过动态链接器--/lib64/ld-linux-x86-64.so.2 加载到我们的可执行程序(应用程序)中的。

那么动态链接器是-- /lib64/ld-linux-x86-64.so.2 是通过什么规则查找可执行文件在执行时,需要的动态文件的呢?

其实就是通过环境变量

在linux下查看环境变量:

echo $PATH

在这里插入图片描述

当然PATH下并不是存放动态库的路径,这里只是做一个演示,如何查看环境变量。

一、动态库查找不到解决方法一(不推荐——不允许使用

把自己制作的动态库放到根目录下的系统动态库中,即/lib目录下

sudo cp ./lib/libMyCalc.so /lib

在这里插入图片描述
从上面的结果可以看到,把自己制作的动态库拷贝到系统动态库中之后,动态链接器根据环境变量就可以找到这个动态库,然后正确加载到可执行程序中。

注意:

这种方法一般不会使用的,因为如果你的动态库的名字和系统中某个动态库的名字一样,就可能会导致系统奔溃的!!!这里只是做一个演示,证明动态链接器是根据环境变量去查找要加载的动态库。

二、动态库查找不到解决方法二(临时测试设置

通过把动态库添加到动态库环境变量中,即:LD_LIBRARY_PATH

在这里插入图片描述

使用export添加环境变量,把当前动态库所在的位置(文件夹位置)添加到LD_LIBRARY_PATH变量中,可执行程序在执行的时候会在默认的动态库之前从LD_LIBARAY_PATH变量中查找有没有所需动态库。

# export
export LD_LIBARAY_PATH=./lib

注意:

但是,这种方法只是临时的,当我们关闭终端,下次再执行程序又会提示找不到动态库。因此,这钟方法一般是再开发动态库的过程中,用于临时的测试

三、动态库查找不到解决方法三(永久设置——不常用

当前用户家目录home)下的.bashrc文件中配置LD_LIBRARY_PAHT环境变量。

cd ~
vi .bashrc

# 然后再最后一行添加一个环境变量,如果没有就创建(Shift+G跳到最后一行)
# 然后把动态库的绝对路径赋值给该变量
export LD_LIBARAY_PATH=/home/shliang/shliang/gcc_learn/Calc/lib

# 保存退出,用source激活配置,如果不激活需要重启终端,因为终端每次重启都会从.bashrc中加载一次配置
source .bashrc

在这里插入图片描述

上面添加完环境变量之后就可以找到动态库了。

在这里插入图片描述

四、动态库查找不到解决方法四(永久设置

这种方法,相对与前三种复杂一些,一定要掌握,可能以后用作中用到的就是这种。做法如下:

1、需要找到动态连接器配置文件/etc/ld.so.conf
2、把我们自己制作的动态库目录的绝对路径写到配置文件中
3、更新配置文件:sudo ldconfig -v

  • ld:dynamic library 动态库的缩写
  • -v :是更细配置文件的时候输出更新信息。

修改配置文件的路径位置:/etc/ld.so.conf

/home/shliang/shliang/gcc_learn/Calc/lib添加到/etc/ld.so.conf配置文件中

之后就可以找到动态库了,如下:

在这里插入图片描述

3.3 动态库的优缺点

1、动态库的优点

  • 执行程序的体积小:程序在执行的时候采取加载动态库,并没有和可执行程序打包在一起
  • 动态库更新了,不需要重新编译程序(不是绝对的,前提是函数的接口不变,内容便里没事)

2、动态库的缺点

  • 程序发布的时候,需要把动态库提供给用户
  • 动态库没有被打包到应用程序中,加载速度相对较慢

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述
♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠

Linux 如何使用gcc生成静态库动态库
03-13
Linux 如何使用gcc生成静态库动态库,使用GCC编译生成静态库动态库的方法
Linux操作系统】GCC编译静态库动态库制作详解
热门推荐
Goforyouqp的博客
08-08 1万+
本文详细介绍了GCC编译过程以及如何制作静态库动态库。通过预处理、编译、汇编和链接四个阶段,我们可以将源代码转换成可执行文件或者库文件。静态库将多个目标文件打包成一个文件,程序在编译时会将静态库的代码复制到可执行文件;而动态库是在程序运行时被加载的库文件,它可以被多个程序共享使用,减少了内存的占用。
【c语言】gcc编译动态库静态库和使用说明
最新发布
hutaotaotao的博客
04-20 707
c语言gcc编译动态库静态库和使用说明
GCC编译步骤、动态库静态库的创建和使用、ELF库简介及查看方法
sjsnsnsnsi的博客
10-05 2843
通过上面的操作,发现一个高级语言程序,通过预处理、编译、汇编之后生成了main.o目标文件的ELF格式文件,这到底是一种怎样的文件格式呢?ELF是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件的文件格式。一个ELF文件一般由四个部分组成:ELF header里面存放着很多整体分布的信息,如文件类型、版本信息等;描述的是一个段在文件的位置、大小以及它被放进 内存后所在的位置和大小;Section将文件分成一个个节区,每个节区都有其对应的功能,如.text 用于存放机器码;
GCC如何生成并调用静态库
xuxu_123_的博客
05-31 1877
本文主要介绍了如何生成静态库,以及如何调用静态库的方法,供参考。欢迎一起交流讨论~
gccgcc编译动态库(共享库)、静态库|链接静态库动态库
小鱼菜鸟的博客
10-04 5305
目录 即看即用 一、GCC 简介 GCC编译流程 GCC编译选项 二、GCC生成动态库静态库 三、生成动态库静态库实例 四、静态库动态库的使用和配置 静态库的使用 共享库的使用 不到你指定链接的so错误 编译链接静态库动态库 链接动态库 即看即用 多个源文件/目标生成动态库 a. gcc -fPIC -shared ...
GCC编译过程,静态库动态库
weixin_43787492的博客
11-25 2335
LinuxGCC编译过程
GCC
weixin_34234721的博客
10-09 310
一、简介: gcc 最初是 "GNU C Compiler" 的简称,只是当作一个 C 语言的编译器,现在已经变成了 "GNU Compiler Collection",可以编译多种语言。     二、编译的四个阶段: 在使用 gcc 编译程序时,编译过程可以被细分为 4 个阶段: ◆ 预处理(Pre-Processing) ◆ 编译(Compiling) ◆ 汇编(Assembl...
Linux静态库动态库制作
01-09
静态库:在编译阶段加载(将库文件的代码加载到源文件) 动态库:在运行时加载 3.生成可执行文件存在的区别(优缺点) (1)使用静态库生成的可执行文件大于动态库生成的可执行文件(程序占用的内存较多) (2)使用...
GCC 编译使用动态链接库和静态链接库的方法
12-31
根据链接时期的不同,库又有静态库动态库之分。 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。 有别于静态库,动态...
Linux下g++编译与使用静态库动态库的方法
01-20
在windows环境下,我们通常在IDE如VS的工程开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库(*.a)与动态库(*.so)的生成...
Linux静态库动态库
01-20
Linux下,库分为静态库和共享库。   库的生成 静态库:库名:Libxxx.a,lib是库的前缀,xxx是库名,.a为静态库的后缀。 第一步:将需要生成静态库的.c文件转换为编译后的.o文件 命令:gcc -S mian.o mian.c 第二步...
GCC 生成静态库
bianyu1hao的博客
09-15 824
最近需要在ubuntu环境下利用GCC生成静态库(static library:.a file),就学习了一下实现过程。 我安装的是以下版本: gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2?revis
gcc生成静态库.a和动态库.so
阿布巴的博客
10-08 2127
gcc生成静态库.a和动态库.so一、用gcc生成静态库动态库1、 hello实例2、实例一3、实例二二、总结三、参考资料 一、用gcc生成静态库动态库 1、 hello实例 2、实例一 3、实例二 二、总结 三、参考资料 ...
gcc编译与交叉编译(x86 to arm) (二)编译静态库动态库
qq_41104439的博客
05-17 1800
编译过程如下图,g++开头的是使用本地gcc编译,aarch64-linux-gnu-g++开头的是交叉编译成arm版本,最后提示“可执行文件格式错误”,就是因为它交叉编译生成的arm架构,在x86上自然不能执行,我们也可以。四个程序文件:main.c、function.h、greeting.c name.c。用例程序文件跟静态库一样,命令如下。
gcc编译C++程序
weixin_30360497的博客
07-07 174
gcc动态编译和静态编译方法 一.单个源.cpp文件生成可执行程序下面是一个保存在文件 helloworld.cpp 一个简单的 C++ 程序的代码: 1 /* helloworld.cpp */ 2 #include <iostream> 3 int main() 4 { 5 std::cout << "hello, world" ; ...
gcc编译动态库静态库
weixin_51281362的博客
06-24 2831
gcc常见选项和动态库静态库
linux静态库编译与使用
计算机视觉算法开发与落地
12-29 2345
linux静态库编译与连接
Linux系统编程】Linux下的编译器——gcc/g++的使用 及 动态库静态库的认识
m0_70980326的博客
07-12 1676
学习Linux下的编译器——gcc/g++,认识什么是动态库静态库
Linux创建静态库.a和动态库.so
06-06
Linux ,可以使用以下命令创建静态库 .a: ```bash gcc -c file1.c file2.c ar rcs libsample.a file1.o file2.o ``` 这将在当前目录创建一个名为 libsample.a 的静态库,其包含 file1.c 和 file2.c 的编译结果。 要创建动态库 .so,可以使用以下命令: ```bash gcc -shared -o libsample.so file1.c file2.c ``` 这将在当前目录创建一个名为 libsample.so 的动态库,其包含 file1.c 和 file2.c 的编译结果。注意,在创建动态库时,需要使用 -shared 选项告诉编译器生成一个共享库,并且不需要使用 -c 选项。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 解决git下载出现:Failed to connect to 127.0.0.1 port 1080: Connection refused拒绝连接错误 194483
  • MP4视频测试URL地址,亲测有效 194088
  • 如何将本地文件通过终端上传到linux服务器 /服务器/阿里云 162038
  • linux上杀死进程命令:kill、pkill、killall杀死进程 137619
  • 解决ModuleNotFoundError: No module named ‘numpy.core._multiarray_umath‘ 错误 125694

分类专栏

  • 1—Python学习 64篇
  • 人脸检测与人脸识别 4篇
  • 自动驾驶 14篇
  • 相机和激光雷达标定 11篇
  • 20-ROS 4篇
  • 2—ML(machine learning)机器学习 5篇
  • 3—DL(deep learning)深度学习 46篇
  • 4—图像处理算法和数学理论 13篇
  • 5—Linux学习 59篇
  • 6—DP(data processing)数据处理 10篇
  • 7—Proj(Project)项目笔记 17篇
  • 8—Use(use)软件、包、工具等的安装及使用 86篇
  • 9—opencv-python、Pillow图像处理 32篇
  • 10—C++学习 3篇
  • 11—Net(Inernet)网络服务 8篇
  • 13—windows系统有关 26篇
  • 15_人脸检测、人脸识别 4篇
  • 16_各种错误和bug(你的痛,我的痛,痛痛痛) 70篇
  • 18—np、pd、plt的使用 4篇
  • 19—目标检测 7篇

最新评论

  • Intel深度摄像头RealSense D435(实感双目摄像头)和目标检测结合使用

    梦想几度重生: 为什么我同时获取红外和深度图的时候,红外图就好像是深度图拉远一些出来的结果,但是分辨率都是调整的640 480,怎么才能让图像都是一个画幅大小对齐呀

  • 这次彻底解决:windows上拔掉U盘或移动硬盘时,弹出:该设备正在使用中,请关闭可能使用该设备的所有程序或窗口,然后重试。

    Hdamao: 请问你最后怎么解决

  • Intel深度摄像头RealSense D435(实感双目摄像头)和目标检测结合使用

    海洋里的一滴水: 这个所谓的深度信息,是点到相机基线的垂直距离,而不是实际的直线距离,还需要更具内外参数计算点的坐标从而计算实际的距离吧。

  • 基于平面的约束2D激光雷达和相机的联合标定(2D Laser and Camera Calibration )原理及项目代码具体使用——旷视

    m0_55629185: 你好,我也是这样的问题,请问您解决了吗?

  • 目标检测使用LabelImg标注VOC数据格式和YOLO数据格式——LabelImg使用详细教程

    小小小小小小小白.: 重装qt库解决

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • 2024年预告
  • 加入bing体验chatGPT大军中来吧,它来了!
  • 在Edge浏览器中登录微软账户报错:0x80190001错误
2024年1篇
2023年2篇
2022年19篇
2021年74篇
2020年110篇
2019年192篇
2018年70篇

目录

目录

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

聚圣源免费八字起名字测试打分结果周易免费起名测名起名带金旁的字有哪些男孩瑞字起名6park.com龙宝宝的起名大全正是江南好风景存折查询校服的裙摆校园修神录2.5属鼠宝宝怎么起名字跳楼死序列号英文物业管理公司起名大气好听的一生一世分集剧情介绍给小老鼠起名字鸡公煲加盟尤文图斯老板女友在线起名大全免费测试女儿好听的郑姓 起名田姓猪宝宝起名压缩文件怎么加密期刊起名夏空的英仙座男人不醉他是人间妄想全文夜雨何时听萧瑟春太与千夏将军家的小娘子免费观看姓李的男孩起名字淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费

聚圣源 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化