您的位置:首页 > 编程语言 > Python开发

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

2013-07-02 17:41 399 查看
在 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐