仅在MacOS上发生的奇怪链接错误

Strange linking error that occurs only on MacOS

提问人:CHOOISFOX 提问时间:11/7/2023 最后编辑:CHOOISFOX 更新时间:11/13/2023 访问量:61

问:

因此,我有一个接口库,其中包含单个单例类和另一个使用它的类。

假设它包含以下代码:

signleton.h

struct Singleton {}; //< Singleton (actually it is in different file, but it really doesn't matter)

struct Object
{
public:
    using Instance = std::pair<std::size_t, std::shared_ptr<Singleton>>;

    template <typename T>
    static std::shared_ptr<T> makeSingleton(T value)
    {
        inst = std::make_pair(typeid(T).hash_code(), std::make_shared<T>(value));
        return std::static_pointer_cast<T>(inst.second);
    }
private: 
    static Instance inst;
};

另外,我有 2 个地方想使用它:

  • main.cpp
  • some_other_file.cpp

基本上,是一个可执行文件,并且是另一个链接到可执行文件的库,因此结构如下所示:main.cppsome_other_file.cppmain.cpp

main.cpp包含包含接口“signleton.h”的库some_other_file.cpp

当我尝试在 MacOS 上创建静态实例时(在其他系统上一切正常),出现链接错误。Object::Instancemain.cpp

错误:

Undefined symbol for architecture x86_64:
    "Object::Instance", referenced from:
        some_function_where_it_is_used() in some_other_file.cpp
        ...

我使用的是 2016 年的旧 macbook air,所以这不是与 M1 相关的问题。

我能够通过移动到 来解决此问题,但是由于我想使这个东西更容易找到,所以我想把它保留在 。Object::Instancesome_other_file.cppmain.cpp

此外,我从未弄清楚此问题的主要原因,我想这是关于链接顺序和东西的东西,但我不太确定,因为它只发生在 MacOS 上。

C++ macOS 单一实例 链接器错误

评论

0赞 alagner 11/7/2023
您使用的是哪个 C++ 版本?我要么使用(17 岁以上),要么只是在一个完全独立的文件中初始化。或者你可以用一个静态的 getter 来替换,在它里面返回一个静态变量。static inline Instance inst;instinst
0赞 CHOOISFOX 11/7/2023
@alagner我在 cpp 20 上
0赞 alagner 11/7/2023
然后我会让它内联,如果可能的话,从.cpp中删除初始化:)
0赞 Jesper Juhl 11/13/2023
可能是您链接文件的顺序吗?链接顺序对某些链接器很重要。
0赞 CHOOISFOX 11/13/2023
@jesper-juhl是的,我想过链接顺序,但找不到任何信息,可以证明这个理论:/

答:

0赞 Richard Barber 11/13/2023 #1

macOS 二进制可执行文件必须动态链接。操作系统和工具链根本不支持可执行文件的静态构建。

二进制可执行文件可以动态链接到静态构建的库。

除了内核扩展,但它们不会依赖任何东西,因为它们是独立的块。

参见 https://developer.apple.com/forums/thread/706419