Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exeプロジェクトでライブラリを生成させる #856

Conversation

berryzplus
Copy link
Contributor

目的

テストプロジェクトから利用するために、sakura.exeのobj群でライブラリを作るようにします。

変更内容

  1. sakura.vcxprojにカスタムのビルド後タスク(LIBコマンド実行)を追加します。
  2. LIBコマンドの出力ファイルをクリーン対象に含めるためにカスタムタスクを追加します。
  3. ビルドで出力フォルダにコピーされるbregonig.dllなどをクリーンの削除対象に含めます。

関連PR

#796(vs2017ソリューションにテストを組み込みたい)

本来は他の変更と合わせて#796に入れるつもりでしたが、このPRの変更内容だけでもかなりお腹いっぱいになれるボリュームがあると感じたので、分割することにしました。

テストプロジェクトでexeと同じコードを使えるように、LIBコマンドでobjをまとめるようにする。
この変更により、$(IntDir)sakura_core.libが生成されるようになる。
MsBuildがクリーン時に参照する削除ファイルリストにファイル名を追加し、
生成された$(IntDir)sakura_core.libがクリーン時に削除されるようにする。
作業ついでに既存の出力成果物もクリーン対象に含めておく。
$(IntDir)と$(OutDir)に出力するファイルは、クリーン対象に含めることができる。
他のパスに出力する生成ファイルはこの方法では削除できないので別の手を考える必要がある。
@berryzplus berryzplus force-pushed the feature/generate_static_lib_for_tests branch from ccf2820 to de7a9a2 Compare April 17, 2019 06:20
@ds14050
Copy link
Contributor

ds14050 commented Apr 17, 2019

#579 (comment) で言及した件ですね。そちらで書いたようにプロジェクトファイルが自分では読めず、Visual Studio に読み込ませることもできず、「テストをコンパイル済みのエディタコードとリンクします #579」をアップデートする作業も「[WIP] vs2017ソリューションにテストを組み込みたい #796」によって無用になるのでできることがありませんが、PR の目的は認めています。

@berryzplus
Copy link
Contributor Author

#579 (comment) で言及した件ですね。

そうです。 #796 は vsソリューションに組み込むことが主眼なので、CMakeLists.txt には手を加えていませんが、やりたいことは同じです。cmake対応はどっかでやりたいですが、まずは vc++ のGUIでテストを使えるようにするのが先決だと思って動いてます。

そちらで書いたようにプロジェクトファイルが自分では読めず、Visual Studio に読み込ませることもできず、「テストをコンパイル済みのエディタコードとリンクします #579」をアップデートする作業も「[WIP] vs2017ソリューションにテストを組み込みたい #796」によって無用になるのでできることがありませんが、PR の目的は認めています。

「元々誰がやった」的な情報を残していくかどうかについては迷いがあるんですよね。
「可能なら残しておきたい」という思いと「日付と名前だけのコメントは理解の妨げになるから削りたい」という思いがあって、ぼくの中では後者の比重が高いように感じています。「コメント削ろう」とか「別なコードで書きなおそう」に原案否定の意思はないんですが。

今回のも「テストをコンパイル済みのエディタコードとリンクします #579」をベースに色々調べてみた結果でこういうPRができてきたわけで、元の発想が消えたわけじゃないと思うんです。

cmake側に関して、まだPRとかは作ってないんですけど、cmakeには 「テストをコンパイル済みのエディタコードとリンクします #579」の需要を満たすための機能 があるようです。add_library(Object Libries) を適用するにはvsソリューションに相当する部分のcmake化が必要ですが、適用すれば本体ソースとテストが参照するlibの更新を連動させられるはずです。この辺、PRを出してもらえるなら、その方がマージが速いと思うので可能なら是非。

@ds14050
Copy link
Contributor

ds14050 commented Apr 18, 2019

add_library(Object Libries) を適用するにはvsソリューションに相当する部分のcmake化が必要ですが、適用すれば本体ソースとテストが参照するlibの更新を連動させられるはずです。

Object Library は使途がよくわかりませんね。まさしく .obj のコレクションで、そのアーカイブ(.lib) とは別のもののようですが。「An object library compiles source files but does not archive or link their object files into a library.」

両者の間の微妙な違いについては、以前にもリンクを張りました>「static link について - 兼雑記」 しかし .obj のリストが公式に必要とされる状況があるのでしょうか。#579 はただの苦肉の策ですし。

@m-tmatma
Copy link
Member

この PR の動作確認は何をしてますか?

@berryzplus
Copy link
Contributor Author

berryzplus commented Apr 18, 2019

この PR の動作確認は何をしてますか?

レビューの一環として動作確認で試してほしいことを説明してほしい、と解釈しました。

  1. vs2017 でソリューションを開いてソリューションをビルドし、
    中間フォルダ(sakura_core/Win32/Debug) に sakura_core.lib が生成されること
  2. cleanした時に中間フォルダ(sakura_core/Win32/Debug) から sakura_core.lib が削除されること、です。

です。

@berryzplus
Copy link
Contributor Author

失礼。パスの例示が違ってますわ。

ちゃんと書くとこんな感じ。

論理名 MsBuild内記述 パス 説明 変化点
中間フォルダ $(IntDir) sakura_core/Win32/Debug/ 中間生成物(objなど) の出力フォルダ sakura_core.lib が 生成されるようになる。
出力フォルダ $(OutDir) sakura/Win32/Debug/ 最終生成物(exeなど) の出力フォルダ bregonig.dll などが Clean 時に削除されるようになる。

PRの評価としては、新規に追加した出力ファイルの生成確認ができれば十分だと思います。
Clean時の削除確認は、余裕があればやる、でよい認識。

実のところ、追加したライブラリを使ってテストプロジェクトのリンクが成功することころまで確認していますが、このPRを入れるにあたってそこまではみなくていいと思ってます。

@berryzplus
Copy link
Contributor Author

add_library(Object Libries) を適用するにはvsソリューションに相当する部分のcmake化が必要ですが、適用すれば本体ソースとテストが参照するlibの更新を連動させられるはずです。

Object Library は使途がよくわかりませんね。まさしく .obj のコレクションで、そのアーカイブ(.lib) とは別のもののようですが。「An object library compiles source files but does not archive or link their object files into a library.」

要するに、いまやってる *.obj のBLOBで拾ってきてリストを作る処理を、*.cpp のBLOBを元に勝手にやってくれる機能だと解釈しています。つまり、やることは現状と同じになるはずです。

LIB コマンドを使う場合LinkTimeCodeGeneration時間が掛かるので、msvcのリリースビルドではlibをつくるよりobjのリストを使うほうが速度的に有利になると思います。この話は完全に別件なんですけどもw

<ItemGroup>
<SakuraCore Include="$(IntDir)*.obj" />
</ItemGroup>
<LIB OutputFile="$(IntDir)sakura_core.lib" Sources="@(SakuraCore)" SubSystem="Windows" LinkTimeCodeGeneration="$(WholeProgramOptimization)" SuppressStartupBanner="true" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$(IntDir)sakura_core.lib ではなくて $(OutDir)sakura_core.lib だと思います。

https://docs.microsoft.com/en-us/cpp/build/reference/common-macros-for-build-commands-and-properties?view=vs-2017
によると $(IntDir)Path to the directory specified for intermediate files. とあります。

sakura_core.lib は中間ファイルではないと思います。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

↑ テストプロジェクトの入力ファイルになるはずで、別のプロジェクトの入力になるので
出力ファイルだと思います。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sakura_core.lib は中間ファイルではないと思います。

いいえ、中間ファイルとしての lib を生成しています。
ざっくりと言ってしまうと「拡張子がlibなだけでobjだと思ってください。」です。

LIBコマンドには色々な使い方があります。

今回はカスタムタスクを追加して中間ファイルとしてのlibを生成していますが、出力ファイルとしてのlibを生成する別なやり方もあります。出力ファイルとしてのlibには、テストで利用したいシンボル定義が含まれません。

テストプロジェクトで参照したいのは、本体プロジェクトの中間生成物です。

参照する対象はobjでもいいのですが、objを直接参照する構成にすると、テストプロジェクト側に各objの名前(約300個)を記述する羽目になります。参照を1つ書けば済むように、中間生成物としてのlibを生成しています。拡張子はlibですが中間生成物なんです。

以上がカスタムlibの出力先を中間フォルダ($(IntDir))としている理由です。

「どうしても出力ファイルにしたいんだ!」ということなら、出力ファイルとしてのlib生成(=MsBuildのImpLibタスク) のパラメータを調整して、エクスポートされないシンボルを除外しないように構成する必要が出てきます。(過去何度かトライしたことありますが、全シンボルを含んだlibを生成できたことはないっす。)

↑ テストプロジェクトの入力ファイルになるはずで、別のプロジェクトの入力になるので
出力ファイルだと思います。

上で書いた通り、テストプロジェクトに参照させたいのは、本体プロジェクトの中間ファイルです。本体プログラムとしてはエクスポートしないシンボルも参照に含めたいので、テストプロジェクトが参照するオブジェクトは中間ファイルである必要があります。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちょっと誤解を招く表現があるので捕捉。

テストプロジェクトが参照したいのが sakura_core/Win32/$(Configuration)/*.obj であるなら、それを直接プロジェクトに含まればいいじゃないか、という点について。

たしかうまくいかなかった(ような気がする)

#856 (comment) で描いているとおり、 LIB コマンドを使わないほうがReleaseビルド時のパフォーマンスは良いです。

というわけで、もう一回試してみます。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あっさりイケたし・・・ 😭

このPRは一旦潰して、変更結果は #796 に混ぜ込みます。
$(IntDir)sakura_core.lib の生成が不要になるので、クリーン時処理は別件になるかな。

@@ -1007,4 +1007,20 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Target Name="MakeSakuraCoreLib" AfterTargets="Link" Inputs="@(ClCompile)" Outputs="$(IntDir)sakura_core.lib">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここも同様

</Target>
<Target Name="AppendCleanTargets" BeforeTargets="CoreClean">
<ItemGroup>
<DeleteOnClean Include="$(IntDir)sakura_core.lib" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここも同様

@berryzplus berryzplus closed this Apr 20, 2019
@berryzplus berryzplus deleted the feature/generate_static_lib_for_tests branch April 20, 2019 05:07
@m-tmatma m-tmatma added the Won't Fix 対応しない【ChangeLog除外】 label Apr 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Won't Fix 対応しない【ChangeLog除外】
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants