首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当订单重要时,如何使一个目标调用另一个目标?

当订单重要时,如何使一个目标调用另一个目标?
EN

Stack Overflow用户
提问于 2016-05-13 00:03:50
回答 2查看 209关注 0票数 0

我有两个目标几乎相同:

代码语言:javascript
复制
# install node modules from package.json and bring npm-shrinkwrap.json up to date
npm-install:
ifndef SHRINKWRAP_BIN
    $(error `npm-shrinkwrap` not found. Please run `sudo npm install -g npm-shrinkwrap`)
endif
    $(NPM_BIN) install --no-shrinkwrap --loglevel=error --no-optional
    $(NPM_BIN) prune --no-shrinkwrap --loglevel=error
    $(NPM_BIN) dedupe --no-shrinkwrap --loglevel=error
    npm-shrinkwrap --dev
    touch $(NPM_TIMESTAMP)

# update npm dependencies to their latest version given the semver constraints and re-write npm-shrinkwrap file
npm-update:
ifndef SHRINKWRAP_BIN
    $(error `npm-shrinkwrap` not found. Please run `sudo npm install -g npm-shrinkwrap`)
endif
    $(NPM_BIN) update --save-dev --loglevel=error --no-optional
    $(NPM_BIN) prune --no-shrinkwrap --loglevel=error
    $(NPM_BIN) dedupe --no-shrinkwrap --loglevel=error
    npm-shrinkwrap --dev
    touch $(NPM_TIMESTAMP)

有什么办法,我可以消除一些重复,让他们两个调用另一个目标?我不能仅仅向它们添加一个包含公共部分的先决条件,因为先决条件在命令之前运行,安装/更新位必须先运行(在prune/dedupe/收缩包装之前)。

EN

回答 2

Stack Overflow用户

发布于 2016-05-13 02:12:50

假设我正确地阅读了这一点,并且两者之间的区别只是npm-install中的单词installnpm-update中的update,那么这里的解决方案就是在您正在运行的命令中使用目标(或其中的一部分)。

就像这样:

代码语言:javascript
复制
# install node modules from package.json and bring npm-shrinkwrap.json up to date
npm-install npm-update:
ifndef SHRINKWRAP_BIN
    $(error `npm-shrinkwrap` not found. Please run `sudo npm install -g npm-shrinkwrap`)
endif
    $(NPM_BIN) $(subst npm-,,$@) --no-shrinkwrap --loglevel=error --no-optional
    $(NPM_BIN) prune --no-shrinkwrap --loglevel=error
    $(NPM_BIN) dedupe --no-shrinkwrap --loglevel=error
    npm-shrinkwrap --dev
    touch $(NPM_TIMESTAMP)

您也可以使用$(word 2,$(subst -, ,$@))$(patsubst npm-%,%,$@),或者由于上面没有将--no-shrinkwrap转换为--save-dev,您可以使用类似的方法(或者将上面的$@用法与类似于此的arg变量组合起来):

代码语言:javascript
复制
npm-install: command := install
npm-install: arg := --no-shrinkwrap
npm-update: command :=  update
npm-update: arg :=--save-dev

npm-install npm-update:
        ....
        $(NPM_BIN) $(command) $(arg) --loglevel=error --no-optional
        ....
票数 3
EN

Stack Overflow用户

发布于 2016-05-13 01:03:19

我对此有几个想法。第一种方法是只在Makefile中使用文本处理来显式地减少重复。定义多行宏,然后调用它。

代码语言:javascript
复制
define NPM_COMMON_STEPS
$(NPM_BIN) prune ...
$(NPM_BIN) dedupe ...
...
endef

因为这没有参数,所以我们不必使用$(call ...)操作符。简单地说,在食谱中我们称之为:

代码语言:javascript
复制
$(NPM_COMMON_STEPS)

还有其他的方法。您可以让虚拟的先决条件目标处理所有的逻辑,并根据谁在“调用”来切换它的某些部分。我们怎么知道呢?为什么,通过特定的目标变量!

这可以通过完整的Makefile来说明:

代码语言:javascript
复制
.PHONY: all common-target a-target b-target
all: a-target b-target

common-target:
        $(if $(CALLED_FOR_A), echo called for a-target)
        $(if $(CALLED_FOR_B), echo called for b-target)
        echo common recipe

a-target: CALLED_FOR_A := y
a-target: common-target

b-target: CALLED_FOR_B := y
b-target: common-target

测试:

代码语言:javascript
复制
$ make
echo called for a-target
called for a-target
echo common recipe
common recipe
$ make a-target
echo called for a-target
called for a-target
echo common recipe
common recipe
$ make b-target
echo called for b-target
called for b-target
echo common recipe
common recipe

正如您所看到的,这里有一个缺点,如果我们更新目标all,那么GNU只执行一次共享公共规则。当代表a-target运行该规则时,它被认为是更新的,而不是为b-target运行的。

如果我们没有在相同的运行中更新两个目标,这并不重要,但同样,这是一个潜在的障碍:

代码语言:javascript
复制
$ make a-target b-target
echo called for a-target
called for a-target
echo common recipe
common recipe
make: Nothing to be done for `b-target'.

因此,在使用这种伎俩之前,我会三思而后行。如果您永远不会在同一个调用中执行npm-updatenpm-install,那么可以使用它。

以下是文本替换解决方案的完整示例:

代码语言:javascript
复制
.PHONY: all a-target b-target
all: a-target b-target

define COMMON
echo common recipe
endef

define COMMON_WITH_ARG
echo common recipe with arg 1 == $(1)
endef

a-target:
        echo a-target
        $(COMMON)
        $(call COMMON_WITH_ARG,a)
        echo a-done

b-target:
        echo b-target
        $(COMMON)
        $(call COMMON_WITH_ARG,b)
        echo b-done

运行:

代码语言:javascript
复制
$ make
echo a-target
a-target
echo common recipe
common recipe
echo common recipe with arg 1 == a
common recipe with arg 1 == a
echo a-done
a-done
echo b-target
b-target
echo common recipe
common recipe
echo common recipe with arg 1 == b
common recipe with arg 1 == b
echo b-done
b-done
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37199299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档