最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Makefile - sharing the output of a long running command in multiple recipes - Stack Overflow

programmeradmin3浏览0评论

I have a Makefile which has a target to create a python virtual environment

venv:
    python3 -m venv venv
    ... install stuff into venv ...

Now, I have several recipes which need to use the output of a command that can only be run when this virtual environment is active.

. venv/bin/activate && run_long_command

How can I set my Makefile up such that I can store the output this run_long_command in a variable as soon as venv target is completed, and make it available to any recipes that will need it?

Without this, I will have to run the long command as part of every recipe as the first thing it does and that's going to slow it down big time.

Another way is to make my users do make venv separately first so that I ensure that venv exists. Then I can do:

OUTPUT := $(shell . venv/bin/activate && run_long_command)

then I can use OUTPUT wherever I want.

But I don't want my users to have to do this, and I don't want my targets to run slow. Any tips?

I have a Makefile which has a target to create a python virtual environment

venv:
    python3 -m venv venv
    ... install stuff into venv ...

Now, I have several recipes which need to use the output of a command that can only be run when this virtual environment is active.

. venv/bin/activate && run_long_command

How can I set my Makefile up such that I can store the output this run_long_command in a variable as soon as venv target is completed, and make it available to any recipes that will need it?

Without this, I will have to run the long command as part of every recipe as the first thing it does and that's going to slow it down big time.

Another way is to make my users do make venv separately first so that I ensure that venv exists. Then I can do:

OUTPUT := $(shell . venv/bin/activate && run_long_command)

then I can use OUTPUT wherever I want.

But I don't want my users to have to do this, and I don't want my targets to run slow. Any tips?

Share Improve this question asked Mar 27 at 4:55 shikhanshushikhanshu 1,5482 gold badges17 silver badges35 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Make is not a shell and exchanging data between recipes with make variables is not very convenient, especially if you want to avoid recursive make invocations.

If, instead of storing the output of run_long_command in a variable, you can store it in a file - say run_long_command.out - and have the other recipes use the file instead of a variable, you could simply:

  • declare venv/bin/activate as a prerequisite of run_long_command.out,
  • declare run_long_command.out as a prerequisite of the other recipes that use it.

Example:

run_long_command.out: venv/bin/activate
    . $< && run_long_command > $@

other-target: run_long_command.out
    <use content of run_long_command.out>

venv/bin/activate:
    python3 -m venv venv
    ... install stuff into venv ...

When building other-target, if venv/bin/activate does not exist yet the virtual environment is built. Then, if run_long_command.out exists and is newer than venv/bin/activate, it is considered as up to date and not re-built. It is only if it does not exist, or venv/bin/activate has changed since its last build, that it is re-made.

发布评论

评论列表(0)

  1. 暂无评论