在 windows (VS2012) 上从源代码构建 NSIS

Building NSIS from source on windows (VS2012)

我正在开发我的软件的纯 x64 版本。我们的 x86 版本安装程序是 NSIS,我的软件是使用 VS2012 构建的。我在网上发现,为了使用 NSIS 构建 x64 安装程序,您必须从源代码构建 NSIS(以及所有 plugins/etc)。这是最终目标。但是,现在我在使用 NSIS 文档中的说明构建 x86(在转向 x64 之前)时遇到了问题。 https://nsis.sourceforge.io/Docs/AppendixG.html#build_windows

我正在尝试构建使用 SCons 构建的 NSIS v3.0.4。我已经使用 pip 安装了 scons(SCons 版本 3.1.1)。

但是,在尝试构建 NSIS 时,我得到以下信息(使用 python 3.8.0)。

C:\Source\nsis\nsis-code-r7069-NSIS-tags-v304>scons ZLIB_W32=C:\Source\zlib-1.2.7 MSTOOLKIT=yes
scons: Reading SConscript files ...
TypeError: cannot use a string pattern on a bytes-like object:
  File "C:\Source\nsis\nsis-code-r7069-NSIS-tags-v304\SConstruct", line 263:
    for v in re.compile(r'^\H\{[v]?(\S+)\}', re.M).finditer(File('#/Docs/src/history.but').get_contents()): # Try to parse the Halibut history file

SConstruct文件的部分如下(从第260行开始所以for循环从263开始):

if not defenv.has_key('VER_PACKED'):
    import re
    found = None
    for v in re.compile(r'^\H\{[v]?(\S+)\}', re.M).finditer(File('#/Docs/src/history.but').get_contents()): # Try to parse the Halibut history file
        if v and not found:
            v = v.group(1).split('.')
            if len(v) >= 2:
                mi = int(re.search(r'\d+', v[1]).group())
                if mi < 1: mi = 1 # Make sure we can subtract 1 from the minor number so trunk stays below the next release
                defenv['VER_PACKED'] = '0x%0.2i%0.3i%0.2i%0.1i' % (int(re.search(r'\d+', v[0]).group()), mi - 1, 66, 6)
                if int(defenv['VER_PACKED'], 0) >= int('0x03000000', 0):
                    found = v
    if not found:
        defenv['VER_PACKED'] = '0x%0.2i%0.3i%0.2i%0.1i' % (3, 3, 42, 0) # Default to a version number we never used
    print('WARNING: VER_PACKED not set, defaulting to %s!' % defenv['VER_PACKED'])

此时,我不确定是否缺少依赖项,或者这是构建脚本的问题并且需要在 NSIS 问题跟踪器中报告。想法?

-更新 1-

根据@Anders 的建议,我首先尝试使用 Python3 构建 repo 的头部(r7132 trunk)而不是 v3.0.4。这让我走得更远,但仍然失败了 Python2 与 mstoolkit.py 中的 3 个语法错误(尽管可能是另一个问题的症状而不是原因)。我还没有对此进行过多调查。

接下来,我又回到了 Python 2.7。这让我更进一步,但 mstoolkit.py 似乎依赖于 VS2003 实现。我使用 VS110COMNTOOLS (C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Tools) 的内容在我的机器上复制了 VCToolkitInstallDir 环境变量,但这也失败了:

  File "C:\Source\IQClient_Interim\Shared\third_party\nsis\nsis-code-r7132-NSIS-tags-v304\SCons\Tools\mstoolkit.py", line 87, in get_msvctoolkit_paths
    raise SCons.Errors.InternalError, "The Platform SDK directory was not found in the registry or in the `MSSdk` environment variable."
InternalError: The Platform SDK directory was not found in the registry or in the `MSSdk` environment variable.

我不知道 VS2003 VCT​​oolkitInstallDir ENVVAR 指向什么来解决这个问题。

综上所述,我只是注意到安德斯说我可能还必须使用旧版本的 scons 以及 python2.7 所以我想我会花一些时间研究它(以及研究@bdbaddog 的解决方案)。

-更新 2- 这是 mstoolkit 指令(参见@Anders 回答的评论) 之后我在为 NSIS 3.0.4 使用 py 2.7 时让它工作了。

现在开始 x64 构建,但这是另一回事,所以我将 post 提出一个不同的问题。

NSIS v3.04不支持Python 3、你要抢latest source code from SVN。 v3.05 即将推出,支持 Python 3.

VS2012 已经足够老了,您应该可以使用 Python 2.7 和旧版本的 SCons 作为替代。

作为最后的选择,您可以尝试将 this diff 应用于 v3.04。

您 运行 遇到的问题是双重的。

  1. Python > 3.0 字符串不再是字节。它们是 unicode
  2. 支持 Python > 3.0 的 SCons(SCons >3.0 支持 Python 2.7 和 Python > 3.5.0)

为了支持这个 Node() 的(SCons 表示文件、目录和值的方式,这些文件、目录和值被送入构建)现在有两个方法 get_contents() 和 get_text_contents( ).

由于您使用的是 Python 3.8.0,get_contents() 将 return 字节,这解释了您收到的错误。

解决它的正确方法是更改​​此行:

for v in re.compile(r'^\H\{[v]?(\S+)\}', re.M).finditer(File('#/Docs/src/history.but').get_contents()): # Try to parse the Halibut history file

至:

for v in re.compile(r'^\H\{[v]?(\S+)\}', re.M).finditer(File('#/Docs/src/history.but').get_text_contents()): # Try to parse the Halibut history file

如果这不能解决问题,请告诉我。 此外,如果您愿意安装 Python 2.7 并通过

重新安装 SCons
py -2.7 -mpip install scons

(假设您在安装 Python 时安装了 py 启动器。不确定 Python 3.8 and/or Python 2.7 是否默认。如果不是,则 / python -m pip install scons。您可能还必须安装 pip。再次不确定默认值。)

这样就可以避免更改 SConstruct 文件。

希望对您有所帮助!