1

さまざまなC++ソースファイルを追加し続けるディレクトリと、それらをコンパイルするための汎用Makefileがあります。Makefileの内容は次のとおりです。

.PHONY: all clean

CXXFLAGS = -pipe -Wall -Wextra -Weffc++ -pedantic -ggdb

SRCS = $(wildcard *.cxx)
OBJS = $(patsubst %.cxx,%.out,$(SRCS))

all: $(OBJS)

clean:
    rm -fv $(OBJS)

%.out: %.cxx
    $(CXX) $(CXXFLAGS) $^ -o $@

注:上記から明らかなように、実行可能ファイル拡張子には* .outを使用しています(オブジェクトファイルには使用していません)。

また、一緒にコンパイルされるいくつかのファイルがあります:

g++ file_main.cxx file.cxx -o file_main.out

このようなファイルをコンパイルするために、これまでMakefileに明示的なルールを追加してきました。

file_main.out: file_main.cxx file.cxx

file.out: file_main.out
    @echo "Skipping $@"

しかし、今では私のMakefileに多くの明示的なルールがあり、それらをより単純な暗黙のルールに置き換えたいと思います。

それを行う方法はありますか?

4

2 に答える 2

4

まず、いくつかのソースファイルを実行可能ファイルに直接コンパイルするこの方法は、ひどく良い考えではありません。より一般的なcompile-then-linkアプローチは、多くの不要なコンパイルを節約します。

とはいえ、多くの明示的なルールをより単純なルールに置き換える方法は、明示的なルールに共通するものによって異なります。すでにパターンルールがあります:

%.out: %.cxx
    $(CXX) $(CXXFLAGS) $^ -o $@

また、特定のターゲットに別のソースファイルを追加するだけの場合は、次のようにする必要はありません。

g++ file_main.cxx file.cxx -o file_main.out

前提条件を(単独で1行に)追加するだけで効果を得ることができます。

file_main.out: file.cxx

そのパターンを持つ複数のターゲットがある場合は、パターンルールを使用できます。

file_main.out another_main.out a_third_main.out: %_main.out : %.cxx

そのようなターゲットが多数ある場合は、変数を使用できます。

MAIN_THINGS = file another a_third a_fourth and_yet_another
MAIN_TARGETS = $(addsuffix _main.out, $(MAIN_THINGS))
$(MAIN_TARGETS): %_main.out : %.cxx

また、重複するセットであっても、他のターゲットセットに他のパターンを追加できます。それはあなたの状況をカバーしていますか?

于 2010-06-16T21:10:52.833 に答える
1

複数の異なるプログラムのソースコードを同じフォルダに入れているようですが、これが問題の原因です。ライブラリとプログラムのソースコードを別々のフォルダー(または、より良いのは別々のプロジェクト)に分割する場合、特定のフォルダー内のすべてのソースファイルに依存することで、この問題を回避できます。すべてが混在している場合は、明示的にする必要があります。

とはいえ、依存関係に一貫性のある予測可能な名前がある場合は、 eval関数を使用してこの冗長性を排除することができます。たとえば、上記の例に基づくと、次のようになります。

#
# I'm going to use standard file extensions here,
# slightly deviating from your conventions. I am also
# assuming that there is a variable named PROGNAMES,
# which gives a list of all the programs to be built.
#
define ADD_EXECUTABLE
     $(1): $(1).o $(1)_main.o
         $(LINK.cc) $(1).o $(1)_main.o -o $(1)
endef

$(foreach progname,$(PROGNAMES),$(eval $(call ADD_EXECUTABLE,$(progname)))) 

また、いくつかの提案...上書きするのではなく、CXXFLAGSに追加する必要があります。標準のファイル拡張子(C ++ソースファイルの場合は「.cpp」、オブジェクトファイルの場合は「.o」、実行可能ファイルの場合は拡張子なし)を使用することをお勧めします。 )。Makeで物事を簡単にするためのヒントについては、 Makefileチュートリアルを参照してください(しゃれは意図されていません)。

于 2010-06-15T11:20:08.343 に答える