XcodeでCompileが走ったファイル一覧を表示する
XcodeでIncremental Buildが走った際に、具体的にどのファイルがCompileされたか表示する方法のメモです。
諸事情により、XcodeでIncremental Buildが走った際、具体的にどのファイルがCompileされたか知る必要があり、Xcode上で見れるBuild Logから読み取ろうにも諸々省略されていて読み取れず。。。
何か良い方法はないかなと模索していたところ、 @kateinoigakukunさんが SWIFT_EXEC
にwrapperかませるとよいかもとのことだったので、雑にscriptねじ込んで表示させてみました。
swiftc
の出力は(微妙に惜しい)JSON形式になっており、ちょっと修正を加えてやれば普通のJSON Textとして扱えます。具体的にはこのような感じになってます。
15002
{
"kind": "began",
"name": "compile",
"command": "\/Applications\/Xcode-11.4.app\/Contents\/Developer\/Toolchains\/XcodeDefault.xctoolchain\/usr\/bin\/swift -frontend -c -primary-file \/path\/to\/project\/\/sample-project\/sample-project\/View\/MainViewController.swift ..............................",
"command_arguments": [
"-frontend",
"-c",
"-primary-file",
"\/path\/to\/project\/sample-project\/sampel-project\/View\/MainViewController.swift",
.
.
],
.
.
}
123
.
.
この出力を若干修正してJSON Textとして読めるようにしつつ、実際にcompileされたファイルを表示するためのshell scriptとRubyコードが次です。超雑です。もっと良い書き方あればGistのコメントで教えて下さい🙏
require "json" | |
json_data = File.open("output.json") do |file| | |
JSON.load(file) | |
end | |
changed_files = json_data | |
.select { |block| | |
block["kind"] == "began" and block["name"] == "compile" | |
} | |
.map { |block| | |
args = block["command_arguments"] | |
idx = args.index("-primary-file") | |
args[idx+1] | |
} | |
puts changed_files |
#!/bin/sh | |
SWIFTC="swiftc" | |
SED="gsed" | |
RUBY="ruby" | |
RUBY_FIND_COMPILED_FILES="find_compiled_files.rb" | |
LOG_OUTPUT_FILE="output.txt" | |
LOG_JSON_FILE="output.json" | |
echo "Compiled files:" | |
$SWIFTC $@ 1>$LOG_OUTPUT_FILE 2>&1 | |
grep -E -v '^[0-9]+$' $LOG_OUTPUT_FILE | $SED -e 's/^}$/},/' -e '1s/{/[{/' -e '$s/},/}]/' > $LOG_JSON_FILE | |
$RUBY $RUBY_FIND_COMPILED_FILES | |
rm $LOG_OUTPUT_FILE $LOG_JSON_FILE |
このshell scriptとRubyコードを適当なところにおき、SWIFT_EXEC
というUser-Defined Build settingsを追加し、その値として先のshell scriptへのパスを設定します。

あとはBuildさせればこんな感じでBuild Logに表示されます。(Compile Swift source files
の行を展開させてやる必要があります)
Compiled files:
/path/to/project/sample-project/sample-projectView/MainViewController.swift
何かファイルを変更した後にIncremental Buildするケースでは問題なく動きます(多分)。ただ、Xcodeの仕様上、ファイルに変更が一切ない場合は直近のBuild Logが使い回されてしまい、実際にCompileはされていないのにCompileされたという表示がなされるので注意です。