问题描述
由于升级到电子10.1.2 ,我对electron-builder
有疑问。现在,我的构建在keyboard-layout
的重建上失败。重建仅适用于Windows,而不适用于Mac。我不知道在哪里打开这个问题,所以我在这里问:)。
我的设置:
- 角度:9.0.7
- 电子:10.1.2
- 电子生成器:22.8.x
当我更新电子从 9.0.0到10.1.2 时,问题开始了。没有其他改变。
问题:
当使用命令electron-builder
调用electron-builder.cmd --x64 -p always -w
时,将重建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\10.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\10.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\10.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\10.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.
...
我尝试过的DID无效的方法:
将binding.gyp
中的node_modules/keyboard-layout
更改为(标有<---
的单词):
['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"
我尝试过的DID帮助:
Electron 10.x.y 将v8更新为8.5 (Electron 10.0.0 release notes),并查看引起错误的行(...\.electron-gyp\10.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\10.1.2\include\node\v8.h
和...\.electron-gyp\9.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
,则构建成功。
我的理解到此为止。
解决方法
我尝试过的DID无济于事:
'WarnAsError': 'false'
应该可以解决问题;但是,报告了两个不同文件(..\src\keyboard-layout-manager.cc
和..\src\keyboard-layout-manager-windows.cc
)的错误,因此您必须修改它们的构建规则。
禁用警告也应该有所帮助,但必须警告您需要禁用4309(而非2220)。同样,您必须对两个文件(或仅对整个编译)都这样做。
旧行和新行在理论上是否不相同?一个移位32位会导致
0xFFFFFFFF
?
否,1 << 32 == 0x100000000 == 0xFFFFFFFF + 1
)。
该如何解决此问题?
- 关闭
'WarnAsError'
应该会帮助 - 关闭警告4309应该会有所帮助
- 还原本地结帐单行应该会帮助
- 使用Clang代替MSVC应该会帮助
- 可能使用其他(较新的)MSVC版本也会有所帮助
这是什么原因?
V8现在允许TypedArrays最多包含2**32
个元素,这比以前多了一个元素。
为什么仅在Windows上会出现此问题?
由于警告是特定于编译器的,因此MSVC仅在Windows上使用。
奇怪的是,您首先看到此错误。您使用--x64
进行编译;如果这听起来确实不错,则应该编译一个64位版本,其中internal::kApiSystemPointerSize == 8
和size_t
具有64位,就像uint64_t
一样,因此在表达式static_cast<size_t>(uint64_t{1} << 32);
中什么都不会被截断。
即使由于某种原因该版本试图创建V8的32位版本,也应采用另一个分支(internal::kApiSystemPointerSize == 4
),并且编译器应足够聪明,以免警告静态的分支反正死了。
无论如何,这似乎是编译器错误/限制。因此,适当的解决方法是更新编译器或禁用错误警告。