使用cmake和vs2010链接静态boost库而不进行自动链接

3

我得到了一个应用程序,与boost_program_options相关联,其CMakeLists.txt如下:

FIND_PACKAGE(Boost COMPONENTS program_options REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES( ${SUBPROJECT_NAME} ${Boost_LIBRARIES} )

我在包含<boost/program_options.hpp>之前在我的代码中使用#define BOOST_ALL_NO_LIB,以禁用vs2010自动链接boost的功能,因为我想通过cmake指定它以使其与linux兼容。
在Linux中,这段代码可以正常编译(使用cmake、make和gcc)。但在Windows上使用VS2010时,我遇到了一个错误。
2>App.obj : error LNK2001: unresolved external symbol "public: static unsigned int const boost::program_options::options_description::m_default_line_length" (?m_default_line_length@options_description@program_options@boost@@2IB)
2>App.obj : error LNK2001: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > boost::program_options::arg" (?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)

请注意,链接器会找到库文件 - 如果它没有找到,我会得到更多的未解决外部错误。
我追踪问题到以下内容:http://lists.boost.org/boost-users/2009/11/54015.php非常好地描述了正在发生的事情(这两个是全局变量)。现在,那里提出的解决方案是启用动态链接并链接到DLL。但这不是我想做的,我想链接静态的boost库(实际上我正在尝试在VS中的应用程序属性下,在链接器->输入中列出D:\boost\boost_1_47\lib\boost_program_options-vc100-mt-gd-1_47.lib)。
我还尝试添加
set(Boost_USE_STATIC_LIBS        ON)
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF)

我将以下内容添加到我的CMakeLists.txt文件中,但它并没有改变任何东西。

有什么想法来解决这个问题吗?

更新: 当使用boost_program_options-vc100-mt-sgd-1_47.lib进行链接时,我会得到许多新的链接器错误,指出CRT符号已经在boost库中定义。 按照panickal的建议更改VS运行时选项后,这些错误也消失了,现在可以正常工作。


你在find_package调用之前添加了3个set调用吗? - Fraser
当然可以。问题已经解决了,不过还是谢谢你的 :-) - Ela782
1个回答

7
你需要链接静态库。尝试链接到boost_program_options-vc100-mt-sgd-1_47.lib,而不是 boost_program_options-vc100-mt-gd-1_47.lib
其中的s表示库的静态版本。你可以查看Boost Library Naming 获取关于命名约定的更多细节。
更新: 为了解决多个定义的链接器错误,在配置属性/C++/代码生成/运行时库中将Visual Studio Runtime Library选项从Multi-threaded Debug DLL (/MDd)更改为Multi-threaded Debug (/MTd)

2
在Windows上,.dll 用于动态链接。但是,在构建程序时,您将需要链接一个包含所需符号的 .lib 文件。而且,那个 .lib 文件与 静态 .lib 文件不同。 - panickal
你应该只链接一个库。你是不是因为链接了其他库而导致新的“先前定义”的链接错误。 - panickal
我认为我之所以会出现这些新错误,是因为我在某个地方已经包含了这个“C++标准库和编译器运行时支持库”,现在,当我链接到静态链接到这个“C++标准库和编译器运行时支持库”的program_options-vc100-mt-sgd时,我猜测我正在将这个运行时库链接两次,编译器告诉我“错误,来自运行时库的函数xyz已经在program_options_-vc100-mt-sgd中定义,你为什么还要再次链接我?” - Ela782
是的,但是链接到“mt-sgd”库会产生我上面描述的所有新链接器错误! - Ela782
按照这里所述的更改库选项,一切都得到了解决。谢谢! - dk123
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接