こんにちは、現役エンジニアの inno_tech です。
Makefileを使った開発中に make: *** No rule to make target '@mkdir', needed by 'makedir'. Stop.
や make: *** No rule to make target 'rm', needed by 'clean'. Stop.
というエラーが発生しました。
問題 | Makefile で make時にエラーが発生
C言語のプログラムをコンパイルをしたくて、下記のようなMakefileを作りました。
# directory設定
SRC_DIR = src
INCLUDE_DIR = include
OBJ_DIR = obj
DBG_DIR = debug
BIN_DIR = bin
# ソースファイル
## IGNORE_SRCで指定したファイル以外の[xxx.c]をコンパイル
IGNORE_SRC = $(SRC_DIR)/ignore_file.c
SRCS = $(filter-out $(IGNORE),$(wildcard $(SRC_DIR)/*.c))
OBJS = $(subst $(SRC_DIR),$(OBJ_DIR),$(SRCS:.c=.o))
OBJS_DEBUG = $(subst $(SRC_DIR),$(DBG_DIR),$(SRCS:.c=.o))
# 出力ファイル名
TARGET_NAME = main.out
TARGET = $(BIN_DIR)/$(TARGET_NAME)
TARGET_DEBUG = $(DBG_DIR)/$(TARGET_NAME)
# コンパイラ設定
## gcc or g++
CC = gcc
## コンパイルフラグ
CFLAGS = -Wall -I$(INCLUDE_DIR)
DBGCFLAGS = -g -Wall -I$(INCLUDE_DIR)
# default rule
default: makedir all foot_print
# non-phony targets
## release ビルド
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS)
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c -o $@ $<
## debug ビルド
$(TARGET_DEBUG): $(OBJS_DEBUG)
$(CC) $(DBGCFLAGS) -o $@ $(OBJS_DEBUG)
$(DBG_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(DBGCFLAGS) -c -o $@ $<
# 設定の表示
foot_print:
@echo "*** Finish make ***"
# phony rules
# releaseビルド
.PHONY: all
all: $(TARGET)
# debugビルド
.PHONY: debug
debug: makedir $(TARGET_DEBUG) foot_print
# ディレクトリ作成
.PHONY: makedir
makedir: @mkdir -p $(BIN_DIR) $(OBJ_DIR) $(DBG_DIR)
# clean .PHONY: clean
clean: rm -f $(OBJS) $(OBJ_DEBUG) $(TARGET) $(TARGET_DEBUG)
いざ make
を実行したところ、make: *** No rule to make target '@mkdir', needed by 'makedir'. Stop.
というエラーが発生しました。
おかしいなと思い、make clean
を実行してもmake: *** No rule to make target 'rm', needed by 'clean'. Stop.
というエラーになりました。
あれ、何が悪いんだろ…
原因 | :(コロン) の後ろにコマンドを記述してはいけない
今回のエラー原因は、mkdir
や rm
といったOSコマンドを利用している部分の記述ミスでした。問題個所は以下の部分です。
# ディレクトリ作成
.PHONY: makedir
makedir: @mkdir -p $(BIN_DIR) $(OBJ_DIR) $(DBG_DIR)
# clean .PHONY: clean
clean: rm -f $(OBJS) $(OBJ_DEBUG) $(TARGET) $(TARGET_DEBUG)
Makefileでは本来、:
の後ろには そのターゲットの依存関係 を記述する必要がありますが、エラーが発生したMakefileでは、makedir
やclean
と同じ行にOSコマンドを記述してしまっています。
解決策 | Makefileを修正
正しくは、[target]: の後に改行した上でOSコマンドを記述します。
# ディレクトリ作成
.PHONY: makedir
makedir:
@mkdir -p $(BIN_DIR) $(OBJ_DIR) $(DBG_DIR)
# clean .PHONY: clean
clean:
rm -f $(OBJS) $(OBJ_DEBUG) $(TARGET) $(TARGET_DEBUG)
ただの凡ミスでした…。気を付けよう。
まとめ
今回のまとめです。
- Makefileでは、
[target]:
以降の部分には 依存関係のみ を記述する. - targetで実行する処理は、改行して後に記述する必要があるので注意.
最後に、紙の本[経済・ビジネス]部門で2022年年間ランキングで第1位になったベストセラー書籍がこちら。
参考になったでしょうか。
ほかにも役立つ情報が他のページにもあるかもしれません。
ご覧になるかはあなた次第です!
この記事がイイねと思ったら、Twitterフォロー か にほんブログ村のどちらかしてくれたら嬉しいよ!
コメント / ご要望