カテゴライズなんてのは先天的に難しいものなのだ

てなことを思う日々。

 1 _IGNORE_KEYS = [
 2     # SuppressStartupBanner:
 3     #     Essentially, the factor determining whether to output a banner
 4     #     is whether or not you want to debug the build process, and it
 5     #     is nonsense that the project file decides.
 6     "SuppressStartupBanner",
 7 
 8     # LinkIncremental,
 9     # EnableFunctionLevelLinking,
10     # FunctionLevelLinking,
11     # MinimalRebuild,
12     # PrecompiledHeaderFile,
13     # PrecompiledHeaderOutputFile,
14     # PrecompiledHeaderThrough,
15     # UsePrecompiledHeader:
16     #     Like "SuppressStartupBanner", it is nonsense that the project
17     #     file decides, because these are for the purpose of shortening
18     #     build time only.
19     "LinkIncremental",
20     "EnableFunctionLevelLinking",
21     "FunctionLevelLinking",
22     "MinimalRebuild",
23     "PrecompiledHeaderFile",
24     "PrecompiledHeaderOutputFile",
25     "PrecompiledHeaderThrough",
26     "UsePrecompiledHeader",
27 
28     # TreatLinkerWarningAsErrors, TreatWarningAsError:
29     #     It can not be said that there is no case to deal with
30     #     warnings as fatal errors only for certain projects, but
31     #     this is usually decided based on a wider range of decisions,
32     #     for example team agreements.
33     #
34     #     In some cases, there are many things you may want to do
35     #     temporarily for problem identification in compilation.
36     #     That is, compatibility between error handing desire and
37     #     persistence as setting is not good.
38     #
39     #     For this matter, I do not think that this should be
40     #     specified in the project file, so I think this should be
41     #     ignored.
42     "TreatLinkerWarningAsErrors",
43     "TreatWarningAsError",
44 
45     # WarningLevel:
46     #     The reason is quite similar to TreatLinkerWarningAsErrors,
47     #     and TreatWarningAsError. However, in this case, there are
48     #     mare cases where you would like to make settings on a per-project
49     #     basis. In extreme cases, there are even things that you want
50     #     to control per compilation unit.
51     #
52     #     Still I think that it is better to control this outside the project
53     #     file.
54     "WarningLevel",
55     ]

英文は google 翻訳がベースなのでちょっとおかしいような気もするところもあるけれど、これでワタシが何を言いたいのかわかる?

これ、Visual Studio のプロジェクトファイル関連なんだけどさ、こういうのをやってるとほんと、「分類ってほんと、むつかしいよなぁ」と痛感するのである、てハナシ。

「ソリューション」と「プロジェクト」という木構造がまずは Microsoft の発明品なのかどうかは定かではないけれど、ワタシの個人的開発者経験としては、Microsoft 開発環境で初めてお目にかかった。もう随分前の話だ。それまでは「Make するんだぜっ」という一元論でしか開発したことはなかったのだ。

これはすなわち「お客様の問題解決をしてやるんだぜ」という製品単位に対応する「ソリューション(解決)」と、「問題解決のための部品たち」という、開発者側目線で言う「サブプロジェクト」に対応する「プロジェクト」という二元論にまずは分解したわけね。Unix 伝統の make なら単に「サブフォルダごとに make」というだけのことだったりするので、この分解そのものは別に「すげー」くはない。単に「製品、という全体単位のまとめあげ君」として、大げさに名前を付けただけ、とも言える、「ソリューション」は。

実際「ソリューション」そのものには登場時から今の今まで、何かスペシャルにウマしことを開発者たちにもたらした、ということはない。けれど、「まとめあげ君がない」ならば、つまり make の世界では「make が子 make を呼び出す」ということを(サポートツールの助けがあるにせよ)明示的に「そうしなければならない」わけだから、「少しはオイシイ」ものではあったのだ、だから Microsoft が考えてくれたことには素直に感謝しよう、という気にはならないでもない。

さて、「ソリューション」と「プロジェクト」という大きな単位についてはわかった。問題はそれより小さな単位が「あるのやないのや」という話である。

そもそも「プロジェクトファイルは誰の持ち物なのか?」について考えるとき、これは当然「チームでの共有設定」ともなりうる一方で、「一開発者個人の設定」でもありえて、なおかつ、時間軸で考えた場合に、「開発ステータスのスナップショット」ともなりうるわけなのだ。最後のはつまり「現在の進捗からは、警告をエラー扱いにしてたら埒があかない、警告が多過ぎて」みたいなことである。プロジェクトファイルへの設定の永続化は、所詮一時的な決断を反映したもの、であることもある、というハナシ。

上で貼り付けたコードはまさしくこうした「誰の持ち物なのか」問題を反映している。こういうの、「プロジェクトファイルに書き込む時点で間違いだろ?」と断言出来るなら話は簡単なんだけれど、そうもいかない。「一時的な決断を反映」させることが出来るように、プロジェクトファイルに記述出来るようにしているのだから。

抽象的な言い回しばかりでわかりにくいかもしれないので、「WarningLevel」だけで考えてみる。

チームでの開発の場合、この扱いは通常、チームの合意、あるいは「コーディング規約」で決定するようなものである、普通は。だからサブプロジェクト単位でこれを都度制御したいニーズは、そう多くはない…、と言いたいところだが、本当は全然そうじゃない。特に C/C++ 、さらにいえば Visual C++ では、「開発者自身には一切責任のない警告」を大量に喰らう場合が多く、従って「やむをえない事情」として事細かな警告制御が必要になることが非常に多い。つまり、「ほんとは統一的に全部同じにしたいのに、そう出来ないことが多いために、プロジェクトファイルに設定せざるを得ない」ことが多いということ。

そして「スナップショットに過ぎない」については、すなわち「開発フェーズ依存」で決断されることが多い、ということ。例えば「作りこみフェーズ」で警告を緩めに扱っておいて、「品質向上フェーズ」において厳しくチェックをする、と「したいことがある」ということである。今目にしているこのプロジェクトファイルは、いったいどのフェーズなのであろうか?

そしてもう一つ。特に OSS に言えること。「プロジェクトファイルを書いたチームメンバー」ではない、たとえばコントリビュータが、「チームメンバーの決断に従う必要があるのかないのか?」ということだ。警告に関して、例えば「オレはこやつをビルド出来ればそれでいいんぢゃ」と思うのも自然であり、そうであれば致命的でない警告なんか目にしたくはないであろうし、逆に何か問題を認識していて、「改造して貢献したい」開発者にとっては、むしろ厳しく警告を扱いたい場合もあるだろう。

簡単に言えばこれがどうであるべきだったのか。「開発フェーズ単位」という分類がなければならなかったのだ、…と思う? いや…、Microsoft は既にこれを「デバッグ(Debug)」「リリース(Release)」というコンフィグレーション単位を(テンプレートビルダによって事実上)強制していて、つまり「ないわけではない」。むしろ「通常時コンフィグレーション単位」とともに「非常時コンフィグレーション単位」のようなものがあれば良かったのか? としたとしても、「チーム外の人間がチームの決断に従う必要がない」場合にも対応するなら、つまり「永続化しちゃうようなものなら元の木阿弥」だ。簡単じゃない。

無論「チームの決断に逆らう」手段は用意されてる。msdev や devenv のコマンドライン引数で明示的にプロジェクトファイルの設定にオーバライド出来る。だから実際には今問題にしているこれらは「問題ではない」のだ。ますますむつかしい。

なんというか、分類がもう一声あれば、もすこし悩みが少なかったりすんのかなー、と思ったりもするんだけれど、じゃあ本当の理想はどういう形なんだ、てのもそう単純ではないだろうなぁと思うのね。実際 Microsoft は一時期「User.props」というユーザ固有設定を可能にしていて、まぁ今回問題にしたようなことの一つの解だったようにも思うんだけれど、当然これは「開発者依存問題」が多発して、つまり「開発者の環境によってビルドが成功したり失敗したりする」てことがあまりに多発したために、今ではこれは非推奨。なんつーか、上のコード貼り付けが取り上げた範囲内、つまり「コード生成には影響しない、開発時の開発効率やコードレベル品質向上のヒントにしか影響しないもの限定」のユーザ設定、みたいなのがあれば、なんぼか良かったのかもね、と思ったりする。

歴史上色んな「開発環境」が発明されては消え、消えては発明されてきたけれど、正直 Microsoft のはこうしたことについて、そう頭悪くもないようには思う。一応「ちゃんと」考えられて出来たものだ。それでもこの種の悩みは尽きないわけだから、まぁこの手のはもう、なくならないもんだとして受け容れるしかないんだろうね。

…ワタシは一体何を言っているのだろうか? なんともまとまりのない、というかまとめるつもりもない駄文を、イキオイに任せて書いちまった。伝えたいこと、伝わった? いつも思うんだけどさ、「本当はむつかしいのになぜだか話を矮小化しちゃう人たち」ってひじょーに多くて、そうした人たちに直接危害を被ることも多いんだよね。「ファックスも直せるんでしょ?」みたいなことな。「言うほど簡単な話じゃないんだぞ」てことを、まぁ言いたかっただけなのね。



Related Posts