首页 > 系统相关 >c++ linux 学习第二课

c++ linux 学习第二课

时间:2023-06-16 23:12:24浏览次数:42  
标签:文件 gcc 第二课 LD c++ LIBRARY linux PATH 加载

c++ linux 学习第二课

一、GCC的工作流程:

gcc编译器将C源文件到生成一个可执行程序中间一共经历四个步骤:

二、gcc常用参数:

-v 版本

-E 生成预处理文件

-S 生成汇编文件

-c 只编译,生成目标文件 .o文件

-I(大写的 i ) 指定头文件所在的路径

-L 指定库文件所在的路径

-l(小写的 L) 指定库的名字

-o指定生成目标的名字

-g包含调试信息,使用gdb调试必须要加-g参数

-On  n=0~3 n越大优化等级越高

-Wall 提示更多警告信息

-D 编译时指定宏  例如:gcc -o test test.c -D MAX=10    或者   gcc -o test test.c -DMAX=10

 

三、静态库和动态库(共享库)

(头文件和库的区别:头文件一般而言是申明和定义,包含了库函数的声明,库文件是已经编译好的二进制代码,包含了库函数的代码实现)

【如果没有引用需要的头文件:函数未声明

如果没有库文件:找不到函数定义】

静态库:是在可执行程序运行前就已经加入到执行代码中,成为可执行程序的一部分。(可执行程序生成后把静态库文件删除没有影响)

静态库的命名:前缀lib   库名称 自定义,例如test   后缀 .a      最终组成 libtest.a

静态库的制作:

1.将.c文件编译成.o文件

  gcc -c fun1.c fun2.c

2.使用ar命令将.o文件打包成.a文件 (在使用ar工具的时候需要添加参数rcs)

  命令:ar rcs 静态库名  .o文件们

  ar rcs libtest1.a fun1.o fun2.o 

静态库的使用:

  gcc -o main main.c -I./ -L./ -ltest1    (-L指定系统去哪里寻找这个静态库)

 

动态库的制作和使用:

共享库在程序编译时并不会被连接到目标代码中,在程序运行时才被载入。如果不同的可执行程序调用了相同的库,那么内存里只需要有一份该共享库的拷贝

共享库的制作:

  (1) 将.c文件编译成.o文件

  gcc -fpic -c fun1.c fun2.c

  【-fpic 产生位置无关代码(position-independent code),则产生的代码中没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存中的任意位置,都可以被正确的执行。共享库被加载时,在内存中的位置不是固定的】

  (2) 使用gcc将.o文件编译成库文件

  gcc -shared fun1.o fun2.o -o libtest2.so

上面的(1)和(2)可以合成一步:gcc -fpic -shared -o libtest2.so *.c

共享库的使用:

  gcc -o main2 main.cpp -I./ -L./ -ltest2

动态库加载遇到的问题及解决:

运行上面的程序后发现报错了:

./main2: error while loading shared libraries: libtest2.so: cannot open shared object file: No such file or directory

ldd加载器,使用ldd加载刚刚生成的main2可执行文件,发现:libtest2.so not found

下面动态库not found的解决方法:

分析:当系统加载可执行代码的时候,能够知道其所依赖库的名字,但是还要知道所依赖的库的绝对路径。  此时就需要系统动态载入器(dynamic linker/loader)【作用是把库加载到内存中】。 

动态库没有被编译到可执行程序main2中,所以环境中必须提供相应的库地址,这就是出现上述问题的原因,也就是解决方法的入口。

 

  -->ldd命令可以查看可执行文件依赖的库文件,执行ldd main2,就可以发现libtest2.so找不到。

  

解决方法:

1. 【不推荐 不要用】第一个方法是把生成的共享库复制到系统根目录的/lib目录下,这样程序就能够找到动态链接库了,但是会污染系统目录,不要用这种方法。

2. 【临时设置,个人简单测试时可以使用】linux 提供了" LD_LIBRARY_PATH "这样一个环境变量,用来告诉加载器去哪里搜索库。使用下面的命令把环境变量设置为当前目录,然后就能够执行了。

export LD_LIBRARY_PATH="."  //此外 这样设置的搜索路径优先于/lib目录,先去设置的路径查找
//此外,这个设置是临时的,当终端退出重进后就会失效,换一个窗口也不能执行
echo $LD_LIBRARY_PATH 命令可以查看上述设置是否生效

 3. 【永久设置,常用】把export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径,设置到~/.bashrc文件中,然后执行下列方法之一使配置文件生效:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库路径  这样写是在原有值之后追加,不会覆盖原有值。

  ⚪执行. ~/.bashrc 使配置文件生效,第一个.后面有空格

  ⚪执行source ~/.bashrc使配置文件生效

  ⚪退出当前终端,再次登录也可以使配置文件生效

/lib 和/usr/lib 是系统目录,不要把自己制作的库文件随便放到里面

更改用户级别的配置文件,(不要更改系统级别的配置文件) 

 其他补充:

 

标签:文件,gcc,第二课,LD,c++,LIBRARY,linux,PATH,加载
From: https://www.cnblogs.com/yz-lucky77/p/17477157.html

相关文章

  • C++面试八股文:在C++中,你知道哪些运算符?
    C++面试八股文:在C++中,你知道哪些运算符?某日二师兄参加XXX科技公司的C++工程师开发岗位第11面:面试官:在C++中,你都知道都哪些运算符?二师兄:啥?运算符?+-*/=这些算吗?面试官:嗯,还有其他的吗?二师兄:当然还有,+=,-=,*=,/=,==,还有逻辑运算,位运算等。面试官:好的。那你知道这些运算......
  • C++通讯录管理系统[2023-06-16]
    C++通讯录管理系统[2023-06-16]通讯录管理系统手机通讯录中的联系人的信息既可以存储在手机中,也可以存储在手机卡中,也可以同时存储在两个位置上(假设每个位置上的存储容量为1000,即手机卡中或手机上最多只能存储1000个联系人)。存储在手机中的联系人的信息只包含姓名和电话号码两项......
  • 大数据学习--虚拟机Linux系统安装使用
    大数据学习推荐使用CentOS系统,于是在虚拟机上安装这个程序。   接下来复制三个,  ......
  • c++一些零碎记录
    c++11alignasstructalignas(8)S{}//定义结构体同时指定分配给结构体的大小为8字节alignof(与内存对齐相关)structobj{chara;intb;}alignof(obj)=4;//alignof(obj)=4表示对于obj,其内存对齐是以多少字节为单位对齐对于单个变量char其alignof(char)=1,单个字节对齐......
  • 对C++中const的说明
    对C++中const的说明在C++中,const是一个关键字,用于指定对象或变量是只读的,即不可修改。它可以应用于不同的上下文中,包括:对象和变量声明:通过在变量或对象的声明前加上const关键字,可以将其标记为只读。这意味着一旦被初始化,就不能再修改该对象或变量的值。constintx=10;//声明一......
  • Linux 使用交叉编译工具链编译boost
    参考:Boost交叉编译执行./bootstrap.sh后,会生成project-config.jam。修改project-config.jam文件:#if!gccin[feature.values<toolset>]#{#usinggcc:;#}if!gccin[feature.values<toolset>]{usinggcc::/cross-tools/aarch64-poky-linux-gcc--sysro......
  • Linux项目流程 + 用git将本地代码上传到gitee
    目录前言 一个"进度条"项目git上传代码首次上传代码 安装git  克隆仓库连接 将文件传入路径目录文件上传三板斧后续提交更新git实用用法补充前言 本文将介绍如何使用makefile编写项目并将其上传到git远程仓库。Makefile是一种用于自动化构建、编译和测试软件项目的工具,它可以......
  • C++ multi process share value via write and read data from serialized file,the b
    #include<atomic>#include<chrono>#include<cmath>#include<condition_variable>#include<cstddef>#include<forward_list>#include<fstream>#include<functional>#include<future>#include<iom......
  • Linux中-bash: /dev/null: Permission denied问题解决
    云上架构2021年08月06日09:19 ·  阅读682​今天在Centos7上运行如下命令 shell复制代码######添加hdfs用户#####useraddhdfs######切换至hdfs用户#####su-hdfs报如下错误 javascript复制代码-bash:/dev/null:Permissiondenied-bash......
  • 1.新手学习Linux 操作命令
     ......