使用 rpython 在 windows 下生成的程序无法运行

文章详细介绍了使用RPython编译出的C代码在Windows环境下无法运行的原因,通过分析Makefile的生成过程,指出是编译器版本解析错误导致的。文章提供了解决方法,通过修改Makefile生成逻辑,确保编译器版本正确识别,从而成功生成可执行文件。
在 windows 用rpython编译出的文件总是无法运行,报
通过跟踪发现,rpython 每次都会将生成的C代码、Makefile 等放置在 %TEMP%\usession-release-2.0.x-17\testing_1 中(17是序号,每次都会自增),进去此目录,发现可执行文件是可以执行的——因为编译目录里是有manifest文件的。
 
Makefile 的生成是在 pypy-2.0.2-src\rpython\translator\c\genc.py 中的 CStandaloneBuilder::gen_makefile 中完成的,其间会调用平台相关的代码 pypy-2.0.2-src\rpython\translator\platform\windows.py 中的 MsvcPlatform::gen_makefile ,而 MsvcPlatform::gen_makefile 会试图在链接阶段嵌入manifest。代码如下——先判断编译器版本 self.version,如果大于等于 VC2005 就会在Makefile中输出 调用 mt.exe 嵌入manifest文件的步骤。
    def gen_makefile(self, cfiles, eci, exe_name=None, path=None,
                     shared=False):
        ……
        if self.version < 80:
            m.rule('$(TARGET)', '$(OBJECTS)',
                    create_obj_response_file + [\
                   '$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA)' + objects + ' /out:$@ $(LIBDIRS) $(LIBS)',
                   ])
        else:
            m.rule('$(TARGET)', '$(OBJECTS)',
                    create_obj_response_file + [\
                    '$(CC_LINK) /nologo $(LDFLAGS) $(LDFLAGSEXTRA)' + objects + ' $(LINKFILES) /out:$@ $(LIBDIRS) $(LIBS) /MANIFEST /MANIFESTFILE:$*.manifest',
                    'mt.exe -nologo -manifest $*.manifest -outputresource:$@;1',
                    ])
至此,可以明白是 self.version 的值不正确。而执行命令 cl 获取编译器版本时,stderr的可能输出如下
中文版 VC2008输出
用于 80x86 的 Microsoft (R) 32 位 C/C++ 优化编译器 15.00.30729.01 版
版权所有(C) Microsoft Corporation。保留所有权利。
 
用法: cl [ 选项... ] 文件名... [ /link 链接选项... ]
 
英文版VC2010输出
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]
 
可见是解析 stderr 时出问题了。如下所示,只需将 match 改search 即可
 
    def __init__(self, cc=None, x64=False):
        self.x64 = x64
        msvc_compiler_environ = find_msvc_env(x64)
        Platform.__init__(self, 'cl.exe')
        if msvc_compiler_environ:
            self.c_environ = os.environ.copy()
            self.c_environ.update(msvc_compiler_environ)
            # XXX passing an environment to subprocess is not enough. Why?
            os.environ.update(msvc_compiler_environ)
 
        # detect version of current compiler
        returncode, stdout, stderr = _run_subprocess(self.cc, '',
                                                     env=self.c_environ)
        r = re.search(r'Microsoft.+C/C\+\+.+\s([0-9]+)\.([0-9]+).*', stderr)
        if r is not None:
            self.version = int(''.join(r.groups())) / 10 - 60
        else:

 见 https://bugs.pypy.org/issue1524

 
 

转载于:https://www.cnblogs.com/JesseFang/p/3167512.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值