NickSoft
NickSoft

Reputation: 3335

GNU Makefile dependency in multi-job make

I have a c++ project under linux. I'm using GNU make and GCC

I have following rules:

all: ... 
version:
config:
  rm -f config.h
  @$(MAKE) --no-print-directory config.h
config.h:
 # ..... create the file config.h here

make version increases build number. 1.1-123, then 1.2-124 ... etc. The version is written in config.h file and config.h is included in all files in the project.

Now the idea is config.h to be rebuild in one of these cases: - when releasing a version of the program (rather than just developing/testing) - when it does not exists

so I do not want to make this dependancy:

all: config
config: version

because then config file will be rebuild on every make and every single file will be recompiled, not only changed files. So I want to not re-build config file while developing, but only if I do make release_version Now. Lets say that rule is:

release_version: config version all

The problem is that when I do make release_version -j 3 it'll make all the 3 targets (config, version, all) at the same time which means that version might not be ready for creation of config.h, then config.h might not be ready for all. So I must make this dependency:

release_version: all all: config config: version

BUT ONLY when make release_version is executed. if make all is executed I don't want to have these dependencies.

Maybe I need something like:

release_version: version_release config_release all_release

all_release: config config_release: config version_release: version

Upvotes: 0

Views: 1434

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126253

With GNU-make you can use an order-only prerequisite to force rules to be run in a particular order withou forcing them to run if they aren't needed by something else:

all: ...other targets... | config
        ...actions...

release_version: config version all

Now if you do a make all it will just rebuild the other targets before the |. If config is needed for some other reason, it will wait for it to be done before running ...actions....

This may not be enough, as those other targets may run before config. If you need them to wait until after config, you need to add | config to their prerequisites as well.

Upvotes: 0

MadScientist
MadScientist

Reputation: 100876

Your examples are a bit haphazard. It would be good if you re-read what you have and clarified it. What does the version target do? What is the relationship between version and config? What is the relationship between this release_version which you don't show anywhere, and config and version?

If I understand correctly you want to have the all rule that will build the code using the existing version of config.h (creating it if it doesn't exist), and the release_version rule that will update config.h, then build the code as if it were all. I'm not sure what version and config do.

You can do it like this, unless I'm missing something:

all: ...

release_version:
        @rm -f config.h
        @$(MAKE) config.h
        @$(MAKE) all

config.h:
        ...create config.h...

.PHONY: all release_version

There are lots of other options as well.

Upvotes: 1

Related Questions