Wie der Name schon sagt, dient es dazu die Includes zu optimieren und überflüssige zu entfernen, um Compilierzeit zu sparen und den Code übersichtlicher zu machen.
Das Ding ist eher ein Prototyp ("alpha quality software -- at best", wie die Webseite es sagt), es produziert eine Reihe falscher Ergebnisse, aber vieles ist doch ganz brauchbar.
Da ich keine Lust hatte selber zu kompilieren, habe ich Binaries gesucht und auch gefunden: http://www.ishani.org/web/articles/code/clang-win32/
Das sind inoffizielle Clang-Build für Windows, interessant daran ist aber, dass eine clang-IWYU.exe beiliegt, die ohne Abhängigkeiten funktioniert.
Das Tool bedient man über die Commandozeile, was für Windows-User natürlich etwas ungewohnt ist. Außerdem hat clang massive Probleme die Standardbibliothek oder boost zu parsen, weswegen man mit Fehlermeldungen bombardiert wird.
Ich habe daher ein Python-Skritp geschrieben, mit dem man IWYU auf alle Dateien eines Projektes anwenden kann und die Ergebnisse in einer Textdatei geliefert bekommt. IWYU hat zwar auch ein Skript, das Includes automatisch anpasst, aber da das Tool nicht soo zuverlässig ist, will man das vermutlich lieber von Hand machen.
In den ersten zwei Zeilen vom Skript trägt man das Verzeichnis der Quellcodedateien und die Include Verzeichnisse ein. In VC sieht man unter Projektoptionen die Command Line (Configuration Properties -> C/C++ -> Command Line), von dort habe ich die rauskopiert (alles mit /I), anschließend wird es noch umformatiert, damit Clang es versteht.
Dann kann man es starten und sollte eine IWYU-Result.txt bekommen, in der die Ergebnisse aller Dateien stehen.
Wie gesagt, man muss nochmal drübersehen, aber es ist definitiv schneller und einfacher, als alle Includes per Hand zu überprüfen.
Hier das Script:
Code: Alles auswählen
BaseDir="D:/Dev/Projects/Apocalyptical Age/Source/Render"
IncludeDirs=r'/I"C:\Libs\boost\boost_1_55_0" /I"C:\Libs\Assimp\install\include" /I"C:\Libs\glm" /I"D:\Dev\Projects\Apocalyptical Age\Source\Utilities" /I"C:\Libs\FreeImage\Dist"'
IncludeDirs=IncludeDirs.replace("/I", "-I")
def AnalyzeFile(FileName):
import subprocess, os
Command='clang-IWYU.exe ' + IncludeDirs + ' -w ' + ' --cwd="'+ BaseDir + '"' + ' "' + FileName + '"'
#print(Command)
#os.system(Command)
def run_command(command):
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return iter(p.stdout.readline, b'')
Start=False
Result=""
for l in run_command(Command):
line=l.decode("utf8")
if " should add these lines:" in line:
Start=True
if Start:
Result+=line
return Result
def AnalyzeDirectory(Directory):
import os
from os.path import join, relpath
file=open(join(Directory, "IWYU-Result.txt"), "w")
ext=(".h", ".hpp", ".c", ".cpp", ".inl")
for root, dirs, files in os.walk(Directory):
for name in files:
if name.endswith(ext):
print("analyzing ", join(root, name))
FileRes=AnalyzeFile(join(root, name))
#print(FileRes)
file.write("------- "+name+" ---------\n")
file.write(FileRes)
file.write("\n\n\n\n")
file.flush()
os.fsync(file)
file.close()
AnalyzeDirectory(BaseDir)