英文:
Why is my C++ symbol name different from the libtorrent library I'm linking to and does this cause linking to fail?
问题
我正在尝试将一个简单的C++程序链接到libtorrent
库:
#include <libtorrent/add_torrent_params.hpp>
#include <libtorrent/magnet_uri.hpp>
int main(int argc, char const* argv[])
{
lt::add_torrent_params atp = lt::parse_magnet_uri(argv[1]);
}
我在命令行上调用cl.exe
,但它告诉我有未解析的外部符号:
>cl /EHsc /Fefoo.exe /I<snip>\vcpkg\installed\x86-windows\include main.cpp torrent-rasterbar.lib /link /LIBPATH:<snip>\vcpkg\installed\x86-windows\lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31937 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
Microsoft (R) Incremental Linker Version 14.34.31937.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:foo.exe
/LIBPATH:C:\Users\rages\code\vcpkg\installed\x86-windows\lib
main.obj
torrent-rasterbar.lib
main.obj : error LNK2019: unresolved external symbol "public: __thiscall libtorrent::add_torrent_params::~add_torrent_params(void)" (??1add_torrent_params@libtorrent@@QAE@XZ) referenced in function _main
main.obj : error LNK2019: unresolved external symbol "struct libtorrent::add_torrent_params __cdecl libtorrent::parse_magnet_uri(class boost::basic_string_view<char,struct std::char_traits<char> >)" (?parse_magnet_uri@libtorrent@@YA?AUadd_torrent_params@1@V?$basic_string_view@DU?$char_traits@D@std@@@boost@@@Z) referenced in function _main
foo.exe : fatal error LNK1120: 2 unresolved externals
在torrent-rasterbar.lib
上运行dumpbin /exports
并寻找add_torrent_params
符号,我看到了这个:
??1add_torrent_params@v2@libtorrent@@QAE@XZ (public: __thiscall libtorrent::v2::add_torrent_params::~add_torrent_params(void))
这与编译器报告的非常不同。我怀疑这是导致链接失败的原因,但我不太确定我需要怎样不同的方法来使它工作。我应该如何让我的编译器和库在符号名称上达成一致?
英文:
I'm trying to link a simple C++ program to libtorrent
:
#include <libtorrent/add_torrent_params.hpp>
#include <libtorrent/magnet_uri.hpp>
int main(int argc, char const* argv[])
{
lt::add_torrent_params atp = lt::parse_magnet_uri(argv[1]);
}
I invoke cl.exe
on the command line and it tells me that I have unresolved external symbols:
>cl /EHsc /Fefoo.exe /I<snip>\vcpkg\installed\x86-windows\include main.cpp torrent-rasterbar.lib /link /LIBPATH:<snip>\vcpkg\installed\x86-windows\lib
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31937 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
Microsoft (R) Incremental Linker Version 14.34.31937.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:foo.exe
/LIBPATH:C:\Users\rages\code\vcpkg\installed\x86-windows\lib
main.obj
torrent-rasterbar.lib
main.obj : error LNK2019: unresolved external symbol "public: __thiscall libtorrent::add_torrent_params::~add_torrent_params(void)" (??1add_torrent_params@libtorrent@@QAE@XZ) referenced in function _main
main.obj : error LNK2019: unresolved external symbol "struct libtorrent::add_torrent_params __cdecl libtorrent::parse_magnet_uri(class boost::basic_string_view<char,struct std::char_traits<char> >)" (?parse_magnet_uri@libtorrent@@YA?AUadd_torrent_params@1@V?$basic_string_view@DU?$char_traits@D@std@@@boost@@@Z) referenced in function _main
foo.exe : fatal error LNK1120: 2 unresolved externals
Running dumpbin /exports
on torrent-rasterbar.lib
and looking for the add_torrent_params
symbol shows me this:
??1add_torrent_params@v2@libtorrent@@QAE@XZ (public: __thiscall libtorrent::v2::add_torrent_params::~add_torrent_params(void))
This is very different from what the compiler is complaining about. I suspect this is what's causing the linker to fail, but I'm not quite sure what I need to do differently to make it work. How do I get my compiler and the library to agree on the symbol names?
答案1
得分: 2
这是由于缺少定义引起的。libtorrent的构建页面非常明确:
构建和链接到libtorrent时的一个常见错误是使用一组配置选项(#defines)进行构建,然后使用不同的配置选项进行链接。由于libtorrent的一些代码位于头文件中,如果它们看到不同的配置,这些代码将与构建的库不兼容。
请始终确保在链接到libtorrent时与构建它时定义了相同的TORRENT_*和BOOST_*宏。查看定义的完整宏列表的最简单方法是在b2命令行中添加-n -a开关来构建libtorrent,这将输出所有编译器开关。
因此,我开始调查vcpkg
是如何构建libtorrent的。我能够在$VCPKG_DIR/buildtrees/libtorrent/install-x64-windows-rel-out.log
中找到一些输出,显示了它为每个文件传递给cl
的所有标志。果不其然,传递那里的每个标志都使我的代码编译通过了。
通过逐步排除,我发现TORRENT_NO_DEPRECATE
是使它工作的魔法解决方案。以下是使其编译通过的最低要求:
> cl -DTORRENT_NO_DEPRECATE /nologo /EHsc /Fefoo.exe /IE:\vcpkg\installed\x64-windows\include main.cpp torrent-rasterbar.lib /link /LIBPATH:E:\vcpkg\installed\x64-windows\lib main.cpp
请注意,这仅用于说明解决不匹配符号的特定问题的解决方案。您可能应该使用在vcpkg
日志中找到的完整定义集,以确保不会出现其他头文件引起的意外问题。
英文:
This was caused by a missing define. The libtorrent build page is very clear about this:
> A common mistake when building and linking against libtorrent is to build with one set of configuration options (#defines) and link against it using a different set of configuration options. Since libtorrent has some code in header files, that code will not be compatible with the built library if they see different configurations.
>
> Always make sure that the same TORRENT_* and BOOST_* macros are defined when you link against libtorrent as when you build it. The simplest way to see the full list of macros defined is to build libtorrent with -n -a switches added to b2 command line, which output all compiler switches.
So I began investigating how vcpkg
was building libtorrent. I was able to find some output at $VCPKG_DIR/buildtrees/libtorrent/install-x64-windows-rel-out.log
which showed me all the flags that it was passing to cl
for each file. Sure enough, passing every single flag there got my code to compile.
By a process of elimination, I found that TORRENT_NO_DEPRECATE
is the magic sauce that makes it work. Here's the bare minimum you need to get it to compile:
> cl -DTORRENT_NO_DEPRECATE /nologo /EHsc /Fefoo.exe /IE:\vcpkg\installed\x64-windows\include main.cpp torrent-rasterbar.lib /link /LIBPATH:E:\vcpkg\installed\x64-windows\lib main.cpp
Please note this is just for illustrating a solution to the specific issue of mismatched symbols. You should probably use the full set of defines found in the vcpkg
log to make sure there are no surprises down the road from other headers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论