[解決済み] SRC、OBJ、BIN サブディレクトリを持つ C プロジェクト用の Makefile を作成するにはどうしたらいいですか?
質問
数ヶ月前、私は次のようなジェネリックを思いつきました。
Makefile
を学校の課題のために作成しました。
# ------------------------------------------------
# Generic Makefile
#
# Author: [email protected]
# Date : 2010-11-05
#
# Changelog :
# 0.01 - first version
# ------------------------------------------------
# project name (generate executable with this name)
TARGET = projectname
CC = gcc -std=c99 -c
# compiling flags here
CFLAGS = -Wall -I.
LINKER = gcc -o
# linking flags here
LFLAGS = -Wall
SOURCES := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS := $(SOURCES:.c=*.o)
rm = rm -f
$(TARGET): obj
@$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
@echo "Linking complete!"
obj: $(SOURCES) $(INCLUDES)
@$(CC) $(CFLAGS) $(SOURCES)
@echo "Compilation complete!"
clean:
@$(rm) $(TARGET) $(OBJECTS)
@echo "Cleanup complete!"
これは基本的にすべての
.c
と
.h
を生成するためのファイル
.o
ファイルを生成し、実行ファイルである
projectname
をすべて同じフォルダーに置きます。
さて、これを少し推し進めたいと思います。 次のようなディレクトリ構造のCプロジェクトをコンパイルするためのMakefileはどのように書けばよいでしょうか。
./
./Makefile
./src/*.c;*.h
./obj/*.o
./bin/<executable>
つまり、C言語のソースをコンパイルするMakefileを
./src/
から
./obj/
で、すべてをリンクして、実行ファイルを
./bin/
.
私はさまざまな Makefile を読んでみましたが、上記のプロジェクト構造に対してそれらを動作させることができません。代わりに、プロジェクトはあらゆる種類のエラーを伴ってコンパイルに失敗します。もちろん、私は完全な IDE (Monodevelop, Anjuta など) を使用できましたが、正直なところ、私は gEdit と古き良きターミナルに固執することを好みます。
作業ソリューション、またはこれがどのように行われるかについての明確な情報を与えてくれるグルはいますか?ありがとうございます。
** アップデイト(v4) **
最終的な解決策:
# ------------------------------------------------
# Generic Makefile
#
# Author: [email protected]
# Date : 2011-08-10
#
# Changelog :
# 2010-11-05 - first version
# 2011-08-10 - added structure : sources, objects, binaries
# thanks to http://stackoverflow.com/users/128940/beta
# 2017-04-24 - changed order of linker params
# ------------------------------------------------
# project name (generate executable with this name)
TARGET = projectname
CC = gcc
# compiling flags here
CFLAGS = -std=c99 -Wall -I.
LINKER = gcc
# linking flags here
LFLAGS = -Wall -I. -lm
# change these to proper directories where each file should be
SRCDIR = src
OBJDIR = obj
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
@$(LINKER) $(OBJECTS) $(LFLAGS) -o $@
@echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
@$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"
.PHONY: clean
clean:
@$(rm) $(OBJECTS)
@echo "Cleanup complete!"
.PHONY: remove
remove: clean
@$(rm) $(BINDIR)/$(TARGET)
@echo "Executable removed!"
どのように解決するのですか?
まず、あなたの
$(OBJECTS)
のルールは問題があります、なぜなら。
- は無差別であり、そのため をすべて ソースをすべてのオブジェクトの前提条件とします。
-
は、しばしば
間違ったソース
を使うことがあります (あなたが
file1.o
とfile2.o
) - は、オブジェクトで停止するのではなく、実行可能ファイルをビルドしようとします。
-
ターゲットの名前 (
foo.o
) は、ルールが実際に生成するものではありません (obj/foo.o
).
を提案します。
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@
@echo "Compiled "$<" successfully!"
は
$(TARGET)
ルールは、ターゲット名が実際にルールを構築するものを記述していないという同じ問題を抱えています。そのため、もしあなたが
make
を何度も入力すると、Make はその都度ターゲットを再構築します。小さな変更により、この問題は修正されました。
$(BINDIR)/$(TARGET): $(OBJECTS)
$(LINKER) $@ $(LFLAGS) $(OBJECTS)
@echo "Linking complete!"
もし、ヘッダファイルの一つを変更した場合、この makefile はどのオブジェクト/実行可能ファイルを再構築しなければならないかを知ることができません。しかし、それは別の日に待つことができます。
EDIT:
すみません、一部省略しました。
$(OBJECTS)
のルールの一部を省略していましたので、修正しました。(コードサンプル内で"strike"が使えればいいのですが...)
関連
-
[C] レポートエラー 代入の左オペランドとしてlvalueが必要
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
#137: 式は変更可能なlvalueでなければならない問題 // 文字列配列の代入問題
-
関数 'malloc' の暗黙の宣言に対する解決策
-
未定義の `__isoc99_sscanf' への参照
-
C 言語のポインタ配列のポインタ型、ポインタに値を割り当てるために配列名を使用、コンパイル時の警告:互換性のないポインタ型からの初期化
-
[解決済み] CコードでEOFを表現する?
-
[解決済み] ++iとi++の違いは何ですか?
-
[解決済み] 難読化Cコードコンテスト2006。sykes2.cの解説をお願いします。
-
[解決済み] C 言語の配列へのポインタ/ポインタの配列の曖昧さ解消
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
警告: 'struct XXX' はパラメータリストの内部で宣言されています。
-
[解決済み] Code::Blocks アプリケーションをコンパイルできない
-
[解決済み] C言語でchar配列をコピーする方法は?
-
[解決済み] stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み] なぜmemsetではなくbzeroを使用するのですか?
-
[解決済み] mallocの結果はキャストするのですか?
-
[解決済み] C言語のコードで「:-!」とは何ですか?
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み] C言語の構造体(CGRectやCGPointなど)をNSLog化することは可能ですか?