为什么 MSVC 链接器“Microsoft (R) Incremental Linker”(link.exe) 在正确使用 /LIBPATH 标志时忽略传递的库?

问题描述 投票:0回答:1

好吧,我正在经历地狱般的尝试,试图在 Windows 上编译一个在 Linux 上很容易编译的程序,我已将其范围缩小到由 CMake 生成的单个命令,其链接器标志似乎没有执行其应有的操作.

以下是我正在执行的步骤以及出错的地方:

我通过命令行使用 MSVC 编译器,

cl.exe
:

Microsoft (R) C/C++ Optimizing Compiler Version 19.40.33812 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

link.exe

Microsoft (R) Incremental Linker Version 14.40.33812.0
Copyright (C) Microsoft Corporation.  All rights reserved.

 usage: LINK [options] [files] [@commandfile]

<... some more helptext down here ...>

编译一个简单的 C++ 程序,使用 SDL2 显示窗口。这是我确认编译并运行的最小可重现代码:

#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <Windows.h>

using namespace std;

int main(int argc, char **argv) {
    SDL_SetMainReady();

    // Initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        return 1;
    }

    // Create a window
    SDL_Window *window = SDL_CreateWindow("SDL2 Window",
                                          SDL_WINDOWPOS_CENTERED,
                                          SDL_WINDOWPOS_CENTERED,
                                          640, 480, SDL_WINDOW_SHOWN);

    if (window == nullptr) {
        SDL_Quit();
        return 1;
    }

    // Event loop
    bool isRunning = true;
    SDL_Event event;
    while (isRunning) {
        while (SDL_PollEvent(&event) != 0) {
            if (event.type == SDL_QUIT) {
                isRunning = false;
            }
        }
    }

    // Cleanup
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

非常简单,没什么复杂的。


为了编译它,我运行以下命令:

cl main.cpp -I "C:/SDL2/include" /c

将程序编译为

main.obj
/c
标志是为了不链接它。

然后要链接,我运行

link.exe
并将路径传递到我的库,这就是出错的地方。

link.exe main.obj /LIBPATH:C:/SDL2/lib/x86/SDL2.lib

Microsoft (R) Incremental Linker Version 14.40.33812.0
Copyright (C) Microsoft Corporation.  All rights reserved.

main.obj : error LNK2019: unresolved external symbol _SDL_SetMainReady referenced in function _main
main.obj : error LNK2019: unresolved external symbol _SDL_CreateWindow referenced in function _main
main.obj : error LNK2019: unresolved external symbol _SDL_DestroyWindow referenced in function _main
main.obj : error LNK2019: unresolved external symbol _SDL_PollEvent referenced in function _main
main.obj : error LNK2019: unresolved external symbol _SDL_Init referenced in function _main
main.obj : error LNK2019: unresolved external symbol _SDL_Quit referenced in function _main
main.exe : fatal error LNK1120: 6 unresolved externals

没有错误消息,什么都没有,就好像我根本没有通过库(是的,我也尝试过,但同样的错误!)

我尝试在

/VERBOSE
中运行,在搜索了 1,338 行日志后,甚至没有 SDL2.lib 提到。是的,我在提供和不提供 LIBPATH 的情况下都运行了,然后对两个生成的日志进行了差异检查,它们字面上是相同的

奇怪的是,当我像这样运行链接器时:

link.exe main.obj /LIBPATH C:/SDL2/lib/x86/SDL2.lib

有效!它生成了一个 main.exe,运行时按预期显示一个空白的 SDL 窗口。如果您没有注意到,唯一的区别是我删除了冒号

:
并添加了一个空格。

The most beautiful blank window I've ever seen...

(PS:确保在同一文件夹中包含SDL2.dll,以防您自己测试)

因此,由于某种原因,当在没有冒号和空格的情况下传递时,它会按预期工作。然而,微软自己的文档显示以下内容:

Lies

更令人困惑的是,当不带参数运行时,

link.exe
程序会说同样的事情:

/LIBPATH:dir

除非我按照它自己的说明进行操作,否则它不起作用。

所以我的问题是,为什么要这样做?这是一个错误吗?难道是我使用方法不对?

我实际上不是使用

link.exe
的人,实际上是 CMake 生成了对链接器的调用(技术上是正确的)。那么在这种情况下,为什么这个问题还没有得到解决,我可以做些什么来让 CMake 产生正确的输出吗?事实上,我在网上没有找到类似的问题,这表明我做错了什么。

是否有任何解决方法,或者我可以直接不将 CMake 与

link.exe
一起使用吗?

抱歉,如果我听起来有点歇斯底里,我已经坚持了三天,可以感觉到我的理智正在消失

c++ visual-c++ cmake linker linker-errors
1个回答
0
投票

/LIBPATH
选项指定要搜索库的目录,它不包括库本身的名称。库名称与链接器命令的其他输入文件一起给出。

使用给出的示例

link.exe main.obj /LIBPATH:C:/SDL2/lib/x86/SDL2.lib

应该是

link.exe main.obj SDL2.lib /LIBPATH:C:/SDL2/lib/x86

换句话说,

/LIBPATH
的操作方式与gcc的
-L
选项类似。

© www.soinside.com 2019 - 2024. All rights reserved.