首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用CMake链接dll编译应用程序。需要查看一个工作样本

用CMake链接dll编译应用程序。需要查看一个工作样本
EN

Stack Overflow用户
提问于 2020-09-16 03:36:27
回答 2查看 1.3K关注 0票数 1

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

以下是有用的文件:

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

工作的CMakeLists.txt是这样的:

代码语言:javascript
复制
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构建系统。因此,他们将继续谈论导入"*.lib“文件。

如果您像我一样使用GCC(MinGW),您要查找的实际文件是"*.dll.a“。

9月17日编辑

不不对。我们使用的是DLL。而DLL不应影响编译。

当您希望将它们放入.exe所需的文件夹中时,DLL应该是DLL,而不是编译检查标头。

但我们正在尝试从dll中解压一个标头。

这个工作流一定有问题。

CMake和GCC

由于我的公司缺乏许可证,我不能使用任何IDE或VS构建工具。

因此,对于开源的编译环境,我必须了解CMake + GCC。

我现在可以正确地编译应用程序和静态库了。但却卡在了dll链接中。

这应该是一个简单的,但由于我找不到任何样本谷歌,因此,我需要你的帮助,以纠正这个链接工作的CMake工作流程。谢谢。

或者任何能找到正确方向的超链接。

如我所知,我可以简单地在IDE中添加dll库,比如VisualStudio,它将尽一切努力将其转换为包含头文件的东西。我一定是错过了CMake的这个部分。

My Step:

  1. 编译dll
  2. 编译一个没有dll的遗留应用程序
  3. 用dll(BOOM!

)链接的函数重新创建应用程序。

详细代码如下:

步骤1:编译dll

测试.h中的代码:

代码语言:javascript
复制
#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中的代码:

代码语言:javascript
复制
#include <iostream>
#include "Test.h"
int helloworld() {
    std::cout << "I hate HelloWorld\n";
    return 0;
}

CMakeLists.txt中的代码:

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.10)
project(Test)
include(GenerateExportHeader)
add_library(Test SHARED Test.cxx)
generate_export_header(Test)

编译它。得到一个"libTest.dll“。好的。

步骤2:编译一个没有dll的遗留应用程序

我们跳过吧。只是一个你好世界控制台应用程序。没有什么特别事情。

编译完成。可以开始了。

步骤3:使用链接dll重新创建应用程序

我试过这么多谷歌的样本,但到目前为止都没有运气。

我试过这个库的名称"Test“和"libTest”。

我尝试将dll直接放在${PROJECT_BINARY_DIR}、${PROJECT_SOURCE_DIR}中,并创建一个add_subdirectory(libStore)。

我尝试过使用find_package(Test/libTest)。

因此,我认为在我的cmake和源代码中应该有不正确的地方。

App.cxx中的代码:

代码语言:javascript
复制
#include <iostream>
#include "Test.h" //Also tried "libTest.h"
int main() {
    std::cout << helloworld();
    getchar();
    return 0;
}

尝试1:

将libTest.dll放在"/Lib“子目录下

根CMakeLists.txt中的代码:

代码语言:javascript
复制
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中的代码:

代码语言:javascript
复制
add_library(libTest libTest.dll)
set_target_properties(libTest PROPERTIES LINKER_LANGUAGE C)

建设成果:

代码语言:javascript
复制
Fatal Error: Test.h(libTest.h): No such file or directory.

企图2:

将libTest.dll直接放入源目录(${PROJECT_SOURCE_DIR})

CMakeLists.txt中的代码:

代码语言:javascript
复制
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

建设成果:

代码语言:javascript
复制
Fatal Error: Test.h(libTest.h): No such file or directory.

企图3:

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

代码语言:javascript
复制
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警告:

代码语言:javascript
复制
Could not find a package configuration file provided by "libTest" with any of the following names:
libTestConfig.cmake
libTest-config.cmake

在源目录中创建一个空文件名libTestConfig.cmake。建设成果:

代码语言:javascript
复制
Fatal Error: Test.h(libTest.h): No such file or directory.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-17 06:42:24

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

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

第一:

我以前尝试过的所有代码都假设您的源代码在项目文件夹中。

如果您想导入从外部获得的DLL,实际的CMakeLists.txt应该如下所示:

代码语言:javascript
复制
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构建系统。因此,他们将继续谈论导入"*.lib“文件。

这将是一个很大的误导,使您毫无意义地跟踪不存在的lib文件,并将其与dll文件本身混淆。

如果您像我一样使用GCC(MinGW),您要查找的实际文件是"lib.dll.a“。

票数 1
EN

Stack Overflow用户

发布于 2020-09-16 04:59:50

我认为问题可能在这里:

代码语言:javascript
复制
include_directories("${PROJECT_SOURCE_DIR}")

与查找DLL本身的问题不同,cmake似乎只是有一个问题来查找Test.h (或libTest.h)头文件。尝试将DLL的头文件放在通过cmake的"include_directories“指定的路径中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63912743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档