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

tes*_*t11 4 c++ qt cmake qt5

我有以下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)
Run Code Online (Sandbox Code Playgroud)

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

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

相应的目录Debug包含:

MyPtojectLib.dll
MyProjectLib.ilk
MyProjectLib.pdb
Run Code Online (Sandbox Code Playgroud)

was*_*ful 7

您声明MyProjectLib为共享库,因此除非您导出库的全部或部分符号,否则您只能.dll在运行时加载,而不能.lib在编译时链接,因为您正在尝试执行此操作.

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

add_library(MyProjectLib STATIC ...)
Run Code Online (Sandbox Code Playgroud)

另一种选择可能是使用"新"cmake功能导出所有符号(参见本文):

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
Run Code Online (Sandbox Code Playgroud)

您也可以通过明确声明要导出的符号来使用"传统"方式,就像在这个答案中一样(长答案).您首先需要在代码中的某处声明一些API宏:

#ifdef MyProjectLib_EXPORTS
#define MyProjectLib_API __declspec(dllexport)
#else
#define MyProjectLib_API __declspec(dllimport)
#endif
Run Code Online (Sandbox Code Playgroud)

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

class MyProjectLib_API MyClass { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

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})
Run Code Online (Sandbox Code Playgroud)

您可以使用AUTOMOCAUTOUIC不是让cmake自动处理对Qt实用程序的调用.

include_directories (${PROJECT_SOURCE_DIR})
include_directories (${PROJECT_BINARY_DIR})
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)