コード ベースをリファクタリングし、さまざまなコンポーネント間の直接的な依存関係を制限しようとしています。ソース ツリーには、src/a、src/b、src/c といういくつかの最上位ディレクトリがあります。
一連の制限を適用したいと考えています。
- a のファイルは、b または c のファイルに依存できません
- b 内のファイルはファイル a に依存できますが、c には依存できません
- c のファイルは b のファイルに直接依存できますが、a のファイルには依存できません
最初のものを強制するのは簡単です。次のような暗黙のルールがあります。
build/a/%.o : src/a/%.cpp
$(CXX) -I src/a $(OTHER_FLAGS) -o $@ $<
a の下のファイルが b または c のヘッダー ファイルをインクルードしようとすると、ヘッダーが見つからないため、ビルドは失敗します。
2 番目の規則には、src/a と src/b をインクルード ディレクトリとして指定する同様の規則があります。問題は建物 c で発生します。以下は許可されます。
src/c/C.cpp
#include "b.h"
void C() { ... }
src/b/b.h
#include "a.h"
class B { ... };
src/a/a.h
class A { ... };
ここでは、c からのファイルに b からのファイルが含まれ (許可されます)、さらに a からのファイルが含まれます (これも許可されます)。次のようなコードを防止したいと考えています。
src/c/C_bad.cpp
// Direct inclusion of a
#include "a.h"
src/c/c_bad.h
// Direct inclusion of a
#include "a.h"
許可されたケースをコンパイルするには、src/c でファイルを構築するためのコンパイル コマンドに -Isrc/a を含める必要がありますが、これにより 2 番目のケースもコンパイルできます。
私の問題に対する答えは、コンパイラから生成された依存関係を調べ、潜在的に違法な依存関係を見つけ、ソース ファイルを調べて、これが直接の依存関係であるかどうかを判断するスクリプトを作成することだと思います。コンパイラやメイクファイルの構造を組み合わせてこれを行う合理的な方法はありますか?
問題があれば、GNU Make 3.81 と g++ 4.5.3 を使用していますが、可能であれば移植可能にしたいと考えています。
アップデート
私たちは、ルールに従うのに努力が必要なものではなく、ルールに違反するのに努力が必要なものを探しています. (過去の経験から、後者はうまくいかないことが示されています。)他の回答にはいくつかの良いアイデアがありますが、私はスクリプトを書くことを言っているものを受け入れます。その周り。
皆さんの回答に感謝します。