我目前正在学习如何编写makefile。我有以下makefile(它是为一个应该在ARM芯片上运行的C项目自动生成的),我试图理解它:
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
我试图围绕制作$(MAKE) --no-print-directory post-build
文件的规则中的.elf
行。
我找不到变量$(MAKE)
的定义,所以我假设它是内置的。这条线实际上在做什么?
答案 0 :(得分:9)
它是-t
本身的递归调用,转发-n
,-q
和make
选项。这是有道理的:您希望嵌套的library(igraph)
g <- graph.lattice(length=100, dim=1, circular=TRUE)
g2 <- erdos.renyi.game(100, 1/100)
g3 <- g %u% g2
g3 <- simplify(g3)
plot.igraph(g3, vertex.size = 1,vertex.label = NA, layout=layout_in_circle)
调用也可以使用这些选项运行。
答案 1 :(得分:2)
来自docs:
此变量的值是调用make的文件名
在制作某些目标的情况下非常有用,你必须调用 makefile,但是你正在使用-t
进行某种干预(--touch
),-n
(--just-print
)或-q
(--question
)标记。如果使用($MAKE)
,该行为将以递归方式传播。
答案 2 :(得分:1)
MAKE
的含义makefile 中的变量 $(MAKE) 是什么?
请参阅 make 手册(在本地运行 man make
),第 5.7.1 节:https://www.gnu.org/software/make/manual/make.html#MAKE-Variable。
让我强调一下它所说的部分:“递归 make 命令应始终使用变量 MAKE
,而不是显式命令名称 make
。” 这里的“递归”只是意味着您在 makefile 内调用 make
。因此,当您使用 make
调用外部 Makefile 时,它又会通过 MAKE
特殊变量而不是直接通过 make
再次调用 make。请参阅以下手册:
MAKE
变量的工作原理递归 make 命令应始终使用变量 MAKE
,而不是显式命令名称 make
,如下所示:
subsystem:
cd subdir && $(MAKE)
这个变量的值是调用 make 的文件名。如果此文件名为 /bin/make
,则执行的配方为 cd subdir && /bin/make
。如果您使用特殊版本的 make 来运行顶级 makefile,则递归调用将执行相同的特殊版本。
作为一项特殊功能,在规则配方中使用变量 MAKE
会改变 -t
(--touch
)、-n
({{1} }) 或 --just-print
(-q
) 选项。使用 --question
变量与在配方行的开头使用 MAKE
字符具有相同的效果。请参阅而不是执行配方。仅当 +
变量直接出现在配方中时才启用此特殊功能:如果 MAKE
变量是通过扩展另一个变量引用的,则它不适用。在后一种情况下,您必须使用 MAKE
令牌才能获得这些特殊效果。
答案 3 :(得分:0)
请不要与较早的回答说递归调用相混淆。 $ MAKE是默认变量,将其替换为“ make”。
在您的情况下,$ MAKE用于makefile的命令part(配方)。这意味着只要依赖关系发生变化,make就会在 您所在的任何目录 中执行命令“ make --no-print-directory post-build”。
例如,如果我有一种情况, test.o:test.c cd / root / $(MAKE)全部 它说,如果test.c中有更改,请在/ root目录中执行“ make all”。