2016-06-12 54 views
1

我试图编写一个Python脚本,它通过subprocess.Popen()调用g ++。exe文件并使用它将.cpp文件编译为一个.exe文件。问题是,不管我怎么努力的路径传递到源文件,我得到以下错误:在Windows上使用g ++从Python脚本编译C++代码

g++.exe: error: CreateProcess: No such file or directory

我的目录结构如下:

D:/Test/test.py 
D:/Test/external/mingw64/g++.exe 
D:/Test/c/client/client.cpp 

而且我的代码是:

import os, subprocess 

class builder(): 
    def __init__(self): 
     self.gccPath = os.path.abspath("external/mingw64/g++.exe") 
     self.sourceDir = os.path.abspath("c/client") 
     self.fileName = "client.cpp" 
     self.sourceFile = os.path.join(self.sourceDir, self.fileName) 

    def run(self): 
     command = [self.gccPath, self.sourceFile , "-o", "client.exe"] 
     print command 
     process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     n=1 
     while True: 
      nextLine = process.stdout.readline() 
      if nextLine == '' and process.poll() != None: 
       break 
      if nextLine != "" and nextLine != None: 
       print n, nextLine 
      n=n+1 

builder = builder() 
builder.run() 

只是一些我试图通过该路径的方式:

Command: ["D:\\Test\\external\\mingw64\\g++.exe", "c/client/client.cpp", "-o", "client.exe"] 
Command: ["D:\\Test\\external\\mingw64\\g++.exe", "c\\client\\client.cpp", "-o", "client.exe"] 
Command: ["D:\\Test\\external\\mingw64\\g++.exe", "D:\\Test\\c\\client\\client.cpp", "-o", "client.exe"] 

我也试过路过CWD到POPEN:

command = [self.gccPath, "client.cpp", "-o", "client.exe"] 
process = subprocess.Popen(command, shell=True, cwd=self.sourceDir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

总是同样的错误。我之前使用过Popen很多次,这通常都是一件小事,所以我现在很害怕我做错了什么。

+0

@ PM2Ring - 但我没有加入两条绝对路径,我加入了一个字符串的绝对路径。 我并不太在意路径外观,它们只是为了调试目的而被打印出来。如果当我得到这个工作,所有打印将被删除。 – Natsukane

+1

听起来像你正在尝试构建一个构建系统。为什么不使用现有的像SCons(http://scons.org/)或CMake(https://cmake.org/)? –

回答

0

这不是找不到的client.cpp文件,而是g++.exe。你可以知道,因为它是CreateProcess,会产生错误。如果是cpp文件,则CreateProcess会成功,只有这样编译器才会返回错误。

os.path.abspath("external/mingw64/g++.exe") 

这将从您给出的相对路径构建绝对路径。相对的意思是相对于当前目录,而不是python文件的目录。

如果你的G ++是在一个固定的树,一个更好的办法应该是从脚本名称构建路径,像这样:

os.path.join(os.path.dirname(__file__), "external/mingw64/g++.exe") 

的,你不相关的东西用abspath其他地方也是如此到当前的工作目录。

+0

试一下,我只是得到“系统找不到指定的路径”。我假设这是一个实际的编译器错误,client.cpp是问题吗? – Natsukane

+0

可能。是否引发异常,如果是,它是什么? – spectras

+0

另外,如果你仍然有'cwd = self.sourceDir',检查它是否是一个有效的路径(用'__file__'构造它就像刚刚改变'gccPath'一样)。 – spectras

0

我能解决我自己的问题,并得到一个工作的.exe用下面的代码:

import os, subprocess, json, glob 

class client(): 
    def __init__(self): 
     self.gccDir = os.path.abspath("external/mingw64") 
     self.sourceDir = "c/client" 
     self.fileName = "client.cpp" 
     self.sourceFile = os.path.join(self.sourceDir, self.fileName) 
     self.destFile = self.sourceFile.replace(".cpp", ".exe") 

    def run(self): 
     srcFiles = glob.glob(os.path.join(self.sourceDir+"/*.cpp")) 
     srcFiles.remove(self.sourceFile) 
     myEnv = os.environ.copy() 
     myEnv["PATH"] = myEnv["PATH"]+";"+self.gccDir 
     command = ["g++.exe", self.sourceFile, " ".join([x for x in srcFiles]), "-std=c++11", "-Os", "-o", self.destFile] 
     process = subprocess.Popen(command, shell=True, env=myEnv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     n=1 
     while True: 
      nextLine = process.stdout.readline() 
      if nextLine == '' and process.poll() != None: 
       break 
      if nextLine != "" and nextLine != None: 
       print n, nextLine 
      n=n+1 

命令结束是:

['g++.exe', 'c/client\\client.cpp', 'c/client\\utils.cpp', '-std=c++11', '-Os', '-o', 'c/\\client.exe'] 

路径看起来很丑陋,但工作。从srcFiles中手动删除sourceFile有点笨拙,但似乎有必要在命令中首先引用主文件。

This answer是非常有用的,并允许我暂时将PATH环境变量设置为任何我有g ++。exe文件的目录。感谢所有人试图提供帮助。