Windows 10のAnniversary Updateで追加された Bash on Windows を使ったら、Atomのscriptパッケージ でC++をお手軽コンパイルできるんじゃないかと思ったけど、結局できなかった作業ログです。
文字化け
まずは Atom、Scriptパッケージ、そしてBash on Windowsが入った状態で適当なcppファイルを用意して、Ctrl+Shift+Bを押してみます。
なんかエラー吐いてるっぽいけど、文字化けして読めず。。
文字化けを解消する方法を少し調べてみたけど、それっぽいものが見つからず。
ソースコードを見てみる
ファイルの種類からそれぞれコマンドを投げる部分のコードはこちらで読むことができます。
https://github.com/rgbkrk/atom-script/blob/master/lib/grammars.coffee
WindowsでC++をコンパイルする部分はこの通り。特に変なことはしていません。
else if GrammarUtils.OperatingSystem.isWindows() and GrammarUtils.OperatingSystem.release().split(".").slice -1 >= '14399' "File Based": command: "bash" args: (context) -> ["-c", "g++ -Wall -include stdio.h -include iostream '/mnt/" + path.posix.join.apply(path.posix, [].concat([context.filepath.split(path.win32.sep)[0].toLowerCase()], context.filepath.split(path.win32.sep).slice(1))).replace(":", "") + "' -o /tmp/cpp.out && /tmp/cpp.out"]
実際に実行されているコマンドは?
実際にログを確認してみても、期待通りの引数でbashが実行されています。
[Command: bash -c 'g++ -Wall -include stdio.h -include iostream '/mnt/c/Users/
このコマンドをbashから実行してみると、問題なく動く。
$ bash -c 'g++ -Wall -include stdio.h -include iostream '/mnt/c/Users/<hogehoge>/test.cpp' -o /tmp/cpp.out && /tmp/cpp.out' hello world
ではコマンドプロンプトから実行するとどうでしょう。
お?これか?
シングルクォートが犯人?
下のように、g++コマンドをかこっているシングルクオーテーションをダブルクオーテーションに変えてあげたら、コマンドプロンプトでもコンパイルを実行できました。
bash -c "g++ -Wall -include stdio.h -include iostream '/mnt/c/Users/<hogehoge>/test.cpp' -o /tmp/cpp.out && /tmp/cpp.out'
つまり、こういうことです。
bashにはシングルクォートで囲った部分全部が引数として送られて欲しかったのですが、コマンドプロンプトは&&の前後の文字列を別々のコマンドとして認識してしまって
bash -c "g++ -Wall -include stdio.h -include iostream '/mnt/c/Users/
と
/tmp/cpp.out'
という2つのコマンドとして認識してしまったわけです。
(参考:Command shell overview: Scripting; Management Services | Microsoft Docs)
というわけで、scriptパッケージのコードを書き換えて再度試してみましたが、結局同じエラーメッセージが表示されてコンパイルできませんでした。
英語環境を用意してみる
やっぱりあの文字化けしているエラーメッセージが何言ってるのかわからないとどうにもならない、ということで英語環境を用意しました。
すると、こんなことを言っていました。
'bash' is not recognized as an internal or external command,
operable program or batch file.
なんと。bashが見えてない?
Atomが32bitだったことが原因
いろいろ原因を調べてみたのですが、結局原因はAtomが32ビットのバイナリなのに対し、bashが64ビットのバイナリだったことでした。
パッケージ中のrunner.coffeeというコードを読むと分かりますが、実際にコンパイルを実行するプロセスはBufferedProcessというNode.jsのchild_processのラッパーを使って実装されています。
なので、当然コンパイルも32ビットのプロセス内で走っているわけです。
原因はわかった、だけど、、、
これで原因はわかりました。Atomとbashを64ビットか32ビットに統一してあげればよさそうです。
というわけで、64bitのAtomをインストールしてみようとそましたが、ざっと公式ページを見てみても、Windowsの64ビットバイナリは見つかりません。
Issueを検索してみると、まだ64bitのバイナリはリリースできる状態にないようです。
Windows 64bit release · Issue #4881 · atom/atom · GitHub
あまり乗り気はしませんが、32bitのbash on windowsは存在するのでしょうか。軽く探してみた限り、なさそうに見えます…。
というわけで、現時点では、Bash on Windowsを使ってScriptでC++をコンパイルはできなさそうです。。