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

问题描述 投票:4回答:2

我有以下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
2个回答
5
投票

您将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

请注意,cazke会自动为共享库生成MyProjectLib_EXPORTS:您无需关心这一点。然后,对于代码中的每个类,请使用声明中的宏:

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)

0
投票

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不会存在(并且我无法进入构建服务器)。幸运的是,当我阅读其他答案并三重检查它是静态链接时,我注意到它只是一个标题库 - 哇!我感觉很幸运!

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