【问题标题】:Error LNK1104: cannot open file 'Debug\MyProjectLib.lib'错误 LNK1104:无法打开文件 'Debug\MyProjectLib.lib'
【发布时间】:2021-06-12 21:09:42
【问题描述】:

我有以下CMakeLists.txt 文件来基于Qt 生成我的项目:

cmake_minimum_required(VERSION 2.8.12)
project(MyProject)

find_package(Qt5Widgets)

set(MyProjectLib_src ${PROJECT_SOURCE_DIR}/gui.cpp)
set(MyProjectLib_hdr ${PROJECT_SOURCE_DIR}/gui.h)
set(MyProjectLib_ui  ${PROJECT_SOURCE_DIR}/gui.ui)
set(MyProjectBin_src ${PROJECT_SOURCE_DIR}/main.cpp)

qt5_wrap_cpp(MyProjectLib_hdr_moc ${MyProjectLib_hdr})
qt5_wrap_ui (MyProjectLib_ui_moc  ${MyProjectLib_ui})

include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_BINARY_DIR})

add_library(MyProjectLib SHARED 
    ${MyProjectLib_src}
    ${MyProjectLib_hdr_moc}
    ${MyProjectLib_ui_moc}
)
target_link_libraries(MyProjectLib Qt5::Widgets)

add_executable(MyProject ${MyProjectBin_src})
target_link_libraries(MyProject MyProjectLib)

当我尝试编译生成的项目时,出现以下错误:

错误 LNK1104:无法打开文件 'Debug\MyProjectLib.lib'

对应目录Debug包含:

MyPtojectLib.dll
MyProjectLib.ilk
MyProjectLib.pdb

【问题讨论】:

    标签: c++ qt cmake qt5


    【解决方案1】:

    TLDR:确保您有源文件,而不仅仅是标题!

    对于到达这里并且可能没有 OP 问题的网络搜索者,我刚刚遇到了一个非常相似的链接错误,因为我拆分了库并留下其中一个没有任何源文件,一个仅标头库:

    add_library(hsm STATIC
      StateAbstract.hpp        # header-only
      StateMachineAbstract.hpp # header-only
      StateMachineBase.hpp     # header-only
    )
    

    我的解决方法是插入一个 cpp 文件等待恢复类实现文件:

    add_library(hsm STATIC
      Placeholder.cpp # this file causes hsm.lib to get generated on Windows
      StateAbstract.hpp        # header-only
      StateMachineAbstract.hpp # header-only
      StateMachineBase.hpp     # header-only
    )
    

    这似乎很明显,但我正在这个项目上进行 Linux/QNX 开发,gcc 创建了一个几乎空的库:

    $ wc -c build/lib/libhsm.a 
    8 build/lib/libhsm.a
    $ strings build/lib/libhsm.a
    !<arch>
    

    那个库链接很愉快。直到后来项目在构建服务器上构建 Windows 版本时,我才看到错误:

    [4/6] cmd.exe /C "cd . && C:\PROGRA~2\MICROS~2\2017\COMMUN~1\VC\Tools\MSVC\1413~1.261\bin\Hostx64\x64\link.exe /lib /nologo /machine:x64 /out:build\lib\hsm.lib   && cd ."
    [5/6] ...
    [6/6]  cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe ... /out:build\gtest\hsm_test.exe ... build\lib\hsm.lib ...
    LINK : fatal error LNK1104: cannot open file 'build\lib\hsm.lib'
    

    由于我在构建服务器输出中看到了创建 lib 文件的命令,我最初无法弄清楚为什么 hsm.lib 不存在(并且我无法进入构建服务器)。幸运的是,当我阅读另​​一个答案并三重检查它是否是静态链接时,我注意到它是一个仅限标题的库 - 哇!我感到很幸运!

    【讨论】:

      【解决方案2】:

      您将MyProjectLib 声明为共享库,因此除非您导出库的全部或部分符号,否则您将只有一个设计为在运行时加载的.dll,而没有.lib 可链接在你尝试做的编译时。

      一个快速的解决方案可能是将MyProjectLib 声明为静态库:

      add_library(MyProjectLib STATIC ...)
      

      另一种选择可能是使用“新”cmake 功能来导出所有符号(请参阅this article):

      set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
      

      您还可以通过显式声明要导出的符号来使用“传统”方式,例如this answer(长答案)。您首先需要在代码中的某处声明一些 API 宏:

      #ifdef MyProjectLib_EXPORTS
      #define MyProjectLib_API __declspec(dllexport)
      #else
      #define MyProjectLib_API __declspec(dllimport)
      #endif
      

      请注意,MyProjectLib_EXPORTS 是由 cmake 为共享库自动生成的:您不需要关心这个。然后对于代码中的每个类,在声明中使用宏:

      class MyProjectLib_API MyClass { /* ... */ };
      

      MyClass 将在编译 MyProjectLib 时成为导出符号,因为 MyProjectLib_EXPORTS 将被定义,而 MyProjectLib_API 将扩展为 __declspec(dllexport)。因此它将导出到.lib 文件中。

      链接MyProjectLib 时,它将是一个导入符号,因为MyProjectLib_EXPORTS 将未定义,MyProjectLib_API 将扩展为__declspec(dllimport)


      你也可以像这样改进你的 cmake 文件:

      qt5_wrap_cpp(MyProjectLib_hdr_moc ${MyProjectLib_hdr})
      qt5_wrap_ui (MyProjectLib_ui_moc  ${MyProjectLib_ui})
      

      您可以使用AUTOMOCAUTOUIC 来让cmake 自动处理对Qt 实用程序的调用。

      include_directories (${PROJECT_SOURCE_DIR})
      include_directories (${PROJECT_BINARY_DIR})
      

      PROJECT_SOURCE_DIR 默认是一个包含目录,我不明白你为什么需要在这里添加PROJECT_BINARY_DIR:只需删除这些行。

      清理后,你的 cmake 文件可能会变成这样:

      cmake_minimum_required(VERSION 2.8.12)
      project(MyProject)
      
      set(CMAKE_AUTOMOC ON)
      set(CMAKE_AUTOUIC ON)
      
      find_package(Qt5Widgets)
      
      set(MyProjectLib_src
          ${PROJECT_SOURCE_DIR}/gui.cpp
          ${PROJECT_SOURCE_DIR}/gui.h
          ${PROJECT_SOURCE_DIR}/gui.ui
      )
      
      add_library(MyProjectLib STATIC
          ${MyProjectLib_src}
      )
      target_link_libraries(MyProjectLib Qt5::Widgets)
      
      set(MyProjectBin_src ${PROJECT_SOURCE_DIR}/main.cpp)
      
      add_executable(MyProject
          ${MyProjectBin_src}
      )
      target_link_libraries (MyProject MyProjectLib)
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 2019-10-27
      • 2019-05-14
      • 2015-03-02
      • 1970-01-01
      相关资源
      最近更新 更多