2016-06-07 46 views
0

这里是我的Makefile指定的makefile命令目标

gitignore-create: 
    touch .gitignore ;\ 
    echo 'node_modules' >> .gitignore ;\ 
    echo 'npm' >> .gitignore ;\ 
    echo '.DS_Store' >> .gitignore ;\ 

如果我跑make gitignore-create我得到gitignore文件的当前目录。

我正在寻找一种方法来从同一目录运行此makefile命令,但目标被指定为另一个。尽管如此,我不想将cd添加到命令本身。

我想是这样的:

# make wrap package=my-package command=gitignore-create 
wrap: 
    pushd packages/$(package)/ && make -C ${CURDIR} $(command) && popd 

而且只创建实际当前目录下的文件。

回答

2

有很多不对的:

wrap: 
     pushd packages/$(package)/ && make -C ${CURDIR} $(command) && popd 

的第一件事情是你应该永远递归调用make规则时使用static命令make总是使用变量$(MAKE)(或者如果您愿意,${MAKE}:它们是相同的)。

其次,你不能使用pushdpopd(至少不可移植性),因为这些都是bash的命令,但要始终运行/bin/sh作为它的外壳(除非你通过设置SHELL的Makefile变量改变它),并在许多系统上,/bin/sh而不是 bash。第三,您不需要那么做,因为在UNIX/Linux中,与所有正确思考的操作系统一样,当前目录是当前进程(其环境的一部分)的属性,并且改变当前进程目录不会更改父进程的当前目录。而且,makefile中的每个配方行都是一个全新的进程(运行一个shell)。因此,您可以直接在任何配方行中使用cd,只要该配方行完成并且shell退出,环境(包括当前目录)的所有更改都将消失:您不必显式撤消它们。

所以你可以写上面的规则等效为:

wrap: 
     cd packages/$(package)/ && $(MAKE) -C ${CURDIR} $(command) 

然而,这终究不会因为给做的原因时,-C选项做任何事情做出改变它的工作目录到您提供的价值。所以这个配方说:“首先将目录改为packages/$(package),然后运行make并告诉它它在启动任何命令之前应该做的第一件事是将目录更改回原始目录”。很明显,这与仅运行make而不改变目录完全相同。

你的解释并不完全清楚,但我觉得你想要做是这样的:

# this variable assignment must come before any include statements 
myMakefile := $(abspath $(lastword $(MAKEFILE_LIST))) 
    ... 
wrap: 
     cd packages/$(package)/ && $(MAKE) -f $(myMakefile) $(command) 

最先记住的路径添加到当前makefile文件,然后创建一个食谱目录改变成packages/$(package)然后运行make让它解析当前的makefile(但不能更改目录,不要使用-C!)并运行该命令。

+0

这是给我的一些错误 'CD包/雷吉/ && /Applications/Xcode.app/Contents/Developer/usr/bin/make -f Makefile文件gitignore-create' '使[1]:Makefile文件:没有这样的文件或目录' make [1]:***没有规则使目标'Makefile'。停止。 make:*** [wrap]错误2 – ThomasReggi

+0

这是我的文件。我基本上想要一种方式来存在底部食谱。 https://gist.github.com/reggi/e180f3a3b8beaabd3c37a15cb6c6c628, – ThomasReggi

+0

可以通过检查'package'变量是否存在然后cd'ing或者通过一个包装方法让我在那里增加它。 – ThomasReggi