__attribute__ ((weak)) 在 clang 和 gcc 中的处理不同

use*_*059 5 c++ macos gcc clang

我有一个应用程序(app)和一个动态库/共享对象(dlib),两者都链接到一个静态库,该库使用__declspec (selectany)/在头文件中声明一个全局变量(gvar)__attribute__ ((weak))。按照设计,app 和 dlib 都应该有自己的 gvar 副本(在 MSVC 和 GCC 上我完全明白)。

移植到 Mac OSX 并使用 clang 编译后,我看到 dlib 中的 gvar 链接到 app 中的 gvar。不确定这是一个叮当声错误还是设计使然;如果是设计使然,有没有办法避免它并获得与 GCC/MSVC 相同的行为?

叮当版:

bash-3.2$ c++ --version
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)

重现问题的最小项目:

主.cpp:

#include <stdio.h>
#include <dlfcn.h>

__attribute__ ((weak)) int g_global = 10;

int main ()
{
    printf ("main (): g_global: addr = %p; value = %d\n", &g_global, g_global);

    typedef void Foo ();

    void* so = dlopen ("./my-so.so", RTLD_LAZY | RTLD_LOCAL);
    Foo* foo = (Foo*) dlsym (so, "foo");
    foo ();
}
Run Code Online (Sandbox Code Playgroud)

共享.cpp:

#include <stdio.h>

__attribute__ ((weak)) int g_global = 20;

extern "C" void foo ()
{
    printf ("foo (): g_global: addr = %p; value = %d\n", &g_global, g_global);
}
Run Code Online (Sandbox Code Playgroud)

构建.sh:

#!/bin/bash

rm -f my-so.so
rm -f app.

c++ -shared -fPIC shared.cpp -omy-so.so
c++ main.cpp -oapp -ldl
Run Code Online (Sandbox Code Playgroud)

输出:

bash-3.2$ ./app
main (): g_global: addr = 0x10c657030; value = 10
foo (): g_global: addr = 0x10c657030; value = 10
Run Code Online (Sandbox Code Playgroud)

请注意,如果我删除属性((weak)),那么 app 和 dlib 将获得自己的 gvar 副本。

use*_*059 2

我在这里找到了答案: https: //gcc.gnu.org/wiki/Visibility

为了获得我想要的行为,我必须添加-fvisibility=hidden到命令行并添加__attribute__ ((visibility ("default")))到需要导出的符号。