Makefile-命令中的命令?

Makefile-命令中的命令?,makefile,Makefile,我有一个令人尴尬的简单的makefile问题,但由于缺乏知识,我不能用谷歌搜索它——我不知道我不知道的单词 基本上,我希望在当前目录中运行makefile,查看./SRC目录中的源文件,当一切完成后,将目标文件移动到./OBJ目录中 生成文件: move_obj: mv -f -t ./OBJ_DIR ./$(OBJ_FILES) file.o: other_file.h $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c move_obj

我有一个令人尴尬的简单的makefile问题,但由于缺乏知识,我不能用谷歌搜索它——我不知道我不知道的单词

基本上,我希望在当前目录中运行makefile,查看./SRC目录中的源文件,当一切完成后,将目标文件移动到./OBJ目录中

生成文件:

move_obj: 
    mv -f -t ./OBJ_DIR ./$(OBJ_FILES)

file.o: other_file.h 
    $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c
    move_obj
我想在编译源文件后调用“move_obj”,但因为我不知道是什么

result: dependency
    evaluation
实际上代表了(我找到的所有makefile介绍指南都说明了“这就是makefile的样子,你去吧”),我不知道为什么这不起作用。我想我需要一些求值命令或者需要定义一个函数或者


提前谢谢你的帮助

如果您想一个接一个(file.o)构建目标(
move_obj
),请将
move_obj
添加到
file.o
的依赖项列表中,以便执行
move_obj
下的命令

因此,您的
Makefile
应该是:

file.o: other_file.h move_obj
    $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c

move_obj: 
    mv -f -t ./OBJ_DIR ./$(OBJ_FILES)
正如注释部分提到的那样,您可以在所需目录中构建目标文件,而不是编译然后移动

file.o: other_file.h
    $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c -o ./$(OBJ_FILES)/$@

如果您想在另一个(file.o)之后构建目标(
move_obj
),请将
move_obj
添加到
file.o
的依赖项列表中,以便执行
move_obj
下的命令

因此,您的
Makefile
应该是:

file.o: other_file.h move_obj
    $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c

move_obj: 
    mv -f -t ./OBJ_DIR ./$(OBJ_FILES)
正如注释部分提到的那样,您可以在所需目录中构建目标文件,而不是编译然后移动

file.o: other_file.h
    $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c -o ./$(OBJ_FILES)/$@

您可以通过创建另一个
规则
来实现这一点,例如
移动
,如下所示

all: $(EXECUTABLE) move

$(EXECUTABLE):  $(OBJECTFILES)
            $(CC) -o $@ $<
$(OBJECTFILES): $(SOURCEFILES)
            $(CC) $(CFLAGS) -c -o $@ -I $(INCLUDE_PATH) $<

# Move the .o to Object directory #
move:           
            $(MV) $(OBJECTFILES) $(OBJECT_PATH)
下面是makefile,它也在做同样的事情

C_FLAGS := -g -Wall -Wextra
CC := gcc
RM := rm
LINKFLAGS := -lanylibrary

.PHONY: $(TARGET) clean

VPATH:= ./src/ ./obj/ ./include/

# Path for .c , .h and .o Files 
SRC_PATH := ./src/
OBJ_PATH := ./obj/
INC_PATH := -I ./include

# Executable Name 
TARGET := exe

# Files to compile
OBJ1 := foo.o \
        main.o

OBJ := $(patsubst %,$(OBJ_PATH)%,$(OBJ1))

# Build .o first
$(OBJ_PATH)%.o: $(SRC_PATH)%.c
                @echo [CC] $<
                @$(CC) $(C_FLAGS) -o $@ -c $< $(INC_PATH)                  

# Build final Binary
$(TARGET):      $(OBJ)
                @echo [INFO] Creating Binary Executable [$(TARGET)]
                @$(CC) -o $@ $^ $(LINKFLAGS)

# Clean all the object files and the binary
clean:   
                @echo "[Cleaning]"
                @$(RM) -rfv $(OBJ_PATH)*
                @$(RM) -rfv $(TARGET)

您可以通过创建另一个
规则
来实现这一点,例如
移动
,如下所示

all: $(EXECUTABLE) move

$(EXECUTABLE):  $(OBJECTFILES)
            $(CC) -o $@ $<
$(OBJECTFILES): $(SOURCEFILES)
            $(CC) $(CFLAGS) -c -o $@ -I $(INCLUDE_PATH) $<

# Move the .o to Object directory #
move:           
            $(MV) $(OBJECTFILES) $(OBJECT_PATH)
下面是makefile,它也在做同样的事情

C_FLAGS := -g -Wall -Wextra
CC := gcc
RM := rm
LINKFLAGS := -lanylibrary

.PHONY: $(TARGET) clean

VPATH:= ./src/ ./obj/ ./include/

# Path for .c , .h and .o Files 
SRC_PATH := ./src/
OBJ_PATH := ./obj/
INC_PATH := -I ./include

# Executable Name 
TARGET := exe

# Files to compile
OBJ1 := foo.o \
        main.o

OBJ := $(patsubst %,$(OBJ_PATH)%,$(OBJ1))

# Build .o first
$(OBJ_PATH)%.o: $(SRC_PATH)%.c
                @echo [CC] $<
                @$(CC) $(C_FLAGS) -o $@ -c $< $(INC_PATH)                  

# Build final Binary
$(TARGET):      $(OBJ)
                @echo [INFO] Creating Binary Executable [$(TARGET)]
                @$(CC) -o $@ $^ $(LINKFLAGS)

# Clean all the object files and the binary
clean:   
                @echo "[Cleaning]"
                @$(RM) -rfv $(OBJ_PATH)*
                @$(RM) -rfv $(TARGET)

这在很多方面都有缺陷

  • result
    通常是一个实际文件,在配方执行后应该出现。如果文件已经存在并且不早于其任何依赖项,
    make
    不执行任何操作。因此,不要在某个地方创建一个文件,然后用另一个规则将其移动,而是确保该规则在最终应该在的位置创建它。否则,
    make
    将永远无法检查是否必须重建它(并且将始终如此)。在这种情况下,使用编译器的
    -o
    标志直接在应该的位置创建它(例如
    -o$(OBJ_DIR)/file.o

  • dependency
    应该列出生成
    结果所需的所有文件,因此
    make
    如果这些文件中的任何一个发生了更改,就会真正地重建它。在您的情况下,依赖项列表中至少缺少
    file.c

  • 为了在目录中放置文件,您应该确保它存在。你可以这样做:

    $(OBJ_DIR):
        mkdir -p $(OBJ_DIR)
    
    $(OBJ_DIR)/file.o: $(OBJ_DIR) file.c other_file.h
        $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c -o $(OBJ_DIR)/file.o
    
  • 您的move_obj配方虽然在本例中不适用,但可能是一个虚假的目标,这意味着它不会创建文件。如果您需要这些规则,请相应地标记它们,将其称为特殊目标的依赖项。
    。PHONY

    .PHONY: move_obj
    
    这样做的原因是,您可能(偶然)在工作目录中有一个名为move_obj的文件。在这种情况下,make将决定对move_obj不做任何事情,而这不是您想要的。将其标记为虚假会告诉make此规则不会创建其目标,并且无论发生什么情况,都必须执行配方


  • 总之,您的问题归结为将Makefile误解为脚本。事实并非如此。它是一个声明性文件,告诉make为了构建文件(您的
    评估
    块)必须做什么,以及何时需要做什么(您的
    依赖关系
    块)。最好不要尝试将Makefile误用为脚本。

    这在很多方面都有缺陷

  • result
    通常是一个实际文件,在配方执行后应该出现。如果文件已经存在并且不早于其任何依赖项,
    make
    不执行任何操作。因此,不要在某个地方创建一个文件,然后用另一个规则将其移动,而是确保该规则在最终应该在的位置创建它。否则,
    make
    将永远无法检查是否必须重建它(并且将始终如此)。在这种情况下,使用编译器的
    -o
    标志直接在应该的位置创建它(例如
    -o$(OBJ_DIR)/file.o

  • dependency
    应该列出生成
    结果所需的所有文件,因此
    make
    如果这些文件中的任何一个发生了更改,就会真正地重建它。在您的情况下,依赖项列表中至少缺少
    file.c

  • 为了在目录中放置文件,您应该确保它存在。你可以这样做:

    $(OBJ_DIR):
        mkdir -p $(OBJ_DIR)
    
    $(OBJ_DIR)/file.o: $(OBJ_DIR) file.c other_file.h
        $(CC) $(CFLAGS) $(CPPFLAGS) -c file.c -o $(OBJ_DIR)/file.o
    
  • 您的move_obj配方虽然在本例中不适用,但可能是一个虚假的目标,这意味着它不会创建文件。如果您需要这些规则,请相应地标记它们,将其称为特殊目标的依赖项。
    。PHONY

    .PHONY: move_obj
    
    这样做的原因是,您可能(偶然)在工作目录中有一个名为move_obj的文件。在这种情况下,make将决定对move_obj不做任何事情,而这不是您想要的。将其标记为虚假会告诉make此规则不会创建其目标,并且无论发生什么情况,都必须执行配方


  • 总之,您的问题归结为将Makefile误解为脚本。事实并非如此。它是一个声明性文件,告诉make为了构建文件(您的
    评估
    块)必须做什么,以及何时需要做什么(您的
    依赖关系
    块)。最好不要尝试将Makefile误用为脚本。

    可以通过在move\u obj中对file.o添加依赖项来实现。为什么不