几年前,我接手了一个来自东北地区(可能是“下东部”)的合作工程机构建立和修改这个庞大的软件包。该软件包使用名为“cmake”的工具构建,以Linux为目标...... 在我的有限能力下(28年的*NIX系统和构建大量开源代码的专业经验),IMHO,cmake是我曾经遇到过的最令人惊讶、最让人心烦意乱、文档最差、结构最奇怪的构建系统。
然后我需要使用“cmake”构建另一个针对MSVS的项目。哦,真是太棒了!终于有了能够可靠生成那些讨厌的“项目”和“解决方案”文件的工具。而且那些相同的CMakeLists.txt文件也可以重新定位到Linux! 哇,我看到了光明。
虽然我还在黑暗中。除非我有一个CMakeLists.txt文件作为起点,否则我似乎无法掌握从头开始并在最简单的问题上花费不到一天时间的过程。
我有一个任务是使用MSVS构建DLL,可以通过ctypes从Python脚本中访问。基本上,这意味着一个DLL具有内置的符号。由于我遇到了一个十年前的错误,我的VS 2008和VS 2010安装无法创建新的C++项目,我想用cmake生成一个DLL解决方案。
我一直没有找到一个现代(即cmake 2.8.5之后的)完整的例子来构建带有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已成功配置、生成并在库目录的Debug子目录中创建了一个DLL,而且MSVS也成功地构建了它。很酷。
但是,这个DLL没有包含允许Python/ctypes访问所需函数的符号。在BuildingWinDLL页面上进行了更多的搜索后,我成功激发了这些符号。Python非常高兴,尽管这只是一个粗鲁、简单的hack,但我现在有了未来工作的模型!
因此,在这场冗长的讨论之后:
- BuildingWinDLL是否指的是CMake 2.8.5及以上版本,只是错误的?
- 正确的方法是什么?
- 有人有一个简单的、"CMake 101"的示例,用于创建带有导出符号的MSVS DLL吗?这不是一个hack,这样我就可以放弃我的hack了?
附注:这里的stackoverflow文章组合系统非常好,友善。假设我被允许回来,我会享受这个系统的。
在steveire的答案之后更新:
原始问题得到了解答,我看到了BuildingWinDLL页面中的一个提示。我还发现我没有改变示例中的一个字段,以适应我的代码。
现在我们进入了下一层。使用所提供的示例,VS2010解决方案构建报错:
LINK : fatal error LNK1104: cannot open file 'MathFunctions\Debug\MathFunctions.lib'
从BuildingWinDLL中我了解到GENERATE_EXPORT_HEADER()在构建DLL方面是个全能的工具。但.lib文件没有生成,而生成的.dll文件也不含有符号......
BuildingWinDLL页面谈论了pre-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。
成功了!感谢所有协助我完成这个过程并与我一同承受痛苦的人。
CMakeLists.txt
дёжјЏжЋ‰дє†дёЂдёЄincludeпј€GenerateExportHeaderпј‰
гЂ‚ - sakra