什么是makefile中的变量$(MAKE) ?



我目前正在学习如何编写makefiles。我有以下makefile(这是自动生成的c项目,应该在ARM芯片上运行),我试图理解它:

    RM := rm -rf
    # All of the sources participating in the build are defined here
    -include sources.mk
    -include FreeRTOS/Supp_Components/subdir.mk
    -include FreeRTOS/MemMang/subdir.mk
    -...
    -include subdir.mk
    -include objects.mk
    ifneq ($(MAKECMDGOALS),clean)
    ifneq ($(strip $(S_UPPER_DEPS)),)
    -include $(S_UPPER_DEPS)
    endif
    ifneq ($(strip $(C_DEPS)),)
    -include $(C_DEPS)
    endif
    endif
    -include ../makefile.defs
    # Add inputs and outputs from these tool invocations to the build variables 
    # All Target
    all: FreeRTOS_T02.elf
    # Tool invocations
    FreeRTOS_T02.elf: $(OBJS) $(USER_OBJS)
        @echo 'Building target: $@'
        @echo 'Invoking: MCU GCC Linker'
        arm-none-eabi-gcc -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -specs=nosys.specs -specs=nano.specs -T LinkerScript.ld -Wl,-Map=output.map -Wl,--gc-sections -lm -o "FreeRTOS_T02.elf" @"objects.list" $(USER_OBJS) $(LIBS)
        @echo 'Finished building target: $@'
        @echo ' '
        $(MAKE) --no-print-directory post-build
    # Other Targets
    clean:
        -$(RM) *
        -@echo ' '
    post-build:
        -@echo 'Generating binary and Printing size information:'
        arm-none-eabi-objcopy -O binary "FreeRTOS_T02.elf" "FreeRTOS_T02.bin"
        arm-none-eabi-size "FreeRTOS_T02.elf"
        -@echo ' '
    .PHONY: all clean dependents
    .SECONDARY: post-build
    -include ../makefile.targets

我正试图把我的头绕在.elf文件规则中的$(MAKE) --no-print-directory post-build行。

我找不到变量$(MAKE)的定义,所以我假设它是内置的东西。这条线实际上在做什么?

这是make本身的递归调用,转发-t, -n-q选项。这很有意义:您希望嵌套的make调用也使用这些选项运行。

From the docs:

这个变量的值是调用make的文件名

在必须调用 makefile来创建某些目标的情况下很有用,但是您正在使用-t (--touch), -n (--just-print)或-q (--question)标志进行某种演练。如果使用($MAKE),该行为将递归传播。

请不要与前面的递归调用的答案混淆。$MAKE是默认变量,会被"make"代替。

在您的场景中,$MAKE用于makefile的命令部分(recipe)。这意味着每当依赖项发生变化时,make在中执行命令make --no-print-directory post-build,无论您在的哪个目录。

例如,如果我有一个case,在

test.o: test.c
      cd /root/
      $(MAKE) all

它说,如果test.c有变化,执行/root目录下的make all

变量MAKE在Makefile中的含义

什么是makefile中的变量$(MAKE) ?

参见make manual (run man make local),章节5.7.1:https://www.gnu.org/software/make/manual/make.html#MAKE-Variable。

让我强调一下它所说的部分:递归的make命令应该始终使用变量MAKE,而不是显式的命令名称make"Recursive"这里仅仅意味着您在makefile中调用make。因此,当您使用make调用外部Makefile时,它又会通过MAKE特殊变量而不是直接通过make再次调用make。参见下面的手册:

5.7.1 MAKE变量如何工作

递归make命令应该始终使用变量MAKE,而不是显式命令名称make,如下所示:

subsystem:
        cd subdir && $(MAKE)

该变量的值是调用make时使用的文件名。如果这个文件名是/bin/make,那么执行的配方就是cd subdir && /bin/make。如果您使用特殊版本的make来运行顶级的makefile,那么递归调用也将执行相同的特殊版本。

作为一个特殊的特性,在规则的配方中使用变量MAKE会改变-t (--touch)、-n (--just-print)或-q (--question)选项的效果。使用MAKE变量与在配方行开头使用+字符具有相同的效果。参见代替执行食谱。这个特殊的特性只有在MAKE变量直接出现在配方中时才会启用:如果MAKE变量是通过扩展另一个变量来引用的,那么这个特性就不适用。在后一种情况下,您必须使用+令牌来获得这些特殊效果。

最新更新