与子进程

时间:2017-02-21 17:17:30

标签: python xbuild

我有一个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.

非常感谢任何输入。我在这里碰到了我的头。

0 个答案:

没有答案