【发布时间】:2020-09-16 03:36:27
【问题描述】:
已找到答案。为了节省您大量阅读的时间:
这里有用的文档:
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 所需的文件夹中,而不是编译检查头文件时。
但我们正在尝试从 dll 中解压缩标头。
这个工作流程一定有问题。
CMake 和 GCC
由于我的公司没有许可证,我无法使用任何 IDE 或 VS 构建工具。
因此,我必须了解 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.
轰隆隆!
【问题讨论】:
标签: c++ dll cmake compiler-errors