ディレクトリ構造が次のようなプロジェクトがあります。
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
一部のC/C++ソースファイルをコンパイル/リンクできるpart/src(または実際にはどこでも)にあるメイクファイルをどのように作成すればよいですか?
-I $ projectroot/part1/src -I $ projectroot/part1/inc -I $ projectroot/part2/srcのようなことはできますか?.
それが機能する場合、それを行う簡単な方法があります。対応する部分のそれぞれにメイクファイルがあるプロジェクトを見ましたか?フォルダー。 [この投稿では、bash構文のように疑問符を使用しました]
従来の方法は、各サブディレクトリ(part1
、part2
など)にMakefile
を配置して、それらを個別に構築できるようにすることです。さらに、すべてをビルドするプロジェクトのルートディレクトリにMakefile
を用意します。 「ルート」Makefile
は次のようになります。
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Makeターゲットの各行は独自のシェルで実行されるため、ディレクトリツリーを逆方向に移動したり、他のディレクトリに移動したりする必要はありません。
GNU make manual section 5.7 ;をご覧になることをお勧めします。とても助かります。
あるサブディレクトリに別のサブディレクトリのコードに依存するコードがある場合は、トップレベルで単一のメイクファイルを使用する方がよいでしょう。
完全な根拠については Recursive Make Thoughd Harmful を参照してくださいプロジェクトの3分の1だけを伝えてください。
上記のリンクに到達できないようです。同じドキュメントがここに到達できます:
VPATHオプションが役立つ場合があります。これは、ソースコードを検索するディレクトリをmakeに指示します。ただし、各インクルードパスには-Iオプションが必要です。例:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
これにより、VPATHで指定されたディレクトリのいずれかで一致するpartXapi.cppファイルが自動的に検出され、コンパイルされます。ただし、srcディレクトリがサブディレクトリに分割されている場合、これはより便利です。他の人が言ったように、あなたが説明するものについては、特に各部分が独立している場合は、各部分のmakefileを使用する方がよいでしょう。
他のディレクトリにある必要なcppファイルをコンパイルするために、ルートMakefileにルールを追加できます。以下のMakefileの例は、目的の場所に到達するための良い出発点です。
CC = g ++ TARGET = cppTest OTHERDIR = ../../someotherpath/in/project/src SOURCE = cppTest。 cpp SOURCE = $(OTHERDIR)/file.cpp ##ソース定義の終了 INCLUDE = -I./ $(AN_INCLUDE_DIR) INCLUDE = -I。$(OTHERDIR)/../ inc ## end more includes VPATH = $(OTHERDIR) OBJ = $( join $(addsuffix ../obj/、$(dir $(SOURCE)))、$(notdir $(SOURCE:.cpp = .o))) ##依存関係の修正srcに対して相対的な../.depになるようにdir DEPENDS = $(join $(addsuffix ../.dep/、$(dir $(SOURCE)))、$(notdir $(SOURCE :. cpp = .d))) ##実行されるデフォルトのルール all:$(TARGET) @true ##クリーンルール clean: @ -rm -f $(TARGET)$(OBJ)$(DEPENDS) ##実際のターゲットを作成するためのルール $(TARGET):$(OBJ) @echo "=============" @echo "ターゲットのリンク$ @ " @echo" ============= " @ $(CC)$(CFLAGS)-o $ @ $ ^ $(LIBS) @echo-リンク完了- ##一般的なコンパイル規則 %。o:%.cpp @mkdir -p $(dir $ @) @echo "=============" @echo "Compiling $ <" @ $(CC)$(CFLAGS)-c $ <-o $ @ ##オブジェクトのルールcppファイルからのファイル ##各ファイルのオブジェクトファイルは、実際のソースディレクトリから1レベル上のobjディレクトリ ##に配置されます。 ../ obj /%。o :%.cpp @mkdir -p $(dir $ @) @echo "=============" @echo "コンパイル$ <" @ $(CC)$(CFLAGS)-c $ <-o $ @ #「その他のディレクトリ」のルール「その他」ごとに1つ必要です。 dir $(OTHERDIR)/../ obj /%。o:%.cpp @mkdir -p $(dir $ @) @echo "==== ========= " @echo"コンパイル$ <" @ $(CC)$(CFLAGS)-c $ <-o $ @ ##依存ルールを作成します ../。dep /%。d:%.cpp @mkdir -p $(dir $ @) @echo "=============" @echo $ *。o [.____の依存関係ファイルの構築。] @ $(シェル)-ec '$(CC)-M $(CFLAGS)$ <| sed "s ^ $ *。o ^ ../obj/$ *。o ^"> $ @ ' ##「その他」ディレクトリの依存ルール $( OTHERDIR)/../。dep /%。d:%.cpp @mkdir -p $(dir $ @) @echo "=========== == " @echo $ *。o の依存ファイルの構築@ $(Shell)-ec '$(CC)-M $(CFLAGS)$ <| sed "s ^ $ *。o ^ $(OTHERDIR)/../ obj/$ *。o ^"> $ @ ' ##依存関係ファイルを含める -include $(DEPENDS)
ソースが多数のフォルダーに分散しており、個々のMakefileを用意することが理にかなっている場合は、以前に提案したように、再帰的なmakeが適切なアプローチですが、小規模なプロジェクトではMakefileへの相対パスでMakefileこのように:
# common sources
COMMON_SRC := ./main.cpp \
../src1/somefile.cpp \
../src1/somefile2.cpp \
../src2/somefile3.cpp \
次に、VPATH
を次のように設定できます。
VPATH := ../src1:../src2
次に、オブジェクトを作成します。
COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(Arch)$(DEBUG).o, $(notdir $(COMMON_SRC)))
これでルールは簡単になりました:
# the "common" object files
$(ObjDir)/%$(Arch)$(DEBUG).o : %.cpp Makefile
@echo creating $@ ...
$(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
そして、出力の構築はさらに簡単です:
# This will make the cbsdk shared library
$(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS)
@echo building output ...
$(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)
次の方法でVPATH
生成を自動化することもできます。
VPATH := $(dir $(COMMON_SRC))
または、sort
が重複を削除するという事実を使用します(重要ではありませんが)。
VPATH := $(sort $(dir $(COMMON_SRC)))
RCの投稿はとても役に立ちました。私は$(dir $ @)関数の使用を考えたことはありませんでしたが、必要なことを正確に行いました。
ParentDirには、ソースファイルを含むディレクトリの束があります:dirA、dirB、dirC。さまざまなファイルが他のディレクトリのオブジェクトファイルに依存しているため、1つのディレクトリ内から1つのファイルを作成し、その依存関係に関連付けられたmakefileを呼び出して依存関係を作成できるようにしたいと考えました。
基本的に、parentDirにMakefileを1つ作成しました。このファイルには、RCに似た一般的なルールがあります(他にもたくさんあります)。
%.o : %.cpp @mkdir -p $(dir $@) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o $@
この汎用ルールを継承するために、各サブディレクトリにはこの上位レベルのメイクファイルが含まれていました。各サブディレクトリのMakefileには、各ファイルに依存するすべてを追跡できるように、各ファイルにカスタムルールを記述しました。
ファイルを作成する必要があるときはいつでも、(本質的に)このルールを使用して、すべて/すべての依存関係を再帰的に作成しました。パーフェクト!
注:「makepp」と呼ばれるユーティリティがあり、このタスクをさらに直感的に実行するように見えますが、移植性のために、別のツールに依存しないため、この方法を選択しました。
お役に立てれば!
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
これにより、make
がジョブに分割され、複数のコアを使用できるようになります
私はこのようなものを探していましたが、何度か試行錯誤した後、私は独自のメイクファイルを作成しますが、それは「イディオマティックな方法」ではありませんが、メイクを理解し始めており、これは私にとってうまくいきます。
PROJ_NAME=mono
CPP_FILES=$(Shell find . -name "*.cpp")
S_OBJ=$(patsubst %.cpp, %.o, $(CPP_FILES))
CXXFLAGS=-c \
-g \
-Wall
all: $(PROJ_NAME)
@echo Running application
@echo
@./$(PROJ_NAME)
$(PROJ_NAME): $(S_OBJ)
@echo Linking objects...
@g++ -o $@ $^
%.o: %.cpp %.h
@echo Compiling and generating object $@ ...
@g++ $< $(CXXFLAGS) -o $@
main.o: main.cpp
@echo Compiling and generating object $@ ...
@g++ $< $(CXXFLAGS)
clean:
@echo Removing secondary things
@rm -r -f objects $(S_OBJ) $(PROJ_NAME)
@echo Done!
私はそれが簡単であり、一部の人にとっては私のフラグが間違っていることを知っていますが、私が言ったように、これは私のプロジェクトを複数のディレクトリでコンパイルし、すべてをリンクしてビンを作成する最初のMakefileです。
私はサジェスチョンを受け入れています:D
autotools
を使用することをお勧めします。
//##
生成されたオブジェクトファイル(.o)をソースファイルと同じディレクトリに配置します。これは、非再帰的なmakeが使用される場合の衝突を回避するためです。
AUTOMAKE_OPTIONS = subdir-objects
Makefile.am
に他の非常に単純なものとともに含めるだけです。
チュートリアル です。