makefile中的预构建步骤

makefile中的预构建步骤,makefile,prebuild,Makefile,Prebuild,如何运行脚本,它必须在所有其他makefile命令之前执行?如果没有要构建的内容,那么脚本就不会被执行,这会很好(但不是强制性的) 我搜索了SO和Google,但什么也没找到 我有一个解决办法: # myscript.bat output is empty CHEAT_ARGUMENT = (shell myscript.bat) CFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT) AFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARG

如何运行脚本,它必须在所有其他makefile命令之前执行?如果没有要构建的内容,那么脚本就不会被执行,这会很好(但不是强制性的)

我搜索了SO和Google,但什么也没找到

我有一个解决办法:

# myscript.bat output is empty
CHEAT_ARGUMENT = (shell myscript.bat)
CFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)
AFLAGS += -DCHEAT_ARGUMENT=$(CHEAT_ARGUMENT)

但是它很难看。是否有其他方法在makefile中运行“预构建步骤”

根据您的
make
版本,如果对CFLAG和AFLAG进行了几十次评估,则至少应避免运行几十次以下内容:

CHEAT_ARG := $(shell myscript)
注意冒号


这只运行一次。不要超过一次,也不要少于一次。选择你自己的折衷方案。

你的建议似乎有点“不合常规”。为什么不在您需要的makefile目标中运行该命令呢

例如,如果需要在链接
foo
之前运行它:

foo: ${OBJS}
    my-command-goes-here
    ${CC} -o $@ ${OBJS} ${LIBS}

您可以将特殊目标添加到Makefile中,并使所有生成规则都依赖于此:

run-script:
    myscript

.o.c: run-script
     $(CC) $(CFLAGS) -o $@ $<

.o.S: run-script
     $(AS) $(AFLAGS) -o $@ $<
运行脚本:
myscript
.o.c:运行脚本
$(CC)$(CFLAGS)-o$@$<
.o.S:运行脚本
$(AS)$(AFLAGS)-o$@$<

根据您的脚本实际执行的操作,将其放在Makefile之前的一个阶段中运行一次(用autoconf术语配置阶段)可能更有意义(而且工作量更少)。

谢谢您的回答ndim帮助了我很多,asveikau。最后一个文件是一个二进制可执行文件,因此我现在可以使用如下内容:

run-script:
    myscript
$(AXF_FILE): run-script $(OBJ_DIRS) $(OBJ_FILES)
    $(LINK) #......
它将运行myscript一次。{AXF_FILE}值取决于myscript,我必须在之前运行它。在这种情况下,myscript总是运行,而不仅仅是在需要重建时。 之后,我想到了最简单的答案:

all: run-script $(AXF_FILE)
这就是全部(当然,可以使用任何目标而不是“全部”)


编辑:此方法在计算$(AXF\U文件)后执行脚本。所以可能会得到错误的AXF_文件值。
现在只有ndim的第一个答案符合我的需要。

我提出了两个解决方案。第一个模拟NetBeans IDE生成的内容:

CC=gcc

.PHONY: all clean

all: post-build

pre-build:
    @echo PRE

post-build: main-build
    @echo POST

main-build: pre-build
    @$(MAKE) --no-print-directory target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)

clean:
    rm -f $(OBJS) target
CC=gcc

.PHONY: all clean
.SECONDARY: main-build

all: pre-build main-build

pre-build:
    @echo PRE

post-build:
    @echo POST

main-build: target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)
    @$(MAKE) --no-print-directory post-build

clean:
    rm -f $(OBJS) target
第二个是Eclipse IDE生成的内容:

CC=gcc

.PHONY: all clean

all: post-build

pre-build:
    @echo PRE

post-build: main-build
    @echo POST

main-build: pre-build
    @$(MAKE) --no-print-directory target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)

clean:
    rm -f $(OBJS) target
CC=gcc

.PHONY: all clean
.SECONDARY: main-build

all: pre-build main-build

pre-build:
    @echo PRE

post-build:
    @echo POST

main-build: target

target: $(OBJS)
    $(CC) -o $@ $(OBJS)
    @$(MAKE) --no-print-directory post-build

clean:
    rm -f $(OBJS) target
请注意,在第一个版本中,无论主版本是否被确定为最新版本,都将始终调用预版本和后版本



在第二个步骤中,如果主生成的状态是最新的,则不执行生成后步骤。虽然预构建步骤总是在这两种情况下执行。

即使不需要,它也不会运行吗?问题是,如果没有什么可建的,就不要执行它。哦,对了。好吧,至少它只运行一次,因此不会超过一次,即使有几十条规则扩展CFLAGS和AFLAGS.ndim,谢谢!这个答案对我来说是最好的。如果脚本生成的任何文件是另一个文件的依赖项,则此解决方案将被破坏:Make不“知道”$(shell)可以修改文件,因此它可能具有运行myscript之前的缓存文件时间戳。发生这种情况时,您将从过期的对象文件中获得一个已损坏的生成。@奥尔斯纳:我的印象是,在make实际开始评估文件依赖关系规则之前,make在“FOO:=$(shell FOO)”中运行了shell命令。我要去核实一下。谢谢你的回答。是的,我也试过这个。但是我有几个$(CC)和$(AS)规则(armasm对不同的体系结构使用不同的参数-二进制是通用的,并且在运行时选择依赖于体系结构的代码)。在很多地方添加“我的命令”不是个好主意。但比我目前的方法更好的是,我不能在链接之前运行它,因为我需要它的结果更早。我只想运行一次,而不是每次处理文件。在任何其他文件处理之前。这几乎和asveikau建议的一样。脚本将在每个文件之前执行(多次)。而autoconf的结果将与您的第一个答案相同,不是吗?嗯,您是对的(需要更多咖啡)。只有在脚本上表达一些适当的make dep时,才能在调用时保存。不,无论生成多少其他目标,脚本最多运行一次。试试看,“如果没有什么可建,就不要执行”现在不是很重要,但会很好。问题变了。你们最终想做什么?myscript.bat做什么?您真的只是想计算一些额外的编译器标志,还是这是一个人为的例子?我的脚本得到SVN修订并检查,它是从上次提交时修改的。它将此信息放到其他脚本(generate rev.bat file)中,该脚本可以简单地输出此信息,而无需其他任何操作。稍后在makefile中,我使用REVISION=$(shell rev.bat)来获取此信息。然后:AXF_FILE=project_r$(REVISION)$(ARCHITECTURE)。在第二个示例中,axfpre构建不必在主构建之前运行,因为它们之间没有依赖关系。如果你做平行制作,要注意这一点。斯科特·威尔斯是正确的。我已经看到从预构建到主构建,从主构建到后构建,都添加了额外的依赖项来应对这种情况。我认为你是对的。。。请随意建议/编辑以改进第二个示例。@mlepage但是如果您添加了额外的依赖项,现在是否会在每次调用make时强制主生成运行,无论其依赖项是否实际发生了更改?我认为这不能保证在生成obj文件之前运行脚本。@mlepage是的,证明它的简单方法是运行
make-j4