原始问题:有什么方法可以让 nw-gyp 默认添加到构建项目中的宏?
我正在开发一个 nw 插件,并尝试将自定义静态库链接到 .node DLL。但是我发现 nw-gyp 默认会添加 _HAS_ITERATOR_DEBUGGING=0 (它总是附加到插件项目以覆盖自定义定义),这将影响 STL 类型的实际结构大小(例如 std::string)。
那么有没有一种方法可以默认添加这样的宏节点 gyp,或者是否有一种简单的方法可以使静态库和 nw 构建项目的编译器(可能是整个工具链、链接工具等)配置相同?
现在我已将 _HAS_ITERATOR_DEBUGGING=0 添加到我的库中并使其成为 MT(D),它似乎工作正常,但我不确定这是否是正确的方法。(其他一些编译器设置可能不会导致编译错误,但可能会在运行时崩溃)
编辑:分享一些分析,让我的起源问题更清楚。
当前所有问题都在 Windows 平台上。
即使我在调试模式下构建 nw 插件(使用 --debug),也会添加 _HAS_ITERATOR_DEBUGGING=0,这可能会受到 nw-gyp 下载的 nw 头文件的影响。例如,从http://node-webkit.s3.amazonaws.com/v0.49.2/nw-headers-v0.49.2.tar.gz下载的标头,您将'defines': [ 'DEBUG', '_DEBUG', 'V8_ENABLE_CHECKS', '_HAS_ITERATOR_DEBUGGING=0' ]
在 Debug_Base 配置部分的第 288 行的 common.gypi 中找到,这很可能是从https://github.com/nwjs/chromium.src继承的(我猜这里是https://github.com/nwjs/chromium.src/blob/nw60/build/config/BUILD.gn #L130)。那么是否可以断定 Chrome 是故意为调试模式添加这些定义的呢?
_HAS_ITERATOR_DEBUGGING=0
调试对我来说有什么问题? 嗯,它会影响许多 STL 类(std::string、std::vector 等)的大小。所以所有需要链接到nw插件的调试库都应该用 编译'_HAS_ITERATOR_DEBUGGING=0'
,否则静态库会发生编译错误和动态库的运行时指针问题崩溃(结构偏移不匹配)(当然使用STL不是一个好习惯在动态库头文件中,但如果您可以假设工具链相同,它仍然可以正常工作)。但是当涉及到第三方二进制文件时,这对我来说真的很难,我没有大部分的源代码,所以我不能给一个调试静态库_HAS_ITERATOR_DEBUGGING=0
。当我需要使用 lldb 或 VS 调试插件时,这真的很令人沮丧,因为所有变量都经过优化,您无法调试它们的值。
我可以强制_HAS_ITERATOR_DEBUGGING=1
进入调试模式吗?如原始问题中所述,它不能像@mmomtchev的回答那样正常完成。一种破解方法是在 gyp 文件中添加插件,这将附加"/D _HAS_ITERATOR_DEBUGGING=1"
到编译命令的末尾,从而覆盖以前的定义。但我不确定这是否是一个好的解决方法!我检查了 v8 头文件并发现了一些带有 std::string 和 std::vector 成员的类。如果你使用这些类,我认为 force _HAS_ITERATOR_DEBUGGING 会引起一些问题,但对于其他类来说它是安全的(我已经测试了很多情况,像 v8::value v8::function 这样的普通类运行良好)。并且与其他插件合作时不安全。configurations->Debug->msvs_settings->VCLinkerTool->AdditionalOptions
/D _HAS_ITERATOR_DEBUGGING=1
假设一个调试插件 A 和另一个发布插件 B 需要相互通信,他们同意使用一个 C++ 结构进行数据交换。一种常见的方法是让 A 将 C++ 结构实例包装到 JS 对象中供用户使用。并让用户通过调用B提供的方法将JS对象传递给B(JS对象是参数之一),然后B将JS对象从参数中解包并获取C++结构实例的指针。一切看起来都很好,但是如果 C++ 结构有 std::string 成员怎么办?A 和 B 的相同 C++ 结构的大小不同。所以 B 在尝试访问类型为 std::string 或 std::vector 的成员时会崩溃。如果 _HAS_ITERATOR_DEBUGGING=0 设置为调试模式,这不是问题,因为 _HAS_ITERATOR_DEBUGGING 总是禁用发布,我猜那
所以我的最后一个问题是:如果这不是强制_HAS_ITERATOR_DEBUGGING=1
调试的好方法,而且我没有许多外部编译的 lib 二进制文件的源代码,这是否意味着我无法在调试模式下构建 nw 插件?另一种可能的方法是用 C 风格的 API 包装这些库并将它们编译为动态库,但这对我来说确实是一项巨大的工作并且是不可接受的。