rishi_v
rishi_v

Reputation: 1

How to tell make to track the output of a python script and only run the script if the input file was updated

I know that in the context of creating a c/c++ executable, make automatically takes care of creating the executable only if the dependency files have been updated.

I have been wondering if there is a way to specify the input and output files of a python script to make, such that make can do its magic depending on the status of the input file.

Makefile entry:

update_info:
    python update_info.py info.xml

# Output file : info.hpp

Basically I would like make to check the version of info.xml. If it has not been updated, I don't want make to run the update_info.py script.

Just trying to find out if there is an existing way to do it. I can live with it, if this cannot be done.

Thanks.

Upvotes: 0

Views: 341

Answers (2)

rishi_v
rishi_v

Reputation: 1

Figured out a way to do this for existing files which are updated by a script:

The solution is to create a new file by copying the make target file.

update_info: target/info.hpp

target/info.hpp: info.xml
    python update_info.xml info.xml
    cp info.hpp target/info.hpp

This way, the current folder can contain a previous version of info.hpp. Make tracks the info.hpp file in target folder and will only run the script if the input file info.xml has changed.

The side effect of this is that the info.hpp in the current folder is updated only if info.xml has changed. Which is what was needed.

If you are using git, you may need to add the target/info.hpp file to the ignore list.

This method is helpful in using make to track those files in a repository with an existing file which is updated by a script.

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 181219

I have been wondering if there is a way to specify the input and output files of a python script to make, such that make can do its magic depending on the status of the input file.

Of course. At its core, make is a very simple and general system. It defines a format for expressing the prerequisites for building various targets, and for expressing machine-actionable instructions for actually building those targets from their designated prerequisites. Given that information, make figures out which recipes, if any, to execute to build a requested target or to bring it up to date with respect to its direct and indirect dependencies.

Make knows nothing about the nature of the targets and prerequisites other than that they are timestamped files (or so it assumes). Make having been designed with building software in mind, it does come with some built-in rules aimed at building programs from source code written in a few select languages, but that's a convenience feature, not a limitation.

If you want to provide for building a file named info.hpp based on another file named info.xml then info.hpp is the target and info.xml is the (a) prerequisite. A rule along these lines would then be appropriate:

info.hpp: info.xml
    python update_info.py info.xml

Generally speaking, though, it is best to avoid repeating target and prerequisite names in the recipe wherever possible. Instead, use the appropriate automatic make variables, such as $^, which represents the distinct elements of the prerequisite list:

info.hpp: info.xml
    python update_info.py $^

Under some circumstances, you might want the Python script to be a prerequisite, too, since changes to the script could cause it to produce meaningfully different output from the same input.

Upvotes: 0

Related Questions