16

私はいくつかのC++クラスを持っています。それぞれがメイクファイル、テスト目的のtest.cppなどを含む独自のフォルダーに入っています。

Main folder
 |-> Class1 folder
 |-> Class2 folder
      |-> Class2.1 folder
 |-> Class2 folder

これらのクラスを含める必要があるメイン プロジェクトがあります。すべてのサブ makefile をメインの makefile に含めようとしています。

「INCLUDE POO/makefile」を試してみましたが、この解決策には 2 つの問題があります。

  • サブメイクファイルのパスが正しくないため、ファイルが見つかりません (「ターゲット 'Vector3D.cpp' をビルドするルールがありません」)。
  • おそらくパスの問題が原因で、「test.cpp」ファイルが上書きされます。(「警告: ターゲットのレシピを上書きしています...」)

すべての makefile を独立させたいので、クラス フォルダーを新しいプロジェクトにコピー/貼り付けしても、それは引き続き機能します。または、makefile を変更せずに単独で実行することもできます。

問題は、makefile を別の makefile に (正しく) インクルードする方法です。

例、テスト目的のみ。

メインのメイクファイル (簡略化)

include Vector3D/makefile
include Color/makefile

CPP      = g++
CXXFLAGS = $(CXXINCS) -Wall -O0

all: main

main: main.o Vector3D.o Color.o
    $(CPP) main.o Vector3D.o Color.o -o main

main.o: main.cpp
    $(CPP) -c main.cpp -o main.o $(CXXFLAGS)

サブ makefile の例 (簡略化)

#Vector3D
CPP      = g++
CXXFLAGS = $(CXXINCS) -Wall -O0


all: test

test: Vector3D.o test.o
    $(CPP) Vector3D.o test.o -o test

Vector3D/test.o: test.cpp
    $(CPP) -c test.cpp -o test.o $(CXXFLAGS)

Vector3D.o: Vector3D.cpp Vector3D.hpp
    $(CPP) -c Vector3D.cpp -o Vector3D.o $(CXXFLAGS)

Vector3D よりも Color/makefile に似ています。

4

2 に答える 2

5

このソリューションの初期コンセプトを提供してくれた @Jonathan-wakely に感謝します。

おそらく改善される可能性がある多くのことがありますが、機能します。

要件の概要:

  • Makefile はスタンドアロンで動作する必要があります
  • メインのメイクファイルにはサブのメイクファイルが含まれます
  • 競合やパスの問題は発生しません。

簡単な解決策は、makefile を再帰的に呼び出すことです。

  • リーフ makefile 用の「通常の」スクリプトを作成する
  • 空のターゲットを使用すると、「:」の後の要件なしで、「sub-make:」などの make 呼び出しを常に実行できます。
  • " -C " パラメータを使用して、make 呼び出しのルート ディレクトリを設定します。
  • サブ makefile によって作成されたバイナリとの最終的なリンクを作成します。

メインのメイクファイルの例:

#all make recursive calls
sub-make:
    make -C Vector3D
    make -C Color

#final linking
CPP      = g++
FLAGS = $(CXXINCS) -Wall -O0

all: main

main: main.o Vector3D/Vector3D.o Color/Color.o
    $(CPP) main.o Vector3D/Vector3D.o Color/Color.o -o main

main.o: main.cpp
    $(CPP) -c main.cpp -o main.o $(FLAGS)

すべてのフル パスを記述せずに *.o バイナリをリンカに提供するためのより良い方法がおそらくありますが、それは別の問題です。

クリーン ターゲットの作成。リーフ makefile の場合、特別な考慮事項はありませんが、メインの makefile の場合は、サブクリーン ルールを呼び出す必要があります。

clean:
    make -C Vector3D clean
    make -C Color clean
    rm -f *.o main

編集:

誰にとっても役に立つかもしれないので、これが私が行ったメイクファイルの構造です。

機能するには、すべてのクラスが次のフォルダー内にある必要があります。

  • .hpp ヘッダー
  • .cpp コード
  • テスト用の main.cpp
  • このmakefileに対して必要なクラス(LIBS)のディレクトリを「$(LIBSPATH)LibName」で指定します。

Makefile

#Following configuration may be set with a parameter:
#   e.g: make FLAGS="-Wall -O0"
FLAGS = $(CXXINCS) -Wall -O0

#Configurable variables
EXEC     = main
CLASS    = World
LIBS     = Color Vector3D Triangle
LIBSPATH = ../

#Static content
CPP      = g++
OBJS     = $(foreach dir, $(LIBS), $(LIBSPATH)$(dir)/$(dir))

all: $(EXEC)

clean: 
    rm -f *.o $(EXEC)
    $(foreach dir,$(LIBS),make clean --no-print-directory -C $(LIBSPATH)$(dir);)

$(EXEC): $(CLASS).o $(EXEC).o $(OBJS:=.o)
    $(CPP) $(CLASS).o $(OBJS:=.o) $(EXEC).o -o $(EXEC)

$(EXEC).o: $(EXEC).cpp
    $(CPP) -c $(EXEC).cpp -o $(EXEC).o $(CXXFLAGS)

$(CLASS).o: $(CLASS).cpp $(CLASS).hpp
    $(CPP) -c $(CLASS).cpp -o $(CLASS).o $(CXXFLAGS)

$(OBJS:=.o): $(OBJS:=.cpp) $(OBJS:=.hpp)
    make --no-print-directory -C $(LIBSPATH)$(strip $(foreach dir,$(LIBS),$(if $(findstring $(dir),$@),$(dir))))
于 2013-10-11T10:57:22.517 に答える