使用cmake构建Windows DLL的一个简单示例

2024-04-28 19:34:44 发布

您现在位置:Python中文网/ 问答频道 /正文

几年前,我被一个位于东北部(可能是“下东区”)的合作工程机构的巨大工程包所累。这个包是用一个叫做“cmake”的东西构建的,它以Linux为目标。。。cmake,IMHO是我所遇到过的最令人吃惊的疯狂的、文档不全的、结构奇特的构建系统,考虑到我有限的能力(28年的*NIX系统和构建lotsa开源代码的专业经验),我不愿意与之合作。

然后我不得不建立另一个项目与“cmake”的目标是无国界医生。哦,快乐!最后一个可以可靠地生成那些讨厌的“项目”和“解决方案”文件的东西。同样的CMakeLists.txt文件可以重新定位Linux!哇,我看到光了。

不过,我现在的地方还是很黑。除非我有一个CMakeLists.txt文件来开始,否则我似乎无法从头开始,花不到一天的时间来解决最简单的问题。

我有一个任务要用msv构建一个DLL,可以使用ctypes从Python脚本访问它。基本上,这意味着一个在板上有符号的DLL。因为我有一个10岁的bug,我的VS 2008和VS 2010的安装不能创建一个新的C++项目,所以我想我会选择用CMADE生成一个DLL解决方案。

我还没有找到一个用cmake构建DLL的现代(又称post-cmake 2.8.5)完整的例子,这个例子应该比过去做得更好。

跳过教程http://www.cmake.org/cmake/help/cmake_tutorial.html,这是可怕的,因为他们希望你在学习CGUID时编写C++代码。(嘿,伙计!我在让cmake工作时遇到了足够的麻烦(让make代码编译!)本教程将介绍如何使用库构建一个简单的二进制文件,然后再构建一个二进制文件,但它不会生成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".

该函数似乎以GenerateExportHeader.cmake的身份出现在cmake安装中,没有任何调试显示此错误的“原因”。我在网上找不到这个错误。

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

我最终决定删除这个令人不快的命令并尝试:

add_library(MathFunctions mysqrt.cxx)

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

哇啦!cmake配置并生成了它,MSVS成功地构建了它,并且在library目录的Debug子目录中出现了一个DLL。库尔。

但是,这个DLL不包含允许python/ctypes访问所需函数的符号。在BuildingWindell页面中进行了更多的浏览之后,我设法引出了这些符号。Python很高兴,我现在有了一个未来工作的模型,尽管这是一个粗鲁,头脑简单的黑客!

所以,在那冗长的讨论之后:

  • 是指CMAKE2.8.5及以上版本的BuildingWindell吗 错了?
  • 正确的方法是什么?
  • 有没有人有一个简单的“cmake 101”例子,用导出的符号创建一个MSVS DLL,而不是一个黑客,这样我就可以扔掉我的黑客?

很好,很友好的文章合成系统。我会喜欢的,假设我被允许回来。。。

在steveire回答后更新:

最初的问题得到了回答,我发现我在buildingwindell页面中遗漏了一个提示。我还发现我未能为自己的代码更改示例中的一个字段。

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

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

我从BuildingWindell中得知,GENERATE_EXPORT_HEADER()都在唱歌,都在跳舞正在调用DLL。未生成.lib文件,并且生成的.dll不包含符号。。。

buildingwindell页面讨论了cmake-2.8.5之前的流程。页面顶部的2.8.5过程说明了如何使用GENERATE_EXPORT_HEADER()自动生成页面底部的文件。仍有必要将这些片段组合在一起,这在文本中是不清楚的。

因此,MathFunctions_Export.h由GENERATE_Export_HEADER()cmake命令和此处提供的特定参数生成,并创建一个带有宏的C HEADER,用于导出符号。显然,必须明确引用此文件和符号,才能正确导出符合以下条件的文件:

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

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

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

成功!感谢所有在这个过程中帮助我的人,感谢他们在我的痛苦中与我一同受苦。


Tags: install文件代码txtcmakeinclude符号export