已找到答案。为了节省您大量阅读的时间:
这里有用的文档:
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 中的这一部分。
我的步骤:
- 编译dll
- 编译不带 dll 的旧版应用
- 使用从 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/