c++ - 使用 CMake 编译带有链接 dll 的应用程序。需要查看工作示例

标签 c++ dll cmake compiler-errors

已找到答案。为了节省您大量阅读的时间:

这里有用的文档:
https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/Exporting-and-Importing-Targets

工作的 CMakeLists.txt 是这样的:

cmake_minimum_required(VERSION 3.10)
project(Test VERSION 1.0)
add_library(Lib SHARED IMPORTED)
set_property(TARGET Lib PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/lib.dll")
set_property(TARGET Lib PROPERTY IMPORTED_IMPLIB "${PROJECT_SOURCE_DIR}/lib.dll.a") //Notice: lib.lib here if you are using VS building system.
add_executable(App app.cxx)
target_link_libraries(App Lib)

大多数在线教程都会假设您使用的是 MS VS 构建系统。因此他们会一直谈论导入“*.lib”文件。
如果你像我一样使用GCC(MinGW),你要寻找的实际文件是“*.dll.a


9月17日编辑
不,这是不对的。我们使用的是 DLL。并且DLL不应该影响编译。
DLL 应该在您想要将它们放入 .exe 所需的文件夹中而不是编译检查 header 时使用。
但我们正在尝试从 dll 中解压 header 。
这个工作流程一定有问题。

CMake 和 GCC
由于我公司没有许可证,我无法使用任何 IDE 或 VS Build Tool。
因此我必须学习 CMake + GCC 以获得开源编译环境。
我现在可以正确编译应用程序和静态库。但卡在dll链接中。
这应该是一个简单的问题,但由于我在 Google 上找不到任何示例,因此我需要您的帮助来纠正此 DLL 链接作业中的 CMake 工作流程。谢谢。

或者可能是任何可以找到正确方向的超链接。
据我所知,我可以简单地将 dll 库添加到 VisualStudio 等 IDE 中,它会发挥所有作用,将其交换为包含头文件的内容。 我一定错过了 CMake 中的这一部分。

我的步骤:

  1. 编译dll
  2. 编译不带 dll 的旧版应用
  3. 使用从 dll 链接的函数重新创建应用(BOOM!)

详细代码如下:


第1步:编译dll

Test.h 中的代码:

#pragma once
#ifdef TEST_EXPORTS
    #define TEST_API __declspec(dllexport)
#else
    #define TEST_API __declspec(dllimport)
#endif
extern "C" TEST_API int helloworld();

Test.cxx 中的代码:

#include <iostream>
#include "Test.h"
int helloworld() {
    std::cout << "I hate HelloWorld\n";
    return 0;
}

CMakeLists.txt 中的代码:

cmake_minimum_required(VERSION 3.10)
project(Test)
include(GenerateExportHeader)
add_library(Test SHARED Test.cxx)
generate_export_header(Test)

编译它。获取“libTest.dll”。很好。

第 2 步:编译不带 dll 的旧版应用

让我们跳过它。只是一个 hello world 控制台应用程序。没什么特别的。
编译完成。很高兴出发。

第 3 步:使用链接的 dll 重新创建应用

我已经尝试了很多来自谷歌的示例,但到目前为止还没有运气。
我已经尝试过库的名称“Test”和“libTest”。
我尝试将 dll 直接放入 ${PROJECT_BINARY_DIR}、${PROJECT_SOURCE_DIR} 中,并创建一个 add_subdirectory(libStore)。
我尝试使用 find_package(Test/libTest)。
因此我认为我的cmake和源代码中应该有一些不正确的地方。

App.cxx 中的代码:

#include <iostream>
#include "Test.h" //Also tried "libTest.h"
int main() {
    std::cout << helloworld();
    getchar();
    return 0;
}

尝试 1:

将libTest.dll放在子目录“/Lib”下
根 CMakeLists.txt 中的代码:

cmake_minimum_required(VERSION 3.10)
project(App VERSION 1.0)
include_directories("${PROJECT_SOURCE_DIR}/Lib")
add_subdirecotry(Lib)
add_executable(App App.cxx)
target_link_libraries(App libTest) //Tried both Test and libTest

/Lib CMakeLists.txt 中的代码:

add_library(libTest libTest.dll)
set_target_properties(libTest PROPERTIES LINKER_LANGUAGE C)

构建结果:

Fatal Error: Test.h(libTest.h): No such file or directory.

尝试 2:

将libTest.dll直接放入源目录(${PROJECT_SOURCE_DIR})
CMakeLists.txt 中的代码:

cmake_minimum_required(VERSION 3.10)
project(App VERSION 1.0)
include_directories("${PROJECT_SOURCE_DIR}")
add_executable(App App.cxx)
target_link_libraries(App libTest) //Tried both Test and libTest

构建结果:

Fatal Error: Test.h(libTest.h): No such file or directory.

尝试 3:

与尝试 2 相同,但添加 find_package(libTest) 函数。

cmake_minimum_required(VERSION 3.10)
project(App VERSION 1.0)
include_directories("${PROJECT_SOURCE_DIR}")
find_package(libTest)
add_executable(App App.cxx)
target_link_libraries(App libTest) //Tried both Test and libTest

CMake 警告:

Could not find a package configuration file provided by "libTest" with any of the following names:
libTestConfig.cmake
libTest-config.cmake

在源目录中创建了一个名为 libTestConfig.cmake 的空文件。 构建结果:

Fatal Error: Test.h(libTest.h): No such file or directory.

轰隆隆!

最佳答案

最后,我在这里找到了答案:

https://gitlab.kitware.com/cmake/community/-/wikis/doc/tutorials/Exporting-and-Importing-Targets

第一:

我以前尝试中的所有代码都假设您的项目文件夹中有源代码。
如果你想导入从外部获得的 DLL,实际的 CMakeLists.txt 应该如下所示:

cmake_minimum_required(VERSION 3.10)
project(Test VERSION 1.0)
add_library(Lib SHARED IMPORTED)
set_property(TARGET Lib PROPERTY IMPORTED_LOCATION "${PROJECT_SOURCE_DIR}/lib.dll")
set_property(TARGET Lib PROPERTY IMPORTED_IMPLIB "${PROJECT_SOURCE_DIR}/lib.dll.a") //Notice: lib.lib here if you are using VS building system.
add_executable(App app.cxx)
target_link_libraries(App Lib)

第二:

几乎所有在线教程都假设您使用的是 MS VS 构建系统。因此他们会一直谈论导入“*.lib”文件。
这将是一个很大的误导,让你毫无意义地追踪不存在的 lib 文件并将其与 dll 文件本身混淆。
如果你像我一样使用 GCC(MinGW),你要查找的实际文件是“lib.dll.a

关于c++ - 使用 CMake 编译带有链接 dll 的应用程序。需要查看工作示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63912743/

相关文章:

c++ - 实现真值表的一般模式

c++ - 智能指针作为 QObject::deleteLater() 的替代品

java - JNA通过java找不到dll文件中指定的程序

c# - 如何使用 MS VC# 2008 EE 为 Fiddler 创建工作扩展 dll?

c++ - 可以在linux程序中使用带有msvc的在windows上构建的lib

C++ gSOAP 文件生成

c++ - 将图像位发送到嵌入在 FPGA 中的 HDL 生成的 RAM block

c++ - 尝试在 CLion/CMake 中构建共享库

linux - cmake : Set environment variables from a script

c++ - CPACK_DEB_PACKAGE_COMPONENT 实际上做了什么?