【发布时间】: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