PieterV
PieterV

Reputation: 836

How to do integer arithmetic in Makefile prerequisites?

I have a file <n>.x and <n-1>.y and I want to create a dependency in my Makefile. Manually I can write each case as follows:

2.x : 1.y
3.x : 2.y
4.x : 3.y
...

Now I would like to be able to write this more generically:

%.x : <???>.y

Gnu Make doesn't seem to have integer arithmetic on its own and shell expansions ($$(( )), $(shell ) don't seem to work for prerequisites.

Is there a way do this in the Makefile itself or should I use an external script that can generate these dependencies and let the Makefile include them?

Edit: My specific case is dealing with files containing financial transactions. Each file (e.g. 2023.journal) represents transactions for a specific year and includes an opening statement (e.g. 2023_opening.journal), which is based on the closing statement of the year before that. This create a dependency between 2023_opening.journal and 2022.journal.

Upvotes: 0

Views: 83

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 29375

With GNU make:

.SECONDEXPANSION:
%.x: $$(shell expr $$* + 1).y

All rules after the .SECONDEXPANSION special target have their list of prerequisites (and only that) processed twice by make: a first time, as everything else, when make parses the Makefile, plus a second time when make needs to check the prerequisites of a target. Contrary to the first phase, during the second phase the automatic variables are defined.

So, after the first phase the rule becomes:

%.x: $(shell expr $* + 1).y

$* is the make automatic variable that expands as the stem in pattern rules. In your case it is the part that matches the %.

And then, when make needs the list of prerequisites for 1.x, the rule is processed again, $(shell expr $* + 1).y is expanded, and becomes (step by step):

  1. 1.x: $(shell expr 1 + 1).y # $* --> 1
  2. 1.x: 2.y # $(shell expr 1 + 1) --> 2

Upvotes: 1

Related Questions