Electron builder 失败并显示:未生成 'object' 文件

Electron builder fails with: no 'object' file generated

自从 升级到 Electron 10.1.2 后,我在 electron-builder 上遇到了问题。我的构建现在在重建 keyboard-layout 时失败。仅 Windows 的重建失败,Mac 的失败。我不知道在哪里打开这个问题所以我在这里问:)。


我的设置:

当我将 electron9.0.0 更新到 10.1.2 时,问题开始了。其他没有改变。


问题:
当使用命令 electron-builder.cmd --x64 -p always -w 调用 electron-builder 时,keyboard-layout 的重建被称为以下步骤之一:

> keyboard-layout@2.0.16 install C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout
> node-gyp rebuild

失败:

...
 win_delay_load_hook.cc
    c:\users\<me>\.electron-gyp.1.2\include\node\v8.h(5378): error C2220: warning treated as error - no 'object' file generated (compiling source file ..\src\keyboard-layout-manager-windows.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
    c:\users\<me>\.electron-gyp.1.2\include\node\v8.h(5378): warning C4309: 'static_cast': truncation of constant value (compiling source file ..\src\keyboard-layout-manager-windows.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
    c:\users\<me>\.electron-gyp.1.2\include\node\v8.h(5378): error C2220: warning treated as error - no 'object' file generated (compiling source file ..\src\keyboard-layout-manager.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
    c:\users\<me>\.electron-gyp.1.2\include\node\v8.h(5378): warning C4309: 'static_cast': truncation of constant value (compiling source file ..\src\keyboard-layout-manager.cc) [C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj]
    Done Building Project "C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\keyboard-layout-manager.vcxproj" (default targets) -- FAILED.
    Done Building Project "C:\Users\<me>\<dir1>\<dir2>\dist\node_modules\keyboard-layout\build\binding.sln" (default targets) -- FAILED.

    Build FAILED.
...

我尝试过但没有帮助的方法:
node_modules/keyboard-layout 中的 binding.gyp 更改为(标有 <--- 的条目):

['OS=="win"', {
         "sources": [
           "src/keyboard-layout-manager-windows.cc",
         ],
         'msvs_settings': {
           'VCCLCompilerTool': {
             'ExceptionHandling': 1, # /EHsc
             'WarnAsError': 'false', # <--- I chnaged this from true to false
           },
         },
         'msvs_disabled_warnings': [
           4018,  # signed/unsigned mismatch
           2220,  # <--- I added this
           4244,  # conversion from 'type1' to 'type2', possible loss of data
           4267,  # conversion from 'size_t' to 'type', possible loss of data
           4302,  # 'type cast': truncation from 'HKL' to 'UINT'
           4311,  # 'type cast': pointer truncation from 'HKL' to 'UINT'
           4530,  # C++ exception handler used, but unwind semantics are not enabled
           4506,  # no definition for inline function
           4577,  # 'noexcept' used with no exception handling mode specified
           4996,  # function was declared deprecated
         ],
       }],  # OS=="win"

我尝试过的帮助:
Electron 10.x.y 将 v8 更新为 8.5 (Electron 10.0.0 release notes) 并查看导致错误的行 (...\.electron-gyp.1.2\include\node\v8.h(5378)) 我看到了这个:

 static constexpr size_t kMaxLength =
      internal::kApiSystemPointerSize == 4
          ? internal::kSmiMaxValue
          : static_cast<size_t>(uint64_t{1} << 32); <--- Line 5378

当我比较来自 ...\.electron-gyp.1.2\include\node\v8.h...\.electron-gyp.0.0\include\node\v8.h 的 v8.h 文件时,这一行发生了变化。

旧版本中的同一行:

  static constexpr size_t kMaxLength = internal::kApiSystemPointerSize == 4
                                           ? internal::kSmiMaxValue
                                           : 0xFFFFFFFF;

如果我将 static_cast<size_t>(uint64_t{1} << 32) 更改为 0xFFFFFFFF 构建成功。


我的理解到此结束

  1. 难道新旧线理论上不一样?移动 32 位导致 0xFFFFFFFF?
  2. 我能做些什么来解决这个问题,这个变化的原因是什么?
  3. 为什么这个问题只出现在 Windows 上?

What I have tried that DID NOT help:

'WarnAsError': 'false' 应该可以解决问题;但是,针对两个不同的文件(..\src\keyboard-layout-manager.cc..\src\keyboard-layout-manager-windows.cc)报告了错误,因此您必须修改这两个文件的构建规则。

禁用警告也应该有帮助,但它必须是您需要禁用的警告 4309(而不是 2220)。同样,您必须对两个文件(或仅对整个编译)执行此操作。

Are the old and new lines not theoretically the same? One shifted for 32 bits results in 0xFFFFFFFF?

没有,1 << 32 == 0x100000000 == 0xFFFFFFFF + 1).

What can I do to fix this issue?

  • 关闭 'WarnAsError' 应该会有帮助
  • 关闭警告 4309 应该会有帮助
  • 在您的本地结帐中恢复这一行应该会有所帮助
  • 使用 Clang 而不是 MSVC 应该会有所帮助
  • 可能使用不同的(更新的?)版本的 MSVC 也会有所帮助

and what could be the reason for this change?

V8 现在允许 TypedArrays 最多 2**32 个元素,比以前多了一个元素。

Why is this problem only on Windows?

因为警告是 compiler-specific,而 MSVC 仅在 Windows 上使用。

奇怪的是你一开始就看到了这个错误。你编译 --x64;如果这听起来像,你应该编译一个 64 位版本,其中 internal::kApiSystemPointerSize == 8size_t 有 64 位就像 uint64_t,所以在表达式 static_cast<size_t>(uint64_t{1} << 32);没有被截断。

即使出于某种原因此构建尝试创建 V8 的 32 位构建,也应该采用另一个分支 (internal::kApiSystemPointerSize == 4),并且编译器应该足够聪明,不会对分支发出警告无论如何,那已经死了。

无论如何,这看起来像一个编译器 bug/limitation。因此,适当的解决方法是更新您的编译器,或禁用错误警告。