2009-04-27 7 views
22

私はmakefilesを初めて使っています。私はmakefileの作成や他の関連する概念を "GNU makeプロジェクトでの管理"から学びました。 makefileはすぐに準備ができており、作成したものがOKであることを確認する必要があります。ここでは、メイクファイルリリースとデバッグビルドを使用したシンプルなメイクファイル

#Main makefile which does the build 

#makedepend flags 
DFLAGS = 

#Compiler flags 
#if mode variable is empty, setting debug build mode 
ifeq ($(mode),release) 
    CFLAGS = -Wall 
else 
    mode = debug 
    CFLAGS = -g -Wall 
endif 

CC = g++ 
PROG = fooexe 

#each module will append the source files to here 
SRC := main.cpp 

#including the description 
include bar/module.mk 
include foo/module.mk 

OBJ := $(patsubst %.cpp, %.o, $(filter %.cpp,$(SRC))) 

.PHONY:all 
all: information fooexe 

information: 
ifneq ($(mode),release) 
ifneq ($(mode),debug) 
    @echo "Invalid build mode." 
    @echo "Please use 'make mode=release' or 'make mode=debug'" 
    @exit 1 
endif 
endif 
    @echo "Building on "$(mode)" mode" 
    @echo ".........................." 

#linking the program 
fooexe: $(OBJ) 
    $(CC) -o $(PROG) $(OBJ) 

%.o:%.cpp 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

depend: 
    makedepend -- $(DFLAGS) -- $(SRC) 

.PHONY:clean 
clean: 
    find . -name "*.o" | xargs rm -vf 
    rm -vf fooexe 

質問

  1. 上記のメイクファイルがリリースとうまく動作し、デバッグビルドです。しかし、それは正しい形式ですか?それとも何か欠陥があるのですか?
  2. 上記のmakefileは、makeを使用して呼び出されると、デフォルトでデバッグビルドを行います。リリースビルドの場合、make mode = releaseが必要です。これは正しいアプローチですか?
  3. g ++に提供されているデバッグフラグとリリースコンパイラフラグは正しいですか?デバッグのために、私は-g -Wallを使用し、リリースについては、ちょうど-Wallを使用します。これは正しいですか?

助けがあれば助かります。

+0

Makefileを含むあなたのソフトウェアのソースをリリースする予定ですか?バイナリを出荷していますか?すなわち、あなたとあなたのチーム以外の誰もがこのMakefileを見て、使用しますか? – Schwern

+0

はい。これはオープンソースプロジェクトなので、私はソースコードを公開する予定です。 –

答えて

13
  1. これは合理的なフォーマットの1つです。これはGNU Makeに特化していますが、すべてのプラットフォームでGNU Makeを使用することを選択した場合、これは比較的小さな問題です。
    • 欠陥がある場合は、最終ビルドを作成するためにデバッグモードでビルドされたオブジェクトファイルをリンクする可能性があります。
    • 'mode = release'オプションが非標準であると主張する人もいます。彼らは正しいだろうが、私が認識している標準的な選択肢はありません。あなたは、あなたの大会が誰にも合わないかもしれないことに気づく必要があります(ただし、必ずしもあなたとあなたのユーザーに合っている必要はありません)。
  2. デフォルトでデバッグビルドをビルドすることはおそらく分かりやすく、デフォルトでビルドビルドをビルドするよりも賢明です。
  3. リリースビルドのための-gフラグを削除することは自動的には悪いことではありませんが、コードにコアダンプが生成された場合、プログラムファイルにデバッグ情報が含まれていると、情報をデバッグするための主なコストは、システムメモリにロードする必要のないプログラムファイル内の余分なセクションです。ランタイムコストは小さいです。
    • 最適化フラグをそこに含めるかどうかを検討する必要があります。 GCCツールを設定すると、-g-Oの両方を使用できます。最適化されたコードをデバッグするのは難しいですが、パフォーマンス上のメリットがあります。
+0

"欠陥がある場合は、最終ビルドを作成するためにデバッグモードでビルドされたオブジェクトファイルをリンクすることができます。"私はその声明ではっきりしていない。リリースビルドを行う前に、既存のオブジェクトファイルをすべて削除し、リリースビルドを行います。私は正しいリリースファイルがリンクされるように。それは大丈夫ですか?答えをありがとう。 –

+0

'make'を実行してから、1つのソースファイルを編集し、 'make mode = release'を実行するとします。大半のオブジェクトファイルは、リリースビルドであっても、デバッグモードでコンパイルされていました。あなたが知っているように、あなたが「モードを作る=すべてを解放する」とすれば、あなたは良いものになるはずです。だから私は「それは欠陥だ」とは言わなかった。私はそれが気づいている可能性のある問題であることを示しました。 (また、単純な解決策もありません。コンパイラオプションを含め、オブジェクトファイルの作成方法を記録する、より洗練されたビルドトラッカーが必要です。例については、「ccache」http://ccache.samba.org/を参照してください)。 –

11

私は、次のモードをお勧めします:

for debugger: -O0 -g -Wall 
for development and internal release: -O2 -g -Wall 
for release outside the company: -O2 -Wall 

は理論的根拠:

  • "本番モード" でコードを開発し、テストすることが非常に重要です。 コード内のバグの が最適化モードで最適化せずに動作するコードがある場合があります。 (だから私はこれがたくさん起こると信じて) - だから-O2
  • ほとんどの場合、最適化されたコードでもかなりうまくデバッグできるので、-gを追加してください。ただし、このモードでバグを見つけるのが難しい場合は、-O0
  • でデバッグ用にコンパイルできます。コード内にデバッグ情報を含めて問題がある場合は、-gを削除する必要があります。運用環境のコードには-gがあることをお勧めします。何かクラッシュした場合、より多くの情報を得ることができるからです。
3

私はフラグについてArtyomのアドバイスをとり、-Oを使用します。

私の主な助言は、デフォルトモードを「リリース」にすることです。あなたの会社外のユーザーはあなたのmake mode=releaseの大会について知りません。99.99%の人が解放のために建てられます。

私はすべてのモードで-Wallをオンにしているのが好きです。あなたは本当に賢いことをしたい場合... -Wall -std=c++98 -pedantic -Wextra -Wconversion良いスタートです。 -std = C++ 98は、g ++に組み込まれている場合は必要ないかもしれませんが、移植性の幻想があればそれを望みます。

関連する問題