2016-06-12 91 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文件的目錄。感謝所有人試圖提供幫助。