このページ上での記法についての注意
"ファイル生成時にすでに値が設定されているとき変更しない": {
"ex" : "%{default}"
}
"入力するべき文字列Aは環境や設定によって変化する": {
"ex" : ["writed","replaced"],
"ex.1" : ["&{A}","something"],
"ex.2" : ["I like &{A}.", "I like something."]
}
"一部VSCode側などで置換されるものもある。":{
"ex": ["${workspaceFolder}","${workspaceFolderBasename}","${SIV3D_0_4_2}"]
}
前提(あると望ましい)
- 環境がWindowsであること。また、それがOpenSiv3Dの動作環境を満たすこと。
Macでは既に専用エディタ以外で開発する方法が示されている。(なお、今回はこちらの方法を参考にしている。)
Xcodeを開かずにOpenSiv3Dを使いたい
[https://qiita.com/makia/items/3188b08670f178104f6d]LinuxでもVimにて開発するための手法が明示されている。
OpenSiv3D Linux版をVimで
[https://qiita.com/higashi000/items/fcdf0af788e54acdc179]
- Visual StudioおよびVisual Studio Codeがインストールされていること。
Visual Studio Codeの拡張機能
C/C++
が導入されていること(IntelliSenseに必要)。(
C/C++
のIntelliSenseの基本的な使い方が分かっていること。)(Visual Studio Code内の概念「タスク」の基本的な使い方をわかっていること。)
(batファイルの使用方法、作成方法を理解していること。)
実行環境
- Windows 10 Home 1903
- Visual Studio 2019 16.4.2
- OpenSiv3D 0.4.2
やることを端的に換言すると
- 任意の場所にVisual Studio上でOpenSiv3Dテンプレートからプロジェクトを生成する。
- C/C++ IntelliSenseで適切に設定する。
- ビルドタスクを設定する。
OpenSiv3Dの製作者である@Reputlessさんが今回のものを簡潔にまとめています。必要なファイルや記述内容が一通りまとまっています。
https://gist.github.com/Reputeless/9cad2d052c6602d442d37d88c820a13a#file-vsdevcmd-debug-bat-L4
任意の場所にVisual Studio上でOpenSiv3Dテンプレートからプロジェクトを生成する。
Visual Studio上でOpenSiv3Dテンプレートを選択しプロジェクトを自分の好きなフォルダに生成する。1
C/C++のIntelliSenseを適切に設定する。
この作業で、VSCode上でOpenSiv3Dの補完機能を効かすことができる。
この生成したプロジェクトのフォルダにある、プロジェクト名の(拡張子がvcxprojであるファイルを含む)フォルダをワークスペースとしてVSCodeで開く。
コマンドパレット(Ctrl+Shift+P)にてC/C++ Edit Configurations (JSON)
を実行する。
すると、ワークスペースでは.vscode\c_cpp_properties.json
という「C/C++のIntelliSense」に対する設定用のjsonが生成される。
ここで、configurations
オブジェクトに対して以下のように設定する。
%{default}
ここにある値はファイル生成時のデフォルトのままで(もともとなければそのままで)
&{VERSION}
OpenSiv3Dのバージョン番号のピリオド(.)をアンダーバーに置換したもの。
今回の場合であれば、0.4.2であるから0_4_2となる。
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"${SIV3D_&{VERSION}}/include",
"${SIV3D_&{VERSION}}/include/ThirdParty"
],
"defines": [
"${default}"
],
"windowsSdkVersion": %{default},
"compilerPath": %{default},
"cStandard": %{default},
"cppStandard": %{default},
"intelliSenseMode": "msvc-x64"
}
],
"version": %{default}
}
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"${SIV3D_0_4_2}/include",
"${SIV3D_0_4_2}/include/ThirdParty"
],
"defines": [
"${default}"
],
"windowsSdkVersion": "10.0.18362.0",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "msvc-x64"
}
],
"version": 4
}
と追加でインクルードするディレクトリが定義されている。 ちなみに、 引用
IncludePathのプロパティについて
ここは、Visual Studioで生成したOpenSiv3Dプロジェクトのプロパティ>VC++ ディレクトリ>インクルードディレクトリを覗いてもらえば分かると思う。
$(SIV3D_&{VERSION})\include
$(SIV3D_&{VERSION})\include\ThirdParty
”${SIV3D_&{VERSION}}/include"
だけを指定するといくつかのヘッダーファイルが発見できないと怒られる(一敗)SIV3D_&{VERSION}
は環境変数である。これはOpenSiv3Dのインストール時に定義されている。これを使えば短く書くことが出来る。
[https://twitter.com/Osmium_1008/status/1218811718568005632?s=20]
C/C++ IntelliSenseにて使用するコンパイラをgccにしてコーディングしてみよう。 一番肝心なSystem::Update()すら補完機能や静的解析に反応されず、コーディング中にエラーとして報告される始末。一応ヘッダーファイルを直接VSCodeで開くと認識されるようになるのだが、毎回このように開くのは面倒くさくてやってられない。 また、コンパイル,ビルドするので、各ファイルの関係を記述するためにMakefileなどを打ち立てなければならない。DxLibなどでは必要なライブラリやヘッダを指定すればよかった。 出来ないと断言したのは決してコーディング環境を立てるのが面倒くさいということだけが理由ではない。 引用
せっかくVSCodeでやるんだからVisual Studioから完全に独立してgccコンパイラでなんとかできないの?
出来ない。
すると殆どのヘッダーファイルに含まれる関数は補完機能やコードの静的解析に認識されているのだが、一部直接システムに関わってくるようなヘッダーファイルなど、つまりSystem.hppやMouse.hppなどが認識されていないことが分かる。(エラーに叱られるから)
しかし、OpenSiv3Dは違い、インクルードディレクトリ,ライブラリ走査対象を指定してやるだけではうまくいかない。Resourcesとして大量の画像やアイコンやengineが含まれている。これらのものを読み込むために依存関係を書かなくてはならないのだ。(しかもResourcesを毎回コピーしてくる必要がある。)(しかしこれはまだ簡単に解決できそう)
gccではどう頑張ってもOpenSiv3D(Windows)プロジェクトをビルドできないのだ。
Platform.hppに含まれるマクロを見てもらえればわかるのだが、「コンパイラがMSVCであり、2019以上のバージョン」でなければエラーが発生して落ちるようになっている。
こうされているのは、一部のOpenSiv3Dの実装がVisual Studio SDKに依存しているためだ。つまりWindowsにおいてはVisual Studioと関わるものでなければビルドできないことを意味する。完全にVisual Studioから独立することはできない。
gccでの補完機能や静的解析がうまく機能しなかったのはそのヘッダがVisual Studio SDKに依存している部分だからなのだろうか…?
[https://twitter.com/Reputeless/status/1208297249039503363]
[https://twitter.com/Reputeless/status/1110176034731655168]
プロジェクトをDebugビルドする。
バッチファイルvsdevcmd-debug.bat
をワークスペース内のパスの指定しやすい場所に作成する。
ここではワークスペース内で一番上層の場所に配置した。
vsdevcmd-debug.bat
はこのようにする。
&{PathToVcvars64.bat}
「x64 Native Tools Command Prompt for VS 2019」ショートカットのプロパティを開き、そこのリンク先を確認すると
%comspec% /k &{PathToVcvars64.bat}
と定義されている。(上記の文字列中にある変数の場所がパスに該当しているはずだ。)
call "&{PathToVcvars64.bat}"
msbuild ".\\"%1".vcxproj"
cd App
".\\"%1"(debug).exe"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
msbuild ".\\"%1".vcxproj"
cd App
".\\"%1"(debug).exe"
これで、コンソールにて
&{BaseName}
このワークスペースの名前
> vsdevcmd-debug.bat &{BaseName}
> vsdevcmd-debug.bat OpenSiv3DProject
と入力すればしっかりとDebugビルドが行われる。 ここで、妙な記述がある。「x64 Native Tools Command Prompt for VS 2019」のショートカットのプロパティまで開いていることについて解説する。 x64 Native Tools Command Prompt for VS 2019などで実行できるMsbuildなど様々なコマンドは、普通に起動しただけのコマンドラインでは実行できない(定義されていない)。 じつはショートカットのプロパティの「リンク先」では、コマンド文字列を入力することでそのコマンドをしっかりと実行できるのだ。(つまりリンク先にパスを入力された状態でショトカをクリックすることは、ターミナルでパスを書いて実行するといったことと似ている?) Programming Field: Cmd - DOS コマンド一覧 こういったことから、for VS 2019専用のコマンドが普通のコマンドプロンプト上で使えるのだ。
Command Prompt for VS 2019について
Developer Command Prompt for VS 2019やx64 Native Tools Command Prompt for VS 2019はいわゆるVisual Studioでやっているビルドだとかのものをそのままコマンドプロンプト上で実行できるようにしたものである。(ここ怪しい)(Power Shell版もあるよ!)
ここから、この二つのコンパイラは根本から違うものとして考えてしまいそうだが、実際はそうでもなく、x64 Native Tools Command Prompt for VS 2019などのショートカットではコマンドプロンプトを普通に起動して別のところに配置されているバッチファイルを実行しているに過ぎない。このバッチファイルのパスは&{PathToVcvars64.bat}
に該当する。
つまりこのバッチファイルがただのCommand Promptをfor VS 2019たらしめている(?)%comspec% /k &{PathToVcvars64.bat}
%comspec%
というのは環境変数で、コマンドプロンプトまでの絶対パスに置換される。
/k
というのはこののちに来るバッチファイルなどの実行可能ファイルの動作後、ターミナルを終了させずにそのまま続けて実行するためのオプションだ。
[https://www.pg-fl.jp/program/dos/doscmd/cmd.htm]
なお、Developer Command Prompt for VS 2019ではなく、x64 Native Tools Command Prompt for VS 2019を選択したことには訳がある。
前者でOpenSiv3Dプロジェクトをビルドしようとすると32bit環境はもうサポートしないよと諭されるのだ。どうやらDeveloper Command Prompt for VS 2019はx86環境らしい…?
AdminWeb: バッチファイル実行時に引数を渡す 文字列の結合には、他言語みたく演算子は特に必要ない。 CX's Memo(Windows関連): Windowsコマンドプロンプト基礎文法最速マスター また、その引数は、タスク側(バッチファイル呼び出し側)で
%1ってなんぞや?
今回定義したバッチファイルvsdevcmd.batは、引数をとる。
コマンドプロンプト上での文法について考えてみる。
このように「%n」とすることでバッチファイルがn番目の引数を取れる。(0<=n<=9,nは自然数)
[https://www.adminweb.jp/command/bat/index6.html]
[https://windows.g.hatena.ne.jp/cx20/20100203/p1]${workspaceFolderBasename}
としてある。これはVisual Studioで生成されたプロジェクトのファイル構成を見てもらえればなんとなく分かってもらえるのではないだろうか。
そうなると、指定の仕方としてはmsbuild ".\\"%1".vcxproj"
となる。
これは実際には".\\${workspaceFolderBasename}.vcxproj"
に該当する。
なぜわざわざ引数を使ってこのような遠回りなことをしたのかというと、この置換変数${workspaceFolderBasename}
はtasks.jsons
などの一部jsonファイルの中にあるものでしか直接置換されないためだ。
自分が置いたバッチファイルまでは置換の走査対象とはならないのだ。
拡張子vcxprojのファイルには、(これをテキストエディタなどで開いてみればわかるのだが)それぞれのビルド時の設定、Resource Filesのインクルード設定等も全部まとまってXML形式で記述されている。 Microsoft Visual Studioのドキュメント: MSBuild
msbuildとvcxprojについて
msbuild ".\\"%1".vcxproj"
これを引数にしてやる必要があるのだ。
[https://docs.microsoft.com/ja-jp/visualstudio/msbuild/msbuild?view=vs-2019]
画像フォルダを追加する際プロジェクトに自動で追加されない問題
カレントディレクトリが App ではないことは、cd
どそれに伴うパスの変更で解決できる。
cd App
".\\"%1"(debug).exe"
プロジェクトをReleaseビルドする。
同様にバッチファイルvsdevcmd-release.bat
を制作する。そして以下のように編集をするとよい。
call "&{PathToVcvars64.bat}"
msbuild ".\\"%1".vcxproj" /p:configuration=release
cd App
".\\"%1".exe"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
msbuild ".\\"%1".vcxproj" /p:configuration=release
cd App
".\\"%1".exe"
実行する際には以下の様に
> vsdevcmd-release.bat &{BaseName}
> vsdevcmd-release.bat OpenSiv3DProject
と入力すればしっかりとReleaseビルドが行われる。 引用
MSBuildとRelease
/p:configuration=release
をMSBuildのオプションとして記述するとReleaseビルドとして行われる。
[https://twitter.com/Osmium_1008/status/1218790630563823617?s=20]
チュートリアル: MSBuild の使用
[https://docs.microsoft.com/ja-jp/visualstudio/msbuild/walkthrough-using-msbuild?view=vs-2019]
ビルドタスクとして設定する。
コマンドパレットにてTasks: Configure task
を実行する。
すると、.vscode/tasks.json
が生成される。
配列tasksに対し以下のオブジェクトを追加する。
&{MSBuild}
任意の文字列。ここでは実行するタスクを選択する際に出てくるタスクの名前が要求されている。私はMSBuildとしている。
{
"tasks": [
...
{
"label": "&{MSBuild}-debug",
"type": "process",
"command": "vsdevcmd-debug.bat",
"args": ["${workspaceFolderBasename}"],
"group": "build",
"presentation": {
"reveal": "always"
},
"problemMatcher": "$msCompile"
},
{
"label": "&{MSBuild}-release",
"type": "process",
"command": "vsdevcmd-release.bat",
"args": ["${workspaceFolderBasename}"],
"group": "build",
"presentation": {
"reveal": "always"
},
"problemMatcher": "$msCompile"
},
...
]
}
Ctrl+Shift+Bを押すなどして、「実行するビルドタスクを選択」を表示させると、&{MSBuild}-debug
,&{MSBuild}-release
が表示されているはずなので、これをそのままタスクとして実行させると…
見事ビルドタスクとしてOpenSiv3Dプロジェクトをビルドすることに成功した。
今後の課題
- 任意の場所にVisual Studio上でOpenSiv3Dテンプレートからプロジェクトを生成する。->Visual Studio外でこれを実行できないか?
- [×]
Releaseビルドに対応できていない
引用,参考文献
- 修正
- (画像フォルダでプロジェクトに自動で追加されない問題について) [https://twitter.com/Osmium_1008/status/1218820716788760576]
- (SIV3D_(VERSION)環境変数) [https://twitter.com/Osmium_1008/status/1218811718568005632]
- (Releaseビルドについて) [https://twitter.com/Osmium_1008/status/1218790630563823617]
- (Windowsにおいてgccコンパイラではコンパイルが出来ない) [https://twitter.com/Reputeless/status/1208297249039503363] [https://twitter.com/Reputeless/status/1110176034731655168]
- Microsoft Visual Studioのドキュメント: MSBuild [https://docs.microsoft.com/ja-jp/visualstudio/msbuild/msbuild?view=vs-2019]
- チュートリアル: MSBuild の使用 [https://docs.microsoft.com/ja-jp/visualstudio/msbuild/walkthrough-using-msbuild?view=vs-2019]
- Visual Studio Code Docs: c_cpp_properties.json reference [https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference]
- Visual Studio Code Docs: Customizing default settings [https://code.visualstudio.com/docs/cpp/customize-default-settings-cpp]
- Visual Studio Code Docs: Configure VS Code for Microsoft C++ [https://code.visualstudio.com/docs/cpp/config-msvc]
- Visual Studio Code Docs: Integrate with External Tools via Tasks [https://code.visualstudio.com/docs/editor/tasks]
- WGGの活動log: Visual Studio Code で DxLibの開発をする [http://wgg.hatenablog.jp/entry/20170920/1505919082]
- stack overflow: What's the difference between process and shell in vscode tasks.json [https://stackoverflow.com/questions/54306943/whats-the-difference-between-process-and-shell-in-vscode-tasks-json]
- Qiita: VS Codeの設定をキレイに変数置換 [https://qiita.com/ShortArrow/items/dc0c8cacd696154510f1]
- AdminWeb: バッチファイル実行時に引数を渡す [https://www.adminweb.jp/command/bat/index6.html]
- CX's Memo(Windows関連): Windowsコマンドプロンプト基礎文法最速マスター [https://windows.g.hatena.ne.jp/cx20/20100203/p1]
ここまでのみちのり
- https://scrapbox.io/appbirdNotebook/2019%2F12%2F20-2019%2F12%2F21の試み
- https://scrapbox.io/appbirdNotebook/2019%2F12%2F26の試み
- https://scrapbox.io/appbirdNotebook/2020%2F01%2F13の試み
@Reputelessさん,@Beat7501さん,@Osmium_1008さんなどその他の人々のおかげで、ものすごく時間がかかりつつもなんとかここまでたどり着くことが出来ました。
感謝しかありません。本当にありがとうございました。
-
正直ここも、特定のvsdevcmdコマンドをVSCodeのタスクに登録してしまって、VSを開かずとも生成するみたいなことができそうな気もするけど…(今のところ分かっていない) ↩