c++ - 使用 Clang、libc++ 和 c++11 制作 SFML2 应用程序。对 SFML 库的 undefined reference

标签 c++ c++11 sfml libc++ clang++

我在制作 SFML2 应用程序时遇到了一个奇怪的问题。我使用存储库中的 Clang++ 以及 libc++(均于今天更新)。 SFML2 也从 SVN 存储库进行了更新。我正在使用最新版本的 Kubuntu。当我大约一个月前上次尝试使用当时最新的存储库时,我也遇到了同样的问题。

我传递给 c++11 和 stdlib 编译器的参数是:-std=c++11 -stdlib=libc++

这是我所调用的完整版本:

clang++ -std=c++11 -stdlib=libc++ main2.cpp -o main -L/home/jonathan/OpenSource/sfml/SFML-Build/lib/ -I/home/jonathan/OpenSource/sfml/SFML/include/ -lsfml-system -lsfml-window -lsfml-graphics -v

当我尝试编译应用程序时,我收到来自 Clang 的链接错误:

/tmp/main2-stOJMp.o: In function `main':
main2.cpp:(.text+0x108): undefined reference to `sf::Window::create(sf::VideoMode, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned int, sf::ContextSettings const&)'

应用程序(当前)所做的就是创建一个 RenderWindow。这只是一个测试应用程序,但对于我使用的大多数 SFML2 函数,都会存在一些像这样的链接问题。如果我不使用 libc++,程序编译得很好。

据我所知,如果我包含 -stdlib=libc++,它不会在 SFML2 lib 文件夹中搜索要正确链接的 SFML2 库。

当我使用 -v 命令通过 Clang 进行调用时,这是 ld 调用:

"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/home/jonathan/OpenSource/sfml/SFML-Build/lib/ -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. -L/lib -L/usr/lib /tmp/main2-kOZbfN.o -lsfml-system -lsfml-window -lsfml-graphics -lc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o

如果我不使用 -stdlib=libc++...

"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o main /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L/home/jonathan/OpenSource/sfml/SFML-Build/lib/ -L/usr/lib/gcc/x86_64-linux-gnu/4.6 -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. -L/lib -L/usr/lib /tmp/main2-2IOIxv.o -lsfml-system -lsfml-window -lsfml-graphics -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o

所以,以防万一我让人们感到困惑:如果我将 libc++ 与 Clang 一起使用,我会从第一个 ld 调用中得到上述错误。如果我不使用它,第二个 ld 调用会完全正常,并且应用程序会成功运行。

我使用 libc++ 的原因是因为我想使用 C++11 中的线程。如果没有它,我的计算机上的 GNU C++ 标准库就会出现大量错误。我不会为此发布错误列表,因为它很大并且与此问题无关。

有人知道我如何解决 SFML2 问题吗?如果不需要,我宁愿不使用 pthreads 库。

最佳答案

SFML2 库已针对 libc++ 以外的某些 C++ 库(也许是 libstdc++?)进行编译。要更正,请使用 -stdlib=libc++ 重新编译 SFML2,并确保链接器在将 SFML2 链接到您的应用程序时看到 -stdlib=libc++。

调试此问题的关键是注意链接器正在寻找带有 std::__1 符号的 sf::Window::create 。 libc++ 用 std::__1 来破坏东西。但其他 std::libs 仅使用 std 来破坏事物。这是一项安全功能,可防止您意外地混合来自两个不同 std::lib 的 std::string 并最终导致运行时错误而不是链接时错误。

关于c++ - 使用 Clang、libc++ 和 c++11 制作 SFML2 应用程序。对 SFML 库的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11996792/

相关文章:

.net - 需要使用 .NET 支持复制 IDispatch*;不知道类(class)名称

c++11 有时会包含 <cstdlib> 而 c++03 不会?

c++ - 更快地解析代码文件

cmake - CMake EXTERNALPROJECT_ADD 与 Git 存储库的正确用法是什么?

c++ - 将数组的所有元素初始化为C++中的一个默认值?

c++ - 减少 Wasm 文件大小(libc、优化、emscripten)

c++ - 类型安全的可变参数函数

c++ - 调整窗口大小时移动了灯光着色器

c++ - C++ SFML 中的抽象类错误

c++ - 带节点删除函数的链表问题