目录
2 我的问题
2.2 解决措施2:-W1,--exclude-libs,ALL
2.3 疑问:可见性设置的覆盖问题
某项目中因为使用到了不同版本库的问题,因此整理下GCC的符号可见性问题,方便自己以后再次使用。
1 -fvisibility=default|internal|hidden|protected
GCC的visibility属性用来控制符号表的可见属性,举例子说明一下
1.1 __attribute__((visibility("default"))) 与 CXX=g++ -fvisibility=hidden 的作用
如果我在编译库的makefile中增加了CXX=g++ -fvisibility=hidden,那么意思就是这个库中的这些函数对外都是隐藏的,除非我再某个函数声明前面增加了__attribute__((visibility("default")))用来说明这个函数的可见性保持默认。
这样写的作用是什么,就是我可以隐藏库里面的绝大多数接口,只开放某几个特定的接口,这样避免应用程序引用多个库时导致冲突。
1.2 __attribute__((visibility("hidden"))) 与 CXX=g++ -fvisibility=default的作用
有了前面的分析,这个的作用也很明显,就是我隐藏库中的某几个特定的函数,开放绝大多数接口。
2 我的问题
我的问题现在有一个程序,然后它需要用到两个算法库1.so 2.so,但是由于某些原因1.so和2.so使用了不同的opencv库版本。那么这时候主程序就会包含两个不同版本的opencv库就会产生一些错误。
2.1 解决措施1:静态编译opencv + 使用-fvisibility=hidden
现在的解决措施是,我不动态编译opencv,而是将opencv静态编译成.a库,并且在编译opencv库的时候里面增加-fvisibility=hidden,由于算法库是静态链接opencv库的,所以即便opencv里面它使用了-fvisibility=hidden隐藏了接口也没事他还是能找到opencv库里面的接口的(如果动态编译opencv库并且使用了-fvisibility=hidden,那么算法库就找不到opencv库里面的接口了)。
2.2 解决措施2:-W1,--exclude-libs,ALL
-W1,--exclude-libs,ALL:这些都是链接器的选项,用于控制链接过程。看一下他们的作用:
-
-Wl
:这个选项告诉编译器将后面的参数传递给链接器。在你的例子中,-Wl
后面跟着的是,--exclude-libs,ALL
,这个参数会被传递给链接器。 -
--exclude-libs
:这是一个链接器选项,用于指定在链接过程中排除某些库。在你的例子中,--exclude-libs
后面跟着的是ALL
,这意味着链接器会排除所有的库。 -
ALL
:这是--exclude-libs
选项的参数,表示排除所有的库。当链接器看到这个参数时,它会把所有的库都标记为隐藏,这样在链接生成的.so文件时,这些库中的符号就不会被导出。
总的来说,-Wl,--exclude-libs,ALL
这个选项的作用是在链接过程中隐藏所有库中的符号。这可以防止库中的符号被导出,从而避免符号冲突。这对于创建动态库(如.so文件)非常有用,因为它可以帮助你控制哪些符号应该被公开,哪些符号应该被隐藏。
2.3 疑问:可见性设置的覆盖问题
参考文献:
https://cumtchw.blog.csdn.net/article/details/125676653