- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在设置共享库的可见性时遇到问题。我想寻求帮助以解决我的问题,如下所述:
我有一堆源文件,我想将它们构建为共享库:
+Base
|_Parameter
| |_Parameter.h
| |_Parameter_Exception.h
| |_Parameter_Exception.cpp
|_Data
| |_DataInput.h
| |_DataInput_Exception.h
| |_DataInput_Exception.cpp
...
那里还有一些文件,但我认为这不会影响我的问题描述。
我正在使用 CMake 来构建这个 SHARED 库。这是我的 CMakeLists.txt 的一部分,它处理构建库。
project( Base )
cmake_minimum_required(VERSION 3.5
set( Base_HEADERS
Parameter/Parameter.h
Parameter/Parameter_Exception.h
Data/DataInput.h
Data/DataInput_Exception.h
)
set( Base_SOURCES
Parameter/Parameter_Exception.cpp
Data/DataInput_Exception.cpp
)
set( LIBRARY_OUTPUT_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )
add_library( Base SHARED ${Base_SOURCES} ${Base_HEADERS} )
generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${PROJECT_NAME}_Export.h )
此设置构建 libBase.so 共享库没有任何问题。值得一提的是,我设置了一些与可见性相关的标志,以便在链接期间使用:
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -fvisibility=hidden -fvisibility-inlines-hidden" )
如上面部分列出的基本库 CMakeLists.txt 中的配置:
-fvisibility=hidden
)比如一段Parameter_Exception.h:
#include "Base_Export.h"
class SomeException : public std::exception
{
public:
SomeException( void ) {}
...
};
请注意,我没有在此处设置任何可见性属性(通过 Base_Export 中定义的宏)。所以我假设 SomeException 类的符号应该对所有 DSO“用户”隐藏(由于 -fvisibility=hidden
)
但似乎并非如此。不幸的是:
一旦我使用了这个库,虽然符号应该被隐藏,但它的异常是可用的。我预计此代码段“库外”会导致链接失败:
#include "Parameter/Parameter_Exception.h"
...
try
{
...
}
/* THIS SHOULD FAIL IN LINKING DUE TO UNDEFINED SYMBOL, RIGHT? */
catch( const SomeException & e )
{
...
}
我还尝试使用以下命令在 libBase.so 中查找符号:readelf -Ws libBase.so
它列出了非常长的文本:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000008b7e0 0 SECTION LOCAL DEFAULT 9
....
但我在这里注意到的是,在上面的“Vis”列中总是有 DEFAULT 这意味着对我来说默认可见性( __attribute__((visibility("default")))
)但是我希望在那里看到 HIDDEN ( __attribute__((visibility("hidden")))
)
那我做错了什么?还是我的理解不正确?我知道所有链接的标志都正确传播,但似乎没有效果。
CMake 配置脚本列出的我的工具链配置(支持可见性属性的 GCC 版本):
...
-- The CXX compiler identification is GNU 5.3.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
...
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done
-- Generating done
非常感谢任何愿意帮助我的人以及可能遇到与我相同的麻烦的其他人。
再次感谢马丁
最佳答案
CMake 直接支持符号可见性处理,因此您根本不需要触摸 CMAKE_SHARED_LINKER_FLAGS
或 CMAKE_CXX_FLAGS
。您可以像这样设置每个目标的可见性:
set_target_properties(Base PROPERTIES
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN YES
)
然后,CMake 将确保为您添加相关标志。不必为每个目标设置这些属性,通常更方便的是设置关联变量来为所有随后创建的目标设置默认值(这是我通常推荐并在我从事的项目中使用的):
cmake_minimum_required(VERSION 3.5)
project(Base)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
add_library(Base SHARED ...)
当与 GenerateExportHeader
模块(您似乎已经在使用)结合使用时,您不仅可以获得对 gcc/clang 的支持,还可以获得 Visual Studio 的支持,使其成为一个不错的跨平台控制符号可见性的方法。您不需要知道相关的编译器标志或属性,CMake 会为您处理它们并为您提供所有编译器的等效行为。
关于c++11 - DSO 库符号似乎具有默认可见性,但应该是隐藏的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37987474/
我有一个 DSO(mylibrary.so.0 库),带有一个标记为 extern "C" 的 func1 函数,我'我确定它已导出,因为 nm -D mylibrary.so.0 | grep fu
user@pc ~/hiddensymbols % cat main.cpp __attribute__((visibility ("hidden"))) int f_b1(void){ return
我正在学习谷歌测试。我下载了 gtest,运行命令 ./configure 和 make 并以 结束 $ sudo cp -a include/gtest /usr/include $ sudo cp
这个问题在这里已经有了答案: libpthread.so.0: error adding symbols: DSO missing from command line (16 个答案) Linking
假设我正在创建共享对象库 libz.so,其中包含一个头文件(例如 stdio.h)。作为 libc 库一部分的 stdio.h 代码在系统中静态链接。动态链接器如何解析从 DSO 到静态链接的 li
我正在尝试在 linux 下编译 qt ffmpeg 包装器简单编码/解码示例 QTFFmpegWrapper source # Set list of required FFmpeg librari
我遇到了一个令人难以置信的链接器问题。我有两个动态 .so 库,一个定义了 gpr_log(称为 libgpr.so),另一个使用它(称为 libgrpc++.so). 我正在尝试像这样链接一个可执行
我在将某些共享库与 g++ 链接时遇到问题。它给了我一个警告,例如: hidden symbol XXX in YYY is referenced by DSO /usr/lib/... 我已经阅读了
我想构建一个 OpenSSL RSA 引擎,从 this existing source code file 开始这是英特尔实现的一种更快的方法。首先,我想构建这段代码,所以我使用这些命令: gcc
我在设置共享库的可见性时遇到问题。我想寻求帮助以解决我的问题,如下所述: 我有一堆源文件,我想将它们构建为共享库: +Base |_Parameter | |_Parameter.h | |_Para
我尝试使用我的 asr 插件运行 unimrcpserver v1.0,它运行良好(在 Windows 7 上),但是当我尝试在另一台计算机(Windows Server 2003)中运行它时,我收到
我有一个正在运行的服务器(正在将其转变为开发服务器,但首先需要一些东西),所以我们不想重新编译 php 来破坏任何东西。 在新服务器上,我们有 mysql.so 和 mysqli.so 的动态扩展我无
关于包含静态成员变量的 C++ 模板类以及从动态库或共享对象中导出它们的问题很多。但这一个更深一些:如果有多个共享对象,每个共享对象都有自己的一组实例化,但可能使用来自另一个共享对象的实例化,该怎么办
我有一个已经编译/链接的 DSO 文件,它导出了一些确实必须隐藏的函数。当我尝试将我的代码链接到该库时 - 它会选择那些不需要的符号而不是我自己的符号。我无权访问源代码,因此我无法重建二进制文件并为不
我正在尝试通过使用 Cmake 再次编译所有内容,将一个 c++ 项目从 Windows 转换为 Debian。 我不太习惯在 Linux 上工作,但我已经设法正确安装了所有东西。 这是错误: /us
我编译php7如下 ./configure --enable-bcmath --with-bz2 --enable-calendar --enable-exif --enable-dba --enab
我最近试图从第 3 方 DSO 中隐藏一些符号,并遇到了用于创建“过滤器 DSO”的“--filter”LD 选项。来自ld manpage ,我的印象是动态链接器只会考虑过滤器 DSO 的 dyns
我尝试从我的实验室编译一个项目,我使用 ccmake 对原始代码进行的唯一更改是: CMAKE_CXX_COMPILER /usr/bin/clang++ CMAKE_CXX_FLAGS -f
我正在针对我编写的共享库编译程序。该库又依赖于 Boost::program_options(以及其他库)。当我编译我的程序时,我当然需要提及我的库,但是我得到一个 DSO 错误: g++ ism_c
这实际上似乎是一个常见问题,我以为我找到了答案,但由于某种原因它不起作用。我有一个使用 GTK2 库的项目,在第一次编译和链接时,我收到错误“libgtk-x11-2.0.so.0:添加符号时出错:命
我是一名优秀的程序员,十分优秀!