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

tests1 プロジェクトをリビルドしたりクリーンすると異なる構成のビルドに影響してしまう #1013

Closed
beru opened this issue Aug 24, 2019 · 12 comments
Labels

Comments

@beru
Copy link
Contributor

beru commented Aug 24, 2019

問題内容

x64/Win32, Debug/Release と4つの組み合わせの構成がありますが、ある構成で tests1 プロジェクトをリビルドしたりクリーンすると、異なる構成の sakura プロジェクトや tests1 プロジェクトのビルドを既に済ませていたのに再度ビルドを行わないといけなくなります。

おそらく依存関係が適切でなくて、異なる構成のファイルを巻き込んで変更したり削除してしまっているものと思われます。

再現手順

  1. sakura プロジェクトと tests1 プロジェクトのビルドを x64/Win32, Debug/Release の4つの組み合わせの構成の分だけ行います(tests1 プロジェクトが sakura プロジェクトに依存しているので、tests1 プロジェクトだけをビルドすれば基本的に良い筈です)。
  2. どの構成でも構わないので、tests1 プロジェクトをリビルドします。
  3. 異なる構成に切り替えて、sakura プロジェクトをビルドすると 1 で既にビルドを済ませていたのにビルドの処理が行われる事が確認出来ます。

再現頻度

毎回発生

問題のカテゴリ

  • ビルドの問題

関連チケット

#999, #1001

@beru beru added the UnitTest label Aug 24, 2019
@beru
Copy link
Contributor Author

beru commented Aug 24, 2019

なんかユニットテストフレームワークのライブラリのビルドの面倒を見る事にマンパワーが取られるのって不毛な気がするんですよね。。doctest を使えばそういう悩みから解消されるし、レガシーなGoogle Test とは違ってテスト自体の記述もすっきりと出来ます。そしてビルド時間も短縮されます。

@berryzplus
Copy link
Contributor

不備の心当たりがあるので「うっ!」という感じです:sob:

ときに、再現しませんでしたが手順あってます?

  1. Build > Batch Build で開いたダイアログでSelect AllしてBuild実行。⇒ 全環境ビルドされる。
  2. アクティブ構成(Win32 | Debug)でBuild実行。⇒ 5 uptodate と表示されてビルド走らない
  3. tests1 を右クリックして project only > Rebuild 実行。 ⇒ リビルド走って 5 succeeded と表示される
  4. アクティブ構成を(Win32 | Release)に切り替えてBuild実行。⇒ 5 uptodate と表示されてビルド走らない
  5. アクティブ構成を(x64 | Release)に切り替えてBuild実行。⇒ 5 uptodate と表示されてビルド走らない
  6. アクティブ構成を(x64 | Debug)に切り替えてBuild実行。⇒ 5 uptodate と表示されてビルド走らない

なお、3の手順で普通にRebuildするとWin32/x64切替でビルドが走ります。
これは、x64構成でもWin32のHeaderMakeを使っているのが理由で「仕様です(キリッ」な感じです。
対策としてはビルドの構成マネージャでx64の構成を変更したらよいです。
HeaderMakeはx64対応をする予定がないので、その点が若干不安ではありますが、おそらく問題はありません。

@beru
Copy link
Contributor Author

beru commented Aug 24, 2019

ときに、再現しませんでしたが手順あってます?

自分の方でもその手順で再確認してみますね。

自分は確認した時には Batch Build を使わずにコンボボックスの選択を切り替えて行ってました。
途中で Rebuild や Clean した後に 構成切り替えてビルドすると、ビルドする事が無い筈な時にもビルドが走ってしまう印象です。

なお、3の手順で普通にRebuildするとWin32/x64切替でビルドが走ります。
これは、x64構成でもWin32のHeaderMakeを使っているのが理由で「仕様です(キリッ」な感じです。
対策としてはビルドの構成マネージャでx64の構成を変更したらよいです。
HeaderMakeはx64対応をする予定がないので、その点が若干不安ではありますが、おそらく問題はありません。

それって、

  • HeaderMakeMakefileMake プロジェクトは Win32 プラットフォーム構成のみ。x64 は無し。
  • sakura プロジェクトが HeaderMakeMakefileMake プロジェクトに依存している。
  • tests1 プロジェクトが sakura プロジェクトに依存している
  • tests1 プロジェクトを クリーンやリビルドすると、依存しているプロジェクト群もそうされる。
  • x64 の sakura プロジェクトも Win32 側の HeaderMakeMakefileMake プロジェクトに依存しているので、Win32 選択時のクリーンやリビルドの余波を受ける

って事でしょうか?

うーん、微妙だなぁ。。

@beru
Copy link
Contributor Author

beru commented Aug 25, 2019

@berryzplus さん

再確認してみました。tests1 プロジェクトのリビルドやクリーンですが Project Only ならば後で構成を切り替えてビルドを実行しても 4 up-to-date で走らない事を確認しました。

という事は #999#1001 の対応に問題があったわけではなく、自分が依存関係を考えずにリビルドやクリーンを行った後に予期しない結果に驚いたというだけの事みたいです。

…と思いきや、sakura プロジェクトの Project Only の リビルドやクリーンを行った後に、後で構成を切り替えて tests1 プロジェクトのビルドを実行すると処理が走ることを確認しました。。
(さぼって手順を詳細に書いてません)

考えられる対処方法としては tests1 プロジェクトを Unload Project するのが効果的だと思いますが、Remove するのが恒久的な解決策になると思います。

@berryzplus
Copy link
Contributor

考えられる対処方法としては tests1 プロジェクトを Unload Project するのが効果的だと思いますが、Remove するのが恒久的な解決策になると思います。

簡易的な方法で対策コミットを作ってみたんですが、依存関係の他にもマズい点があるようです。

  • 元々言ってた話
    • HeaderMakeにはx64ビルドがなく、sakura - x64HeaderMake - Win32 を参照している
      • だから x64 をリビルドしたら Win32 も再ビルドされてしまう

間違っちゃいないんですが、本質は別のところにありました。

実は、x64とWin32、DebugとReleaseは、ソースコードを共有しているんです(キリッ
・・・当たり前のこと過ぎて、脳内に極楽とんぼが飛んだことと思います。
しかし、これが重要。

サクラエディタのソースコードは、一部が自動生成されています。

  1. sakura_core/githash.h (バージョン情報埋込用)
  2. sakura_core/funccode_enum.h 機能コードの定数を定義するファイル(C++用)
  3. sakura_core/funccode_define.h 機能コードの定数を定義するファイル(リソースファイル用)

リビルドはクリーンしてビルドですが、クリーン時にこれらのファイルを削除するようにしているので、それが原因でビルドが走っているみたいです。

考え得る対策

  • クリーン時にファイルを削除する処理を削る
  • 自動生成ファイルの出力先をビルド環境ごとに分ける

@beru
Copy link
Contributor Author

beru commented Aug 28, 2019

サクラエディタのソースコードは、一部が自動生成されています。

  1. sakura_core/githash.h (バージョン情報埋込用)
  2. sakura_core/funccode_enum.h 機能コードの定数を定義するファイル(C++用)
  3. sakura_core/funccode_define.h 機能コードの定数を定義するファイル(リソースファイル用)

リビルドはクリーンしてビルドですが、クリーン時にこれらのファイルを削除するようにしているので、それが原因でビルドが走っているみたいです。

考え得る対策

  • クリーン時にファイルを削除する処理を削る
  • 自動生成ファイルの出力先をビルド環境ごとに分ける

自動生成ファイルを作成する専用のプロジェクトを用意するとかも良いんじゃないかと思います。
sakura プロジェクトはそのプロジェクトに依存して、そのプロジェクトは HeaderMakeMakefileMake に依存する形に。

@berryzplus
Copy link
Contributor

サクラエディタの stdafx.h のインクルード構造について、いい評価を訊いたことはありません。だいたい皆さん愚痴ってらっしゃる。
いわく、「ヘッダーファイルを少しでも変えるとフルビルドが走る」と。(漢文風

さて、サクラエディタのcppファイルは全部で370個くらいあります。

自動生成ファイルのうち、Funccode_enum.h は プリコンパイル済みヘッダーの元ネタ(=StdAfx.h) のインクルードパスに含まれています。つまり、現状「 Funccode_enum.h の変更」が検知されると、プリコンパイル済みヘッダーが再構築されます。プリコンパイル済みヘッダーが再構築されるとどうなるかというと、すべてのcppファイルが再ビルドされます。要するに Funccode_enum.h が変更された、とビルドシステムが判断した場合、プロジェクト全体のフルビルドが走るってことです 😢

約370個あるcppのうち、本当に Funccode_enum.h に依存しているのは半分くらい(170個)です。

変更量がそれなりに多いわりに効果が微妙なので、「う~む」という感じです。

@beru
Copy link
Contributor Author

beru commented Aug 28, 2019

自動生成ファイルのうち、Funccode_enum.h は プリコンパイル済みヘッダーの元ネタ(=StdAfx.h) のインクルードパスに含まれています。つまり、現状「 Funccode_enum.h の変更」が検知されると、プリコンパイル済みヘッダーが再構築されます。プリコンパイル済みヘッダーが再構築されるとどうなるかというと、すべてのcppファイルが再ビルドされます。要するに Funccode_enum.h が変更された、とビルドシステムが判断した場合、プロジェクト全体のフルビルドが走るってことです 😢

約370個あるcppのうち、本当に Funccode_enum.h に依存しているのは半分くらい(170個)です。

変更量がそれなりに多いわりに効果が微妙なので、「う~む」という感じです。

/showIncludes オプションを付けてビルドして調べてみたところ、

StdAfx.h
  env/DLLSHAREDATA.h
    env/CommonSetting.h
      CKeyWordSetMgr.h
        func/CKeyBind.h
          Funccode_enum.h

こういう流れで取り込んでいる事が分かりました。

ヘッダファイルには enum EFunctionCode; 前方宣言を書いて #include "Funccode_enum.h" しないようにして、必要な cpp ファイル側で #include "Funccode_enum.h" するように改造してみました。
beru@9783aec

Funccode_enum.h を更新した場合のビルドに掛かる時間が約25秒 → 約11秒 に短縮されました(ビルド環境によって処理時間は変わると思いますが…)。

Funccode_enum.h に依存している cpp ファイルの数は約 80 ファイルぐらいのようです。結構数としては多いのでヘッダファイルに #include "Funccode_enum.h" を記述するのもしょうがない気がします。

@berryzplus
Copy link
Contributor

Funccode_enum.h を更新した場合のビルドに掛かる時間が約25秒 → 約11秒 に短縮されました(ビルド環境によって処理時間は変わると思いますが…)。

Funccode_enum.h に依存している cpp ファイルの数は約 80 ファイルぐらいのようです。結構数としては多いのでヘッダファイルに #include "Funccode_enum.h" を記述するのもしょうがない気がします。

修正ファイル数22、リビルドされるファイル数165の時点で止めてしまいましたが、似たようなことをやってました 😄

対応による変化をどう捉えるかですよね。

  • リビルド時間を半分に減らすことができる ← 好意的解釈
  • 80 ファイル変更してもビルドに時間がかかる ← 否定的解釈

前者の考え方をしたほうが幸せでいられると思うんですが、これまでのプロジェクトの流れでは後者の考え方による否定的なコメントが多かったように思います。

技術的な裏付けがある修正対応で、
効果があるんだから適用してもいいんじゃないかな~
と思っています。

自動生成ファイルの出力先を分ける対応を入れれば、このPRの困りごと自体は解決できるはずで、「対応すべきなのかどうか」はやっぱり「微妙」なんですけどね 😢

少なくとも「対応する価値」はあるような気がします。

@beru
Copy link
Contributor Author

beru commented Aug 29, 2019

他の手段としてパフォーマンスは低下しますが、ビルド時に静的に数値の対応付けを解決させるのではなく、実行時にランタイムで文字列をキーにしたハッシュテーブル等を経由して動的に解決させるように作り変えるという方法もあると思います。

おそらくパフォーマンスの低下は許容出来る範囲内だと思いますが、コードの書き換えが大変手間なので別の意味で実現可能性が低いかも知れません…。

@beru
Copy link
Contributor Author

beru commented Aug 29, 2019

自動生成ファイルの出力先を構成毎に分ける方法で解決するべきなのかどうかは判断付きかねます。
見えないものを気にしなければそれで丸く収まりそうな気もしますが…。

HeaderMakeMakefileMake はあまり変更するものでも無いので sakura.sln にプロジェクト登録する必要性はあまり無い気がします。sakura プロジェクトのリビルド時に自動生成ファイルを再生成させたいのかというと、そんな事も無いのではないかと思います。無かったら生成してほしいですし、Funccode_x.hsrc が変わった時にも再生成してほしいですが…。

もっとも Funccode_x.hsrcsakura_rc.rc をエディタで編集する仕組みがそもそもどうなんだ的な疑問も…。。

@beru
Copy link
Contributor Author

beru commented Sep 1, 2019

この問題は解消したと思うので Close します。

UnitTestのプロジェクトが犯人だと思っていたらそんな事はなかったので申し訳ないです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants