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

Posted

技术标签:

【中文标题】在 Windows 上从源代码构建 NSIS(VS2012)【英文标题】:Building NSIS from source on windows (VS2012) 【发布时间】:2019-11-14 19:54:33 【问题描述】:

我正在开发我的软件的纯 x64 版本。我们的 x86 版本的安装程序是 NSIS,我的软件是使用 VS2012 构建的。我在网上发现,为了使用 NSIS 构建 x64 安装程序,您必须从源代码构建 NSIS(以及所有插件/等)。这就是最终目标。但是,现在我在使用 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 主干)的头部,而不是 v3.0.4。这让我走得更远,但在 mstoolkit.py 中似乎是 Python2 vs 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 指向什么来解决这个问题。

话虽如此,我只是注意到安德斯说我可能还必须在 python2.7 中使用旧版本的 scons,所以我想我会花一些时间来调查这个(以及调查@bdbaddog's解决方案)。

-更新 2- 这是 mstoolkit 指令(请参阅@Anders 答案的 cmets) 在那之后,我在为 NSIS 3.0.4 使用 py 2.7 时让它工作了。

现在开始 x64 构建,但这是一个不同的故事,所以我将发布一个不同的问题。

【问题讨论】:

【参考方案1】:

NSIS v3.04 不支持 Python 3,你必须获取latest source code from SVN。 v3.05 即将推出,支持 Python 3。

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

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

【讨论】:

现在这两个都试过了。首先尝试从您的链接构建,但看起来 mstoolkit.py 尚未针对 Python3 进行更新。所以我回到了 python 2.7,但现在找不到 VS 工具包。我试图使用 VS2012 中存在的 VS110COMNTOOLS envvar 来模拟它正在寻找的 VSToolkitInstallDir ENVVAR,但它没有用。看起来 mstoolkit.py 非常依赖于 VS2003。想法?或者我应该简单地寻找 VS 以外的其他替代方案来构建它(记住 x64 是我的最终目标)。目前正在更新 OP。 你为什么使用 mstoolkit.py? mstoolkit 选项适用于旧的免费快递版本,如果您不指定 mstoolkit=yes,scons 应该能够获取您的正常 VS 安装。话虽这么说,那个 .py 文件可能是唯一没有为 python3 更新的文件,如果你修复它,我会接受补丁。 在稍微阅读了 scons 文档后,我在大约 20 分钟前得出了相同的结论。作为一名 Windows 开发人员,我接受过培训,可以在处理开源项目时自动搜索出任何显示为 MS 的内容,因此我希望它在不指定使用微软工具包的情况下无法工作。哎呀!它现在很好地嗡嗡作响。假设这可行,关于从这里到哪里构建 x64 的任何快速指示?有这方面的文档吗? 就NSIS而言,您只需将target_arch scons参数设置为amd64即可。您显然需要一个真正有效的 scons 和 64 位编译器配置。 32 位 NSIS 安装程序可以安装 64 位程序(服务器核心或其他已删除 wow64 的地方除外)。【参考方案2】:

您遇到的问题是双重的。

    Python > 3.0 字符串不再是字节。它们是 unicode 支持 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() 将返回字节,这解释了您收到的错误。

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

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 和/或 Python 2.7 的默认设置。如果不是,则 /python -m pip install scons。您可能还必须安装 pip。再次不确定该默认值。)

那么你就可以避免改变 SConstruct 文件了。

希望这会有所帮助!

【讨论】:

以上是关于在 Windows 上从源代码构建 NSIS(VS2012)的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 上从 Qt Creator 进入 Qt Sources(不是从源代码构建的)

在 Windows 上从源代码构建点云库 Boost 时出错

在 Windows 上从源代码构建 nginx

在Windows 7上从Windows 10 VS2017部署编译并找不到DLL

NSIS 构建不会在 Windows 上安装 Electron 应用程序。安装程序静默退出并产生 1620 错​​误

在 Windows 7 上从 emacs 运行 nmake