5

私のオブジェクト指向プログラミング コースでは、最終プロジェクト (学術目的) を行わなければなりません。クラス、makefile、および C++ をよりよく理解するために、プロジェクトを「正しい方法」(つまり、makefile、モジュラー、DRY、簡単にスケーラブルなど) にしたいと考えています。

私が得たアイデアは、「ツリーソースファイル構造ディレクトリ」を作成することです。そのため、各サブフォルダーに、ヘッダー、テストファイル、および単一のメイクファイルを含むソースファイルを取得しました。インターフェイスで作業したい場合は、サブフォルダー インターフェイスに移動し、ファイルを編集し、テストを実行します。すべて問題なければ、ルート ディレクトリでオブジェクトをリンクするだけです。データ構造に取り組みたい場合も同じです。優れた機能は、すべてのサブフォルダーにソース コードとオブジェクト ファイルが存在することです。したがって、ルート ディレクトリのリンカーは、サブフォルダーで既にコンパイルされているオブジェクト ファイルを検索し、それらをリンクします。

私はインターネットで検索してきましたが、さまざまな解決策を見つけることができました。

SUBDIRS=eda
.PHONY: subdirs $(SUBDIRS)
$(SUBDIRS):
    $(MAKE) -C $@

私が見つけた問題は、「eda」フォルダーの前提条件が「変わった」ものになることです

-自動変数$(@D) を使用していますが、その仕組みがよくわかりませんでした - ワイルドカード機能を使用している可能性がありますが、このオプションについて少し混乱しています。

とにかく、私にとって最も魅力的な解決策は最初のもの (make を再帰的に使用する) でしたが、 make を再帰的に使用することは推奨されないという多くのコメントを見つけました興味深い記事

そこで皆さんにアドバイスをお願いしたいのですが、目的を達成し、すべての重要なモジュールを別のフォルダーに入れるにはどうすればよいでしょうか? 再帰は最善の解決策ですか?たぶん、「automake」に飛び込む必要がありますか?それとも、すべてのオブジェクト ファイルをルート ディレクトリの新しい「オブジェクト」サブフォルダに移動し、それらをリンクする方がよいでしょうか?

ところで、私は Amarok のソース コードを盗聴して、このツリー構造のプロジェクトを作成することに着想を得ました。「src」というサブフォルダーがあり、そこに入ると、イコライザー、プレイリスト、ダイナミックなど、多くのサブフォルダーが表示されます。 、statusbar、core、playlistgenerator、playlistmanager など。そして、多くのサブフォルダーには独自のサブディレクトリがあります。その結果、すばらしい音楽プレーヤーができあがります。この方法が Amarok チームにうまく機能するなら... 私も似たようなことができるかもしれません!

コメント、フィードバック、提案などは大歓迎です。よろしくお願いします。


編集#1

Beta、いくつかの暗黙のルール (サフィックス) と、edaフォルダーにオブジェクトを必要とするリンカーのターゲットがあります。このターゲットの他のすべての前提条件は、現在のフォルダーに基づいて構築されます。私が抱えている問題は、そのターゲットをビルドするためにmakeを実行すると、「eda」フォルダーの前提条件の名前が、暗黙のルールでビルドするターゲットとして使用されることです。これは、私のプロジェクトでの再帰的な makefile のトリッキーで不潔な部分です。make がサブフォルダーを検索する必要があるすべてのオブジェクト ファイルに対して、特別な暗黙のルールを作成する必要があると思います。

だからこそ、私はいくつかのフィードバックが欲しいのです: ¿ それとも、私のプロジェクトで make recursive を使用する利点が他の選択肢を圧倒しますか?

とにかく、理解が深まれば、ここに私のドラフト Makefileがあります(spnish-english :P )

#Makefile hecho para las pruebas de los archivos dentro de esta carpeta
FLAGS=-g -DDEBUG

OUT_TI=TIndividuo

OUT_TP=TProfesor
OUT_TA=TAula

.SUFFIXES: .cpp .c .h .o
.c.o: ; cc $(FLAGS) -c $*.c
.cc.o: ; gcc $(FLAGS) -c $*.cc
.cpp.o: ; g++ $(FLAGS) -c $*.cpp

SUBDIRS=eda
.PHONY: subdirs $(SUBDIRS) 

$(OUT_TI): eda/TAula.o CandidatoHorario.o TIndividuo.o TIndividuoTest.o TGen.o
    g++ CandidatoHorario.o TIndividuo.o TIndividuoTest.o TGen.o eda/TAula.o -o $@
CandidatoHorario.o: CandidatoHorario.cpp CandidatoHorario.h
TIndividuoTest.o: TIndividuoTest.cpp TIndividuo.h
TIndividuo.o: TIndividuo.cpp TIndividuo.h
TGen.o: TGen.cpp
#eda/TAula.o: eda/TAula.cpp eda/TAula.h
#   g++ -c eda/TAula.cpp -o $@

$(SUBDIRS):
    $(MAKE) -C $@

clean:
    rm -f *.o $(OUT_TI) $(OUT_TA) eda/TAula.o
4

1 に答える 1

1

「Recursive Make Considered Harmful」は確かに読んで理解する論文です。その後、ツールの選択は実際に特定のプロジェクトに合わせて調整する必要があります。

あなたが開始する小さなプロジェクト (または高レベルの決定を導く影響力があるプロジェクト) の場合は、少し時間をかけて自分の好み (プロジェクトのレイアウト、ディレクトリ構造、単体テスト フレームワークなど) を特定し、一般的なコードを作成することをお勧めします。すべてのプロジェクトで使用するメイクファイルのセット。一般的なマスター makefile を簡単に作成できます。モジュール化のためにさらに一般的な makefile をいくつか追加することもできます (たとえば、ライブラリのビルド、単体テスト、または依存関係の自動検出など)。また、オプションで含まれる構成 makefile を使用して、柔軟性をさらに高めることもできます (ライブラリの順序を指定するなど)。DAG の構築のほとんどは、プロジェクト ディレクトリの内容に大きく依存します。例は次のようになります。

include config.mk

sources := $(wildcard *.cpp)
programs := $(sources:%.cpp=%)
lib_sources := $(wildcard lib/*/*.cpp)
lib_dirs := $(sort $(patsubst %/, %, $(dir $(lib_sources:lib/%=%))))
lib_objects := $(lib_sources:lib/%.cpp=$(BUILD)/%.o)

all: $(programs:%=$(BUILD)/%)

.PRECIOUS: %/.sentinel %.d

# for dependencies on directories in build tree
%/.sentinel:
        @mkdir -p $* && touch $@

clean:
        $(RM) -r $(BUILD)

programs_aux:=$(programs)
include $(foreach program, $(programs), program.mk)

lib_dirs_aux:=$(lib_dirs)
include $(foreach lib_dir, $(lib_dirs), lib.mk)

# this should probably be in lib.mk
-include $(lib_objects:%.o=%.d)

含まれるprogram.mk(およびlib.mk) には、プログラムのリスト (およびライブラリのリスト) を反復処理する定型コードが含まれており、makefile の特定の部分を取り出してプログラム (およびライブラリ) をビルドします。

このようなメイクファイルの実装を支援するために、 http://gmsl.sourceforge.netのような標準ライブラリを使用できます。

このアプローチにはいくつかの問題があります: * 強力なスキルを必要とするメイクファイルにつながります * 非常に大規模なプロジェクトに常にうまく対応できるとは限りません * 「構成ではなく規則」に大きく依存し、作成する規則を事前に明確に定義する必要があります使用します (IMO これは良いことで、他の人は柔軟性に欠けると思うかもしれません)

それ以外の場合は、SCons や CMake などの高レベルの構成ツールを使用することをお勧めします。これらのツールは概念的に単純である傾向があり、他のフレーバーのジェネレーターも使用できるためです。

于 2013-07-25T08:25:53.447 に答える