我有一个Xamarin应用程序的python构建脚本,我需要根据语言环境编译成不同的ipa和apk。
该脚本操作info.plist和Android清单中的必要值,然后使用subprocess.popen构建每个版本以调用xbuild。或者至少就是它的假设。
问题是当我无论如何与子进程交互时(基本上我需要等到它开始更改下一个版本的值之前完成)
这有效:
build_path = os.path.dirname(os.path.realpath(__file__))
ipa_path = "/path/to/my.ipa"
cmd = '/Library/Frameworks/Mono.framework/Versions/4.6.2/Commands/xbuild /p:Configuration="Release" /p:Platform="iPhone" /p:IpaPackageDir="%s" /t:Build %s/MyApp/iOS/MyApp.iOS.csproj' % (ipa_path, build_path)
subprocess.Popen(cmd, env=os.environ, shell=True)
然而,它将导致python脚本继续与构建并行。
如果我这样做:
subprocess.Popen(cmd, env=os.environ, shell=True).wait()
Xbuild失败并显示以下错误消息:
Build FAILED.
Errors:
/Users/sune/dev/MyApp/iOS/MyApp.iOS.csproj: error :
/Users/sune/dev/MyApp/iOS/MyApp.iOS.csproj: There is an unclosed literal string.
Line 2434, position 56.
它在被调用的毫秒内失败,而通常构建过程需要几分钟
subprocess.popen的任何其他简写方法,如.call,.check_call,以及subprocess.poll和subprocess.communicate的底层操作都会导致同样的错误发生。
真正奇怪的是,即使调用time.sleep也会引发同样的错误:
subprocess.Popen(cmd, env=os.environ, shell=True)
time.sleep(2)
我不理解,因为据我所知,我也应该能够做到这样的事情:
shell = subprocess.Popen(cmd, env=os.environ, shell=True)
while shell.poll() is None:
time.sleep(2)
print "done"
基本上与调用shell.wait()
相同编辑:使用命令列表而不是字符串
如果我使用命令列表并且像这样使用shell = False
cmd = [
'/Library/Frameworks/Mono.framework/Versions/4.6.2/Commands/xbuild',
'/p:Configuration="Release"',
'/p:Platform="iPhone"',
'/p:IpaPackageDir="%s' % ipa_path,
'/t:Build %s/MyApp/iOS/MyApp.iOS.csproj' % build_path
]
subprocess.Popen(cmd, env=os.environ, shell=False)
然后就是结果:
MSBUILD: error MSBUILD0003: Please specify the project or solution file to build, as none was found in the current directory.
非常感谢任何输入。我在这里碰到了我的头。