使用 Cmake 和 Visual Studio 2013 的未解析外部

Unresolved Externals using Cmake and Visual Studio 2013

提问人:AdmiralJonB 提问时间:1/31/2015 更新时间:1/31/2015 访问量:4246

问:

我在使用 cmake 和 Visual Studio 2013 与 SFML 时遇到了问题。当我尝试编译我的程序时,我得到了使用 SFML 的所有内容的未解析外部问题。我在多台机器上遇到了这个问题,在某些情况下也遇到了其他一些库的问题。

我正在使用以下命令生成我的 Visual Studio 项目(在 VisualStudioProject 文件夹中):

Z:/Coding/cmake/cmake-3.1.1-win32-x86/bin/cmake.exe -G “Visual Studio 12” ..

这是我的CMakeLists.txt(它实际上是从我编写的python脚本生成的,但我怀疑这很重要)。我可以确认所有库都已正确找到。

cmake_minimum_required (VERSION 2.6)

set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib )

project(Game)

include_directories( Z:/Coding/Libraries/SFML/SFML-2.2/include Z:/Coding/Game/src/win32 Z:/Coding/Game/src )

find_library( SFML-GRAPHICS NAMES sfml-graphics PATHS Z:/Coding/Libraries/SFML/SFML-2.2/lib NO_DEFAULT_PATH )
find_library( SFML-WINDOW NAMES sfml-window PATHS Z:/Coding/Libraries/SFML/SFML-2.2/lib NO_DEFAULT_PATH )
find_library( SFML-SYSTEM NAMES sfml-system PATHS Z:/Coding/Libraries/SFML/SFML-2.2/lib NO_DEFAULT_PATH )

add_executable( win32 "Z:/Coding/Game/apps/win32.cpp" )
target_link_libraries( win32 ${SFML-GRAPHICS} ${SFML-WINDOW} ${SFML-SYSTEM} )

这是我简单的SFML测试程序:

#include <string>
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

int main(int argc, char *argv[])
{
    sf::RenderWindow window;
    window.create(sf::VideoMode(1280, 1024), "Test");

    while (true)
    {
        sf::Event ev;

        while (window.pollEvent(ev))
        {
            if (ev.type = sf::Event::EventType::Closed)
            {
                window.close();
                exit(1);
            }
        }
    }

    std::string hello = "Hello";
    cout << hello << endl;
}

我收到了以下未解决的外部问题:

错误 1 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: __thiscall sf::String::String(char const *,class std::locale const &)” (__imp_??0String@sf@@QAE@PBDABVlocale@std@@@Z) 在函数中引用 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 2 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: __thiscall sf::String::~String(void)” (__imp_??1String@sf@@QAE@XZ) 在函数中引用 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 3 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: __thiscall sf::VideoMode::VideoMode(unsigned int,unsigned int,unsigned int)” (__imp_??0VideoMode@sf@@QAE@III@Z) 函数中引用 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 4 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: void __thiscall sf::Window::create(class sf::VideoMode,class sf::String const &,unsigned int,struct sf::ContextSettings const &)” (__imp_?create@Window@sf@@QAEXVVideoMode@2@ABVString@2@IABUContextSettings@2@@Z) 在函数中引用 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 5 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: void __thiscall sf::Window::close(void)“ (__imp_?close@Window@sf@@QAEXXZ) 引用 在函数 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 6 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: bool __thiscall sf::Window::p ollEvent(class sf::Event &)” (__imp_?pollEvent@Window@sf@@QAE_NAAVEvent@2@@Z) 引用于 函数 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 7 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public: __thiscall sf::RenderWindow::RenderWindow(void)” (__imp_??0RenderWindow@sf@@QAE@XZ) 函数中引用 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 8 错误 LNK2019:未解析的外部符号 “__declspec(dllimport) public:虚拟__thiscall sf::RenderWindow::~RenderWindow(void)” (__imp_??1RenderWindow@sf@@UAE@XZ) 在函数中引用 _main Z:\Coding\Game\VisualStudioProject\win32.obj win32

错误 9 错误 LNK1120:8 未解决 外部 Z:\Coding\Game\bin\Debug\win32.exe win32

我过去曾在 Windows 上使用过相同风格的脚本,并成功地使用了早期的 VS(至少我记得我有过),所以我认为这是 VS 2013 的新事物,但我完全被难住了。

提前致谢。

注意:这是一个简单的示例。这种样式的CMakeLists.txt是由脚本生成的,因为它使用的主要代码库非常大(最初是基于Linux的,因此为什么'/'在任何地方都使用)。

C++ visual-studio-2013 cmake SFML 未解析外部

评论


答:

2赞 KidneyChris 1/31/2015 #1

在黑暗中刺伤:

尝试跑步

Z:/Coding/cmake/cmake-3.1.1-win32-x86/bin/cmake.exe -G “Visual Studio 12 2013 Win64”

这将强制它在 64 位环境中执行所有链接。我假设您使用的是 64 位计算机。我进一步假设您有 64 位版本的 SFML。(这是未来,我认为这些都是安全的假设)。

CMake 会尝试根据 http://www.cmake.org/cmake/help/v3.0/generator/Visual%20Studio%2012%202013.html 选择一个“合理”的默认值但有时你想强制它选择正确的选项。

评论

1赞 Fraser 1/31/2015
+1 但我认为如果您不在生成器中指定或传递命令行,CMake 将始终默认为 win32。Win64-Ax64
0赞 AdmiralJonB 1/31/2015
看来你是对的。谢谢,但另一个答案读起来更好一些。
0赞 KidneyChris 1/31/2015
我同意@Fraser的答案读起来更好。据推测,他们实际上知道自己在做什么,而不是我的“呃,这可能是一个 64 位链接问题”:-)
6赞 Fraser 1/31/2015 #2

这看起来您实际上没有成功链接三个 SFML 库中的任何一个。

如果CMakeLists.txt中的调用找不到库,那么CMake将输出一个致命错误,我相信你会提到。find_library

因此,我最好的猜测是,您正在尝试链接 SFML 库的 64 位版本,而您的 CMake 命令指定了 32 位版本。

要创建 64 位版本,只需运行:

cmake -G "Visual Studio 12 Win64" ..

您需要清空构建文件夹才能将生成器从 更改为 。"Visual Studio 12""Visual Studio 12 Win64"

有关 VS 生成器的详细信息,请参阅文档

评论

0赞 AdmiralJonB 1/31/2015
看来你是对的。谢谢。这将是对我的构建脚本的有趣更改......