2017-09-04 7 views
2

最初の例ではMakefileが正しく動作していて、2番目の例ではまったく動作していません。Makefile規則の混乱

ワーキング:

CC=gcc 
CFLAGS=-Wall -Wextra -Werror 
FILES=$(addprefix src/, ft_putnbr ft_putchar main) 
OBJ=$(addsuffix .o, $(FILES)) 
NAME=put 

$(NAME): $(OBJ) 
    $(CC) -o $(NAME) $(OBJ) 
%.o: %.c 
    gcc -c $^ -o [email protected] $(CFLAGS) -I includes/ 
clean: 
    rm -f $(OBJ) 

に動作していない:

CC=gcc 
CFLAGS=-Wall -Wextra -Werror 
FILES=$(addprefix obj/, ft_putnbr ft_putchar main) 
OBJ=$(addsuffix .o, $(FILES)) 
NAME=put 

$(NAME): $(OBJ) 
    $(CC) -o $(NAME) $(OBJ) 
%.o: $(subst obj,src, %.c) 
    gcc -c $^ -o [email protected] $(CFLAGS) -I includes/ 
clean: 
    rm -f $(OBJ) 

唯一の違いは/ objに設定FILES接頭辞であること、私はobjがソースファイルからファイル分離したかったので、私が使用するために必要なので、 $(substitute)関数を使用して、ルールの1つでディレクトリを変更します。 二Makefileは生成します。

make: *** No rule to make target 'obj/ft_putnbr.o', needed by 'put'. Stop. 

誰もがここに私のミスを見ていますか? makefileで

答えて

2

、拡張の対象となるコンテキストは、パターンルールがこれらのいずれでもない形態 $(...)又は${...}

です。だから、:

%.o: %.c 
    ... 

stem.ostemの任意の値のため、...を行うことによってstem.c から作られていることを意味するものとしてmakeによって解釈が、%.o: %.cは、フォーム$(...)のではなく、それが拡張されていない です。

したがって、文脈において、

%.o: $(subst obj,src, %.c) 

意味:

$(subst obj,src, %.c) 

は単純である:ストリングsrcobjのすべての発生を置き換える結果%.c。 文字列%.cobjの出現がありません。結果は単に%.c、 のままです。だからあなたの第二のmakefileは同等です:中

CC=gcc 
CFLAGS=-Wall -Wextra -Werror 
FILES=$(addprefix obj/, ft_putnbr ft_putchar main) 
OBJ=$(addsuffix .o, $(FILES)) 
NAME=put 

$(NAME): $(OBJ) 
    $(CC) -o $(NAME) $(OBJ) 
%.o: %.c 
    gcc -c $^ -o [email protected] $(CFLAGS) -I includes/ 
clean: 
    rm -f $(OBJ) 

、例えば、ターゲットobj/ft_putnbr.oが前提obj/ft_putnbr.cが存在する場合にのみ ルール%.o: %.cを満足させます。 それは存在しません。したがって:

No rule to make target 'obj/ft_putnbr.o 

代わりに使用します。

のMakefile

CC=gcc 
CFLAGS=-Wall -Wextra -Werror 
SRCS=ft_putnbr.c ft_putchar.c main.c 
OBJS=$(addprefix obj/,$(SRCS:.c=.o)) 
NAME=put 

$(NAME): $(OBJS) 
    $(CC) -o $(NAME) $(OBJS) 

obj/%.o: src/%.c | obj 
    gcc -c $< -o [email protected] $(CFLAGS) -I includes/ 

obj: 
    mkdir -p [email protected] 

clean: 
    rm -fr obj $(NAME) 

または類似。このメークファイルは、そのディレクトリをorder-only prerequisite$(OBJS)にすることによって、ディレクトリobjが に存在することを確実にしてから、オブジェクトファイルをコンパイルしようとします。