makefile中的预构建步骤

时间:2009-10-23 09:16:39

标签: makefile prebuild

如何运行必须在所有其他makefile命令之前执行的脚本?如果没有什么可构建的话,脚本的执行会很好(但不是强制性的)。

我搜索了SO和Google,但找不到任何内容。

我有这个解决方法:

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

但它非常难看。还有其他方法可以在 makefile 中运行“预构建步骤”吗?

5 个答案:

答案 0 :(得分:26)

我提出两种解决方案。第一个模仿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

第二个是Eclipse IDE生成的:

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

请注意,在第一个版本中,无论主要版本是否确定为最新版本,都会调用前置和后置版本。

在第二个中,如果主构建的状态是最新的,则不执行构建后步骤。虽然预构建步骤总是在两者中执行。

答案 1 :(得分:11)

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

CHEAT_ARG := $(shell myscript)

请注意冒号。

这只运行一次。永远不会超过一次,但也不会少于一次。选择你自己的权衡。

答案 2 :(得分:5)

您可以在Makefile中添加一个特殊目标,并让所有构建规则依赖于:

run-script:
    myscript

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

.o.S: run-script
     $(AS) $(AFLAGS) -o $@ $<

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

答案 3 :(得分:3)

你提出的建议似乎有些“不像制造”。为什么不在以前需要它的makefile目标中运行命令呢?

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

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

答案 4 :(得分:1)

谢谢你的回答。 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_FILE)后执行脚本。因此,AXF_FILE的值可能会错误。 现在只有 ndim 的第一个答案可以正常工作。