C++_动态链接库和搜索共享库

标准

1998	C++98
2011	C++11  ISO/IEC 14882:2011	
2014	C++14
2017	C++17
2020	ISO C++ 委员会正式发布了C++20 标准,命名为 ISO/IEC 14882:2020		

实现

01.命令查看自己的g++编译器默认的c++版本
   g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
02.g++命令编译cpp文件的时候其实也可以指定c++标准,例如直接指定C++17的标准  相比于正常的命令只是多了一个命令行参数-std=c++17  
	g++ -std=c++17 test.cpp -o test.o
03.系统的g++有哪些
    ls /usr/bin/ |grep g++	
	
04切换版本--gcc和g++同时切换
   查看当前的gcc/g++是否是通过update-alternatives管理的,查看其链接方式
       ll /usr/bin/gcc*
       ll /usr/bin/g++*
	直接链接的
  # 切换gcc的版本
  sudo update-alternatives --config gcc
  
  # 切换g++的版本
  sudo update-alternatives --config g++	

动态库

制作-生成链接库	  
使用链接库
搜索链接库
   "Linux下的库有动态与静态两种,
   动态通常用.so为后缀,静态用.a为后缀
   Windows 下.DLL是动态链接库, .LIB是静态链接库
   动态库与静态库的区别动态库个编译好的程序,程序运行时可以直接调用其中的函数, 不参加工程的编译.
   而静态库应该说是一个程序集, 只是把一些相应的函数总结在一起, 如果调用静态库中的函数,
   在编译时,这些调用的函数都将参加编译静态库必要的目标代码的是在对程序编译的时候被加入到程序中,
   而运行时不再需要.a的库了而动态库,则是在运行时转载从内存管理的角度来看。">	

共享搜索库

  01.默认情况下, /etc/ld.so.conf  文件中包含有默认的共享库搜索路径
       /etc/ld.so.conf.d/
  02.第二种,通过LD_LIBRARY_PATH环境变量
   可以通过在.bashrc或者.cshrc中配置该环境变量,
     LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库. 可以设置多个搜索目录, 这些目录之间用冒号分隔
  03.,通过编译选项-Wl, -rpath指定动态搜索的路径 -Wl选项告诉编译器将后面的参数传递给链接器。
  
 具体解释:
  01. ldd  list-dynamic-dependencies 命令查看可执行程序的链接库
     ldd 不会列出依赖树,如果想要依赖树,用 lddtree(apt install pax-utils)
	    ldd 未必会显示所有依赖的库(不包含用 ldopen() 函数直接从代码中加载的,因为很有可能会根据用户输入来加载,无法预判)
     ldd可以列出一个程序所需要得动态链接库(so)
	 “=>” 左边 表示该程序需要连接的共享库之 so 名称,
	 “=>” 右边 表示由 Linux 的共享库系统找到的对应的共享库在文件系统中的具体位置
	可执行模块的dependency的工作原理,其实质是通过ld-linux.so(elf动态库的装载器)来实现
	ld-linux.so.2是glibc的库文件,一般链接到相应版本的ld-xxx.so上,是和动态库载入有关的函数
	通过动态编译链接的,当一个 需要动态链接 的应用被操作系统加载时,系统必须要 定位 然后 加载它所需要的所有动态库文件。 
	在Linux环境下,这项工作是由ld-linux.so.2来负责完成的,
   
   ld-linux.so.2 man page给我们更高一层的全局介绍, 它是在 链接器(通常是ld)在运行状态下的部件,
   用来定位和加载动态库到应用的运行地址(或者是运行内存)当中去。
   
   ldconfig 命令的用途, 主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下
   :ldconfig,配置文件目录:/etc/ld.so.conf.d,配置文件在/etc/ld.so.conf内容由用户编辑,缓冲文件/etc/ld.so.cache
   
 02.-Wl pass comma-separated to the linker  
   
   运行时动态库 not found。即使在使用-L和-l参数使得成功编译,在运行时仍然可能会找不到库,因为运行时库的搜索路径可能并没有包含-L的目录。
   第一种方法:找到缺少的动态库(由于编译和链接时候的使用到了这个动态库,所以很容易找得到),将其加到/lib,/usr/lib中的一个文件夹下,这几个文件夹是系统默认的搜索路径。将库文件放置在其中,运行时就可以搜索到了( /lib  /usr/lib )。
   第二种方法:设置临时增加链接动态库的路径;export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:[your lib]
   第三种方法:/etc/ld.so.cache中缓存了动态库路径,可以通过修改配置文件/etc/ld.so.conf中指定的动态库搜索路径,然后执行ldconfig命令来改变。
   第四种方法:在链接时语句后面添加如下命令:-Wl,-rpath=[your lib] 。其中-WI是gcc参数,-rpath是ld参数
       (从 GCC5.4 左右开始)-Wl,-rpath 设置的变为 runpath 而不是 rpath.二者唯一区别在于动态库搜索路径顺序.一般并不推荐使用 rpath.

制作-生成动态链接库

g++ 生成动态链接库
 
CMake如何生成动态链接库文件
  CMakeLists.txt
    SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
    ADD_LIBRARY(filename SHARED ${CURRENT_SOURCES} ${CURRENT_INCLUDE})
    运行完成之后可以在库文件的输出目录看到libfilename.so文件。
配置阶段解析所有的输入变量,并存储在CMakeCache.txt这个文件。这个阶段解决了用户构建一个项目需要依赖的各种输入参数
解析器使用了lex/yacc 语法解析器-antlr4 ,执行构建动作-解析器Parser生成。解析器的匹配器找到各种token
    CMake找到头文件, include_directories(/home/include
	     找到库文件   link_directories
		 链接库文件   target_link_libraries
		生成
           add_library	  指定的源文件生成链接文件
		       SHARED库会被动态链接(动态链接库),在运行时会被加载。MODULE库是一种不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数
           add_executable			   

使用动态链接库

 .a 文件是 static library, 在编译的时候一起编入可执行文件
   -o 的作用是给生成的可执行文件命名, -L 的作用是声明 .a 所在的目录, -l 是指明所用的 .a 文件,
  
gcc/g++来链接的时候一样,要使用 -L 来指定第三方库所在路径。
     cmake可以使用  LINK_DIRECTORIES 命令来指定第三方库所在路径	


find_package 和 find_library 指令可以得到库文件的绝对路径

动态库的添加:
  link_directories(${PROJECT_SOURCE_DIR}/lib) #添加动态连接库的路径
  target_link_libraries(project_name -lmxnet ) #添加libmxnet.so
  
  
  静态库的添加:
  add_library(mxnet STATIC IMPORTED)
  set_property(TARGET mxnet PROPERTY IMPORTED_LOCATION /path/to/libmxnet.a)
  target_link_libraries(project_name mxnet ) #添加libmxnet.a

其他

ln 命令用于给文件创建链接,根据 Linux 系统存储文件的特点,链接的方式分为以下 2 种:软连接和硬链接	
   s:建立软链接文件。如果不加 "-s" 选项,则建立硬链接文件;
   权限位中"l"表示这是一个软链接文件;其次,在文件的后面通过 "->" 显示出源文件的完整名字。所以软链接比硬链接的标志要明显得多
 ll

python的搜索路径和pip

 Python  where python
 PYTHONPATH 是Python中一个重要的环境变量,用于在导入模块的时候搜索路径,通过访问Pythonpath可以看到,
  路径列表的第一个元素为空字符串,代表的是相对路径下的当前目录
  搜索路径
  PYTHONPATH 是 python查找模块和包的路径,每导入一个模块,python解释器将依次在PYTHONPATH 下寻找
  可以通过 sys.path 来查看 PYTHONPATH 的具体内容
     1、添加环境变量 PYTHONPATH,python会添加此路径下的模块,在.bash_profile文件中添加如下类似行:
      export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.7/site-packages
     2、在site-packages路径下添加一个路径配置文件,文件的扩展名为.pth,内容为要添加的路径即可
         如果本来python就没有添加上site-packages目录,那第二个方法其实也是用不了的。
     3、sys.path.append()函数添加搜索路径,参数值即为要添加的路径。
       import sys
       sys.path.append('/Users/username/Documents/')	 
 pip 安装路径
     apt-get install -y pip-python3       (python3.x就去安装pip3)
       pip list   (2) pip freeze 第二种还会显示出库的版本号和路径
	 
   升级pip--已有pip的前提下
    在线的方式

    离线的方式
      01.下载wheel  https://pypi.org/project/pip/#files
	  02.上传到离线的jiqi
	  03.执行 pip install
	  
安装open3d遇到的问题
   pip 安装open3d,不要安装open3d-python  python版本与open3d匹配问题
   pip版本问题-升级pip版本 pip版本和python匹配问题
      open官网查询得知, 3.6 3.7 3.8 3.9版本的python支持open3d
	  
环境变量	说明
  PYTHONSTARTUP	在交互式启动时执行的文件(无默认值)
  PYTHONPATH	‘:’ - 以默认模块搜索路径为前缀的分隔目录列表。结果是sys.path。
  PYTHONHOME	交替的 <prefix> 目录 (或者 <prefix>:<exec_prefix>). 默认的模块搜索路径为 <prefix>/pythonX.X.
  PYTHONCASEOK	忽略import语句中的大小写(Windows)。
  PYTHONIOENCODING	用于 stdin/stdout/stderr 中的编码
  PYTHONHASHSEED	如果此变量设置为random,则效果与-R选项相同:使用一个随机值为str,bytes和datetime对象的哈希值设定种子。它也可以设置为 [0, 4294967295] 范围内的整数,以获得具有可预测种子的哈希值。

参考

https://github.com/cplusplus/draft/tree/c++20		
posted @ 2022-12-07 10:29  辰令  阅读(144)  评论(0编辑  收藏  举报