简体   繁体   English

在特定目录中运行的可执行文件 Makefile

[英]Executable Makefile that runs in a specific directory

What I try to achieve :我试图实现的目标

  • making a makefile executable using a shebang使用 shebang 制作 makefile 可执行文件
  • making it switch to a certain directory beforehands, so it is callable from any where事先让它切换到某个目录,所以它可以从任何地方调用

What I have :我有什么

/docker/images/Makefile (with executable flag): /docker/images/Makefile(带有可执行标志):

#!/usr/bin/make -f

default: ...
...

I can do我可以

cd /docker/images
./Makefile

However, what I would like to be able to do :但是,我希望能够做的是

cd /somewhere/else
/docker/images/Makefile

What I tried :我试过的

man make states, that I can set a --directoy <dir> param. man make声明,我可以设置一个--directoy <dir>参数。
However, the shebang #!/usr/bin/make --directory=/docker/images -f , does not work:但是,shebang #!/usr/bin/make --directory=/docker/images -f不起作用:

$ cd /somewhere/else
$ /docker/images/Makefile
make: *** =/docker/images -f: Datei oder Verzeichnis nicht gefunden.  Schluss.

(File or dir not found) (找不到文件或目录)

Any guesses?有什么猜测吗?
I'm on Devuan ASCII with GNU Make 4.1我在使用 GNU Make 4.1 的 Devuan ASCII

I've seen the related thread which does not address my issue.我看到了相关的线程,它没有解决我的问题。

Sure you can.你当然可以。 Use /usr/bin/env with -S option, which is exactly meant for splitting parameters on the shebang line./usr/bin/env-S选项一起使用,这正是用于在 shebang 行上拆分参数的意思。

$ cat Makefile
#!/usr/bin/env -S make -C /docker/images -f
all:
        echo Foo

Output: Output:

$ /docker/images/Makefile
make: Entering directory '/docker/images'
echo Foo
Foo
make: Leaving directory '/docker/images'

When we put #!/usr/bin/make --directory=/docker/images -f当我们放#!/usr/bin/make --directory=/docker/images -f

and run /docker/images/Makefile并运行/docker/images/Makefile

It's equivalent to run:它相当于运行:

/usr/bin/make "--directory=/docker/images -f" /docker/images/Makefile

One solution is to delegate to second line:一种解决方案是委托给第二行:

#!/home/debian/bin/run_second_line
# /usr/bin/make --directory=/docker/images -f

default: ...
...

In /home/debian/bin/run_second_line:在 /home/debian/bin/run_second_line 中:

#!/bin/bash
get_second_line=$(awk 'NR == 2{print}' "$1")
exec bash -c "${get_second_line#?} $1"

Update:更新:

It should work with this shebang:它应该与这个 shebang 一起工作:

#!/usr/bin/perl -euse File::Basename;exec qq`make -C @{[dirname $ARGV[0]]} -f ` . $ARGV[0]

What about just:只是:

make -C /some/dir/where/there/is/a/makefile

Inspired from similar approaches, I found a solution:受类似方法的启发,我找到了一个解决方案:

My makefile now has the following head:我的 makefile 现在有以下头部:

#!/bin/bash

# the following block will be executed by bash, but not make
define BASH_CODE 2>/dev/null
make -C $(dirname $0) -f $(basename $0) $@
exit 0
endef

# the following lines will be interpreted by make, but not bash

# Makefile starts here #
volumes = $$HOME/docker/volumes

# headings created with https://www.askapache.com/online-tools/figlet-ascii/

default: talk

talk:
    @echo Dies ist ein Test
    pwd

...

With these lines in place I can now do the following:有了这些行,我现在可以执行以下操作:

  1. call make -C /path/to/makefile/调用make -C /path/to/makefile/
  2. call /path/to/makefile/Makefile调用/path/to/makefile/Makefile

Anybody with a better solution?有人有更好的解决方案吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM