强制Makefile在构建任何目标后执行脚本(在退出之前)

时间:2013-12-14 10:14:37

标签: shell makefile

我想在make退出时执行shell命令,无论它构建的目标是什么。似乎make没有办法直接这样做。但是,这是一个在启动时执行shell命令的示例,无论目标是什么:

Force Makefile to execute script before building targets

有没有类似的hack在退出之前执行一次shell命令?我可以把命令放在每个目标的底部,但是a)它会被执行多次,而b)这很丑陋且难以管理。

4 个答案:

答案 0 :(得分:4)

正如janos所说,没有内置设施可以做到这一点。您可以使用他建议的包装器。你也是,如果你愿意忍受一些“bleah”,请使用递归将其推送到makefile中。它可能看起来像这样:或许:

ifdef RECURSING

    ... normal makefile goes here ...

else

.DEFAULT all:
        @$(MAKE) RECURSING=true $@ ; r=$$? ; \
         <extra shell command here>; \
         exit $$r

endif

答案 1 :(得分:3)

我看到的唯一解决方案是创建一个包装器脚本,只需将所有参数传递给make,然后运行所需的自定义操作:

#!/bin/sh
make $* && ./custom_script.sh

答案 2 :(得分:2)

您可以使用两个makefile,其中一个调用另一个。例如

wrapper.mk:

foo bar:
        make -f other.mk $@
        @echo finished
.PHONY: foo bar

other.mk:

foo bar:
        @echo Building $@

然后运行“make -f wrapper.mk foo”,wrapper.mk运行other.mk来构建foo。 .PHONY目标意味着无论文件是否存在,目标都将被传递给other.mk以供每次考虑。

这需要在wrapper.mk中列出所有目标 - 可能有使用默认规则或匹配任何规则的方法。

答案 3 :(得分:0)

@Gavin Smith@MadScientist的答案与其他这些问题结合在一起:

  1. How to pass argument to Makefile from command line?
  2. Makefile match any target / task
  3. How to get the invoking target of makefile?
  4. Suppress "nothing to be done for 'all' "
  5. Makefile: declare all targets PHONY
  6. Makefile set global variable in target body

我建立了这个:

Makefile

ECHOCMD:=/bin/echo -e
SHELL := /bin/bash

define DEFAULTTARGET :=
    printf 'Calling makerules.mk "%s"\n\n' "${MAKECMDGOALS}"
    make -f makerules.mk ${MAKECMDGOALS}

    printf '\n'
    printf 'Running something after all rules finished\n'
endef

%:
    @:
#   printf 'IS_MAKEFILE_RUNNING_TARGETS="%s"\n' "${IS_MAKEFILE_RUNNING_TARGETS}"

    $(if ${IS_MAKEFILE_RUNNING_TARGETS},,${DEFAULTTARGET})
    $(eval IS_MAKEFILE_RUNNING_TARGETS=1)

all:
    @:
#   printf 'IS_MAKEFILE_RUNNING_TARGETS="%s"\n' "${IS_MAKEFILE_RUNNING_TARGETS}"

    $(if ${IS_MAKEFILE_RUNNING_TARGETS},,${DEFAULTTARGET})
    $(eval IS_MAKEFILE_RUNNING_TARGETS=1)

makerules.mk

all:
    printf 'Calling my all rule\n'

foo:
    printf 'Calling my foo rule\n'

bar:
    printf 'Calling my bar rule\n'

xyzzy:
    printf 'Calling my xyzzy rule\n'

用法示例:

  1. make

    printf 'Calling makerules.mk "%s"\n\n' ""
    Calling makerules.mk ""
    
    make -f makerules.mk
    make[1]: Entering directory '/cygdrive/d/User/Downloads'
    printf 'Calling my all rule\n'
    Calling my all rule
    make[1]: Leaving directory '/cygdrive/d/User/Downloads'
    printf '\n'
    
    printf 'Running something after all rules finished\n'
    Running something after all rules finished
    
  2. make all

    printf 'Calling makerules.mk "%s"\n\n' "all"
    Calling makerules.mk "all"
    
    make -f makerules.mk all
    make[1]: Entering directory '/cygdrive/d/User/Downloads'
    printf 'Calling my all rule\n'
    Calling my all rule
    make[1]: Leaving directory '/cygdrive/d/User/Downloads'
    printf '\n'
    
    printf 'Running something after all rules finished\n'
    Running something after all rules finished
    
  3. make all foo

    printf 'Calling makerules.mk "%s"\n\n' "all foo"
    Calling makerules.mk "all foo"
    
    make -f makerules.mk all foo
    make[1]: Entering directory '/cygdrive/d/User/Downloads'
    printf 'Calling my all rule\n'
    Calling my all rule
    printf 'Calling my foo rule\n'
    Calling my foo rule
    make[1]: Leaving directory '/cygdrive/d/User/Downloads'
    printf '\n'
    
    printf 'Running something after all rules finished\n'
    Running something after all rules finished
    
  4. make all foo bar

    printf 'Calling makerules.mk "%s"\n\n' "all foo bar"
    Calling makerules.mk "all foo bar"
    
    make -f makerules.mk all foo bar
    make[1]: Entering directory '/cygdrive/d/User/Downloads'
    printf 'Calling my all rule\n'
    Calling my all rule
    printf 'Calling my foo rule\n'
    Calling my foo rule
    printf 'Calling my bar rule\n'
    Calling my bar rule
    make[1]: Leaving directory '/cygdrive/d/User/Downloads'
    printf '\n'
    
    printf 'Running something after all rules finished\n'
    Running something after all rules finished
    
  5. make all foo bar xyzzy

    printf 'Calling makerules.mk "%s"\n\n' "all foo bar xyzzy"
    Calling makerules.mk "all foo bar xyzzy"
    
    make -f makerules.mk all foo bar xyzzy
    make[1]: Entering directory '/cygdrive/d/User/Downloads'
    printf 'Calling my all rule\n'
    Calling my all rule
    printf 'Calling my foo rule\n'
    Calling my foo rule
    printf 'Calling my bar rule\n'
    Calling my bar rule
    printf 'Calling my xyzzy rule\n'
    Calling my xyzzy rule
    make[1]: Leaving directory '/cygdrive/d/User/Downloads'
    printf '\n'
    
    printf 'Running something after all rules finished\n'
    Running something after all rules finished
    

相关问题:

  1. Stop executing makefile
  2. Force exit from a Makefile target without raising an error
  3. Suppress make rule error output
  4. Make: how to continue after a command fails?
  5. https://unix.stackexchange.com/questions/460606/make-how-to-suppress-make-error-messages-without-suppressing-other-output
  6. makefile use variable defined in target
  7. How do I get a makefile function to stop the current target?
  8. Can I make a makefile abort outside of a rule?
  9. Remove target from MAKECMDGOALS?
  10. How to detect if the makefile **`--silent`** / **`--quiet`** command line option was set?

更新

与上面相同,但是现在您将所有内容都放在一个Makefile中:

  1. Getting the name of the makefile from the makefile

Makefile

ECHOCMD:=/bin/echo -e
SHELL := /bin/bash


ifeq (${IS_MAKEFILE_RUNNING_TARGETS},)

MAKEFILE_JUSTNAME := $(firstword ${MAKEFILE_LIST})

define DEFAULTTARGET :=
    printf 'Calling "%s" "%s"\n\n' "${MAKEFILE_JUSTNAME}" "${MAKECMDGOALS}"
    make -f ${MAKEFILE_JUSTNAME} ${MAKECMDGOALS}

    printf '\n'
    printf 'Running something after all rules finished\n'
endef

%:
    @:
#   printf 'IS_MAKEFILE_RUNNING_TARGETS="%s"\n' "${IS_MAKEFILE_RUNNING_TARGETS}"

    $(if ${IS_MAKEFILE_RUNNING_TARGETS},,${DEFAULTTARGET})
    $(eval export IS_MAKEFILE_RUNNING_TARGETS=1)

all:
    @:
#   printf 'IS_MAKEFILE_RUNNING_TARGETS="%s"\n' "${IS_MAKEFILE_RUNNING_TARGETS}"

    $(if ${IS_MAKEFILE_RUNNING_TARGETS},,${DEFAULTTARGET})
    $(eval export IS_MAKEFILE_RUNNING_TARGETS=1)


else

all:
    printf 'Calling my all rule\n'

foo:
    printf 'Calling my foo rule\n'

bar:
    printf 'Calling my bar rule\n'

xyzzy:
    printf 'Calling my xyzzy rule\n'


endif