‫こんにちは､ ようこそ｡
‫この講義では､ Unreal で C++ ファイルをコンパイルする際の主な手順を理解することになります｡
‫さっそく､ その仕組みを見てみましょう｡
‫だから､ そろそろ他のファイルから､ 外からのコードを使い始める時期が来ていて､ C++でこの仕組みを学ぶ必要があるんだ｡
‫そのためには､ 少し回り道をして､ C++のコードをバイナリにコンパイルするときに何が起こっているのか､
‫より詳しく理解する必要があります｡
‫そこで､ ここではそのコンパイルの手順を紹介します｡
‫まず､ あなたのコード､ C++ファイル､ ヘッダーファイルが､ さまざまなテキストファイルで用意されます｡
‫これらは､ アンリアル・ヘッダー・ツールと呼ばれるツールに供給されます｡
‫さて､ このツールは､ 非現実的な特定のシンタックスの断片をすべて取り出し､ それを使ってさらにC++のコードを生成する役割を担っています｡
‫このアンリアル特有の構文､ 大文字の新しいクラスはアンリアル特有の構文､
‫そしてクリプト・リーダーAPIのもの､ 生成されたボディの例をいくつか見てみましょう｡
‫基本的には､ アンリアル・ヘッダー・ツールは､ コードの中にあるさまざまな構文の断片を見て､ 「よし､
‫仕事をしなければ」と思うわけです｡
‫中に入って､ いろいろと追加する必要があるんです｡
‫これは､ 生成されたボディを､ Unreal を使用する際に私たちの生活を便利にするコードの束に置き換えるものです｡
‫Uプロパティや新機能といったこともやっています｡
‫設計図の世界と通信できるように､ 必要なものをすべて追加しています｡
‫それが最初の一歩なんですね｡
‫アンリアル特有のものをすべて実際のC++に変換するのです｡
‫実際のC++を手に入れたら､ それを標準的なC++のコンパイルプロセスに投入するのだが､ これには3つのステップがある｡
‫1つ目は､ 前処理を行うステップで､ これは実際にはC++のどの構文にも触れることができ､ 実際にはハッシュで始まる行だけを扱います｡
‫そこで､ このような前処理ディレクティブをいくつか用意しました｡
‫これらはプリプロセッサーで処理されます｡
‫次のステップは､ 実際にコンパイラと呼ばれるものです｡
‫コードを受け取って実行可能なバイナリに変換するのですが､ 個々のC++､ いわゆる翻訳ユニット､
‫基本的にはC++ファイルに対してのみ行うため､ このステップは完全ではありません｡
‫つまり､ C++ファイルを受け取って､ それを個別にバイナリに変換するのです｡
‫そして､ 3番目のステップがリンカーで､ これらすべてをまとめて､ 実際に1つの実行ファイルを実行できるように出力します｡
‫では､ これらの標準的なコンパイルの手順を､ サンプルファイルを使ってもう少し詳しく見てみましょう｡
‫そこで､ ゲームがあったと想像してください｡
‫CP しかも､ やっていることは1と1を足すだけなので､ とてもとてもシンプルなゲームなのですが､
‫1と1を足すには､ 数学の別のファイルで宣言されている関数を使わなければならないのです｡
‫H だから､ 数学が宣言しているのです｡
‫ADですが､ 実は何をするものなのか定義されていないんです｡
‫だから､ それは数学でやり過ごす｡
‫CP そして､ 実にシンプルな実装であることがおわかりいただけると思います｡
‫さて､ プリプロセッサのステップでは何が起こるのでしょうか？
‫まあ､ さっきも言ったように､ ハッシュで始まるプリプロセッサーディレクティブを処理するものです｡
‫つまり､ ハッシュにはmathが含まれていて､ 基本的にはmathにあるものをすべてここにコピーすればいいということです｡
‫この2つのファイルを組み合わせて､ Game Iという新しい出力ファイルを作成するのですが､
‫基本的にGamesがインクルードされています｡
‫これでGame IIはADD操作の定義を得たことになり､ 次に数学DHCPでプリプロセッサを実行します｡
‫しかし､ プリプロセッサーディレクティブを持たないため､ 基本的には何も変更されません｡
‫次のステップはコンパイルで､ おそらく最も重要で複雑なステップです｡
‫コンパイルが行うのは､ 個々のファイルに含まれるC++をバイナリに変換することですが､
‫完全なバイナリではありません｡
‫そのため､ 後でリンカーがそれを埋める必要があります｡
‫つまり､ リンカーはゲームのobjファイル用に作られたバイナリと､ マスターファイル用に作られたバイナリを一緒にして､
‫ゲームを作ろうとしているのです｡
‫XYは､ 両方のバイナリを組み合わせたもので､ 最終的には､ 必要なすべての定義を備えているため､ 実際に実行できる完全な実行ファイルになります｡
‫さて､ なぜこのような複雑なプロセスを踏んでいるのでしょうか｡
‫ここでの考え方は､ 「変更さえすれば､ 私たちのコンパイル時間を短縮することができる」というものです｡
‫DHCPをゲーム化するために｡
‫実は､ コンパイル作業を全部実行する必要はないんです｡
‫ゲームDHCPに関わるビットを実行するだけなので､ プリプロセッサをCP上でだけ実行し､ コンパイラをゲーム上でだけIに実行し､
‫あとは先ほどの数学のobjファイルを再利用すればいいわけです｡
‫その点では何も変わっていないので､ 再コンパイルする必要はないですね｡
‫同様に､ 数学のドットCPを変更するだけなら､ ゲームのobjファイルを再コンパイルする必要がないので､ この処理の方が効率的で､
‫そもそもなぜこのような処理をしているのか､ その理由を説明します｡
‫そこで､ ちょっとした実験を行い､ なぜHを入れたり､ CPファイルを移動させたりするのか､ 考えてみたいと思います｡
‫その理由は何でしょうか？
‫moveを含めずにC++ファイルをコンパイルすることはできないのでしょうか？
‫H そこで､ これから行う実験は､ hash includeの行をコメントアウトすることです｡
‫そこで､ ダブルフォワードスラッシュを使って､ その行の前にコメントをつけると､ 基本的にプリプロセッサがファイルの内容に置き換えるのではなく､
‫プリプロセッサによって取り除かれるようになります｡
‫そして再コンパイルします｡ 出てきたエラーメッセージを見て､ 私たちがこの手を入れたのは何のためなのか､
‫その内容を理解してほしいと思います｡
‫ビデオを一時停止して､ 試してみてください｡
‫なるほど｡
‫お帰りなさい｡
‫そこで､ この行の先頭にダブルフォワードスラッシュを付けて､ 基本的に無効にしてしまいましょう｡
‫そして､ コントロールのalt f 11を行い､ ライブコーディングの出力を見てもらう｡
‫そのため､ 非常に早い段階で､ いくつかのエラーが発生しました｡
‫つまり､ ムーバーはクラスでも名前空間でもなく､ 他にもいろいろあるのです｡
‫プライマリテックのコンポーネントが宣言されていないこと､ superがクラスや名前空間でないこと､ ownerが未知の識別子であることを言いたいのです｡
‫つまり､ ムーバを定義していない､ 宣言していない､
‫ということです｡
‫だから､ わからないんです｡
‫C++コンパイラは､ これが何であるかわからない､ と言う｡
‫だから､ 可動子Hがクラスを宣言しているから､ 可動子Hを含めてハッシュになっているわけです｡
‫U moverはクラスで､ コンポーネントを演じるあなたから派生して､ こういうメソッドを持っているなどと書いてあります｡
‫そのクラスであることの意味を宣言しているのです｡
‫だから､ その宣言がないと､ C++コンパイラは続行できないのだ｡
‫そのために､ そのヘッダーファイルをインクルードする必要があるのです｡
‫素晴らしい内容です｡
‫これで､ C++ のコンパイル､ 特に Unreal での C++ のコンパイルに関わるプロセスを少しは理解していただけたかと思います｡
‫それでは､ 次回の講義でお会いしましょう｡