web-dev-qa-db-ja.com

リリースビルドとデバッグビルドを備えたシンプルなメイクファイル-ベストプラクティス

Makefileは初めてです。 「GNU make」を使用したプロジェクトの管理」の本から、メイクファイルの作成とその他の関連概念を学びました。メイクファイルの準備ができたので、作成したものに問題がないことを確認する必要があります。これがメイクファイルです。

#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 $@

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

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

質問

  1. 上記のmakefileは、リリースビルドとデバッグビルドでうまく機能します。しかし、それは正しい形式ですか?それとも、そこに欠陥がありますか?
  2. 上記のmakefileは、makeを使用して呼び出されると、デフォルトでビルドをデバッグします。リリースビルドの場合、make mode = releaseが必要です。これは正しいアプローチですか?
  3. G ++に提供されているデバッグおよびリリースコンパイラフラグは正しいですか?デバッグには-g -Wallを使用し、リリースには-Wall。これは正解?

どんな助けでも素晴らしいでしょう。

23
Navaneeth K N
  1. これは妥当な形式の1つです。これは特にGNU Makeに関連付けられていますが、GNU Makeをすべてのプラットフォームで使用することを選択した場合は比較的小さな問題です。
    • 欠陥がある場合は、デバッグモードでビルドされたオブジェクトファイルをリンクして、最終的なビルドを作成する可能性があります。
    • 'mode = release'オプションは非標準であると主張する人もいるかもしれません。それらは正しいでしょうが、私が知っている標準的な代替手段はありません。コンベンションがすべての人に適しているとは限らないことに注意する必要があります(ただし、必ずしもそうする必要はありません。自分とユーザーに適している必要があります)。
  2. デフォルトでデバッグビルドをビルドすることはおそらく賢明です-そしてデフォルトでリリースビルドをビルドするよりも賢明です。
  3. リリースビルドの-gフラグを削除しても、自動的に悪いわけではありませんが、コードでコアダンプが生成された場合、プログラムファイルにデバッグ情報が含まれていれば、コアダンプの先頭または末尾を作成する方が簡単です。情報をデバッグするための主なコストは、システムメモリにロードする必要のないプログラムファイル内の余分なセクションです。実行時のコストはわずかです。
    • そこに最適化フラグを含めるかどうかを検討する必要があります。 GCCツールセットを使用すると、-g-Oの両方を使用できます。最適化されたコードをデバッグするのは困難ですが、(多くの場合、重要な)パフォーマンス上の利点があります。
13

次のモードをお勧めします。

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を用意することをお勧めします。何かがクラッシュした場合、より多くの情報を取得できるからです。
11
Artyom

フラグに関するArtyomのアドバイスを参考にして、-Oを利用します。

私の主なアドバイスは、デフォルトモードを「リリース」にすることです。社外のユーザーはあなたのmake mode=release規則について知ることはなく、99.99%のユーザーがリリース用に構築することを望んでいます。

すべてのモードで-Wallがオンになっているのが好きです。あなたが本当に衒学者になりたいのなら...-Wall -std=c++98 -pedantic -Wextra -Wconversionは良いスタートです。 -std = c ++ 98は、g ++に慣れている場合は必要ないかもしれませんが、移植性の幻想がある場合は、それが必要になります。

3
Schwern