【问题标题】:A simple example of using cmake to build a Windows DLL使用 cmake 构建 Windows DLL 的简单示例
【发布时间】:2014-07-21 18:32:37
【问题描述】:

几年前,我正忙于构建和修改位于东北部(也许是“Down East”)的合作伙伴工程机构的这个庞大的软件包。这个软件包是使用名为“cmake”的东西构建的,以 Linux 为目标...... cmake,恕我直言,鉴于我的能力有限(28 年拥有 *NIX 系统和构建大量开源代码的专业经验)。

然后我不得不使用“cmake”构建另一个针对 MSVS 的项目。哦,欢乐!最后,可以可靠地生成那些讨厌的“项目”和“解决方案”文件的东西。那些相同的 CMakeLists.txt 文件可以重新定位 Linux!哇,我看到了曙光。

不过,我所在的地方仍然很黑。除非我有一个 CMakeLists.txt 文件作为开始,否则我似乎无法从头开始着手,并且在这个过程中花费不到一天的时间来解决最简单的问题。

我的任务是使用 MSVS 构建一个 DLL,可以使用 ctypes 从 Python 脚本访问该 DLL。基本上,这意味着一个带有板载符号的 DLL。由于我有一个 10 年前的错误,即我的 VS 2008 和 VS 2010 安装无法创建新的 C++ 项目,我想我会选择使用 cmake 生成 DLL 解决方案。

我还没有找到一个现代的(也就是 cmake 2.8.5 之后的)COMPLETE 使用 cmake 构建 DLL 的示例,它在这项任务上应该比过去做得更好。

深入阅读教程http://www.cmake.org/cmake/help/cmake_tutorial.html,这太可怕了,因为他们希望您在学习 cmake 的同时编写 C++ 代码。 (嘿,伙计!我在让 cmake 工作时遇到了很多麻烦,更不用说制作可以编译的代码了!)本教程虽然构建了一个简单的二进制文件,然后使用库构建了一个二进制文件,但它不会生成 DLL。

字里行间读到http://www.cmake.org/Wiki/BuildingWinDLL,天真地在lib目录下的CMakeLists.txt文件中添加了一些代码:

之前:

add_library(MathFunctions mysqrt.cxx)

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

之后:

add_library(MathFunctions SHARED mysqrt.cxx)
GENERATE_EXPORT_HEADER( MathFunctions
             BASE_NAME MathFunctions
             EXPORT_MACRO_NAME MathFunctions_EXPORT
             EXPORT_FILE_NAME MathFunctions_Export.h
             STATIC_DEFINE MathFunctions_BUILT_AS_STATIC
)
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

cmake 3.0.0 和 cmake 2.8.12.2 都在这个文件中使用:

CMake Error at MathFunctions/CMakeLists.txt:2 (GENERATE_EXPORT_HEADER):
  Unknown CMake command "GENERATE_EXPORT_HEADER".

该函数在 cmake 安装中显示为 GenerateExportHeader.cmake,并且没有多少调试可以揭示此错误的“原因”。而且我一直无法在互联网上找到这个错误。

那是我一天中的前六个小时。

我最终决定删除有问题的命令并尝试以下操作:

add_library(MathFunctions mysqrt.cxx)

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

哇啦! cmake配置生成,MSVS构建成功,库目录的Debug子目录下出现了一个DLL。库尔。

然而,这个 DLL 不包含允许 python/ctypes 访问所需函数的符号。在 BuildingWinDLL 页面中进行了一些深入研究之后,我设法引出了这些符号。 Python 非常高兴,我现在有了一个未来工作的模型,尽管这是一个粗鲁、头脑简单的 hack!

那么,经过冗长的讨论:

  • 是BuildingWinDLL,指cmake 2.8.5及以上,简单 错了吗?
  • 这样做的正确方法是什么?
  • 有没有人有一个简单的“cmake 101”示例来创建一个带有导出符号的 MSVS DLL,这不是 hack,以便我可以扔掉我的 hack?

PS:stackoverflow 上非常、漂亮、友好的文章撰写系统。假设我被允许回来,我会喜欢这个......

steveire 回答后更新:

回答了原始问题,我发现我错过了 BuildingWinDLL 页面中的提示。我还发现我未能为自己的代码更改示例中的字段之一。

所以现在我们进入下一层。使用引用的示例,VS2010 解决方案构建抱怨:

LINK : fatal error LNK1104: cannot open file 'MathFunctions\Debug\MathFunctions.lib'

我从 BuildingWinDLL 中收集到 GENERATE_EXPORT_HEADER() 在构建 DLL 方面是全能的。没有生成.lib文件,生成的.dll不包含符号...

BuildingWinDLL 页面讨论了 cmake-2.8.5 之前的进程。页面顶部注明的 2.8.5 过程是现在如何使用 GENERATE_EXPORT_HEADER() 自动生成页面底部的文件。 仍然需要将碎片编织在一起,我从文字中不清楚。

因此 MathFunctions_Export.h 由 GENERATE_EXPORT_HEADER() cmake 命令和此处提供的特定参数生成,并创建一个带有宏的 C 头文件,用于导致符号被导出。显然必须明确引用此文件,并且要正确限定导出的符号:

#include <math.h>
#include <Mathfunctions/MathFunctions_Export.h>

MathFunctions_EXPORT double mysqrt(double v) {
    return sqrt(v);
}

现在添加 #include 和 *EXPORT 限定符会导致符号被导出,并且 VS 现在知道生成 .lib 并用符号填充 .dll。

成功!感谢所有在这个过程中提供帮助并在我的痛苦中与我一起受苦的人。

【问题讨论】:

  • 如果您将其重写为一个直截了当的问题,并为我们提供我们需要的信息,而不是长篇博文,这将有所帮助。此外,所有这些标签是否真的与您的问题相关?因为如果不是这样,他们会吓跑很多人,他们知道他们对 VS2010 或 Python 或其他东西一无所知,并且认为他们无法回答。
  • 您的CMakeLists.txt 中可能缺少include(GenerateExportHeader)
  • 嗯,妈妈教我分享,不幸的是,当我痛苦时,我仍然分享......
  • @abarnert 我听到了,但我个人发现问题中的额外细节很有帮助。我也一直在寻求使用 CMake 创建符号导出 DLL。我已阅读此问题中列出的所有相同文档。我发现它很有帮助 The Red Gator 列出了他读过的文档以及他发现这些文档中缺少的东西,因为我走上了类似的道路。了解 Red Gator 在此过程中遇到的陷阱,让我对所提供的解决方案更有信心。我知道我们都有自己的喜好。就我自己而言,我发现添加的叙述非常有帮助!

标签: python c++ visual-studio-2010 dll cmake


【解决方案1】:
include(GenerateExportHeader)

使用前。

http://www.cmake.org/cmake/help/v3.0/module/GenerateExportHeader.html

CMake 默认构建 STATIC 库,如果您想构建共享库,请保留 SHARED。

【讨论】:

  • 谢谢。这摆脱了“未知”的翅膀。我想知道这一步在文档中的哪个位置很清楚。我在引用的网页中找不到它。因为它回答了标题,所以我将其标记为答案。
  • 哇,给我画“duh”。 BuildingWinDLL 页面在最顶部有这个。 cmake 文档中似乎有一种模式来分割示例,这使我很难理解它们。不清楚这两个代码块是否属于一起。
  • 从文档中看不清楚,但是如果你想将 dll 导出和导入定义为没有 linux 构建,那是如何实现的?
  • @TheRedGatorinVirginia,你有最终工作解决方案的完整代码示例吗?看看它肯定会对我有很大帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-05
  • 2020-03-12
  • 2014-02-05
  • 1970-01-01
相关资源
最近更新 更多