Often the automatic builds are controlled by the
make tools using the
rules defined in so named
make is very nice since it
allow a smooth control of the build with a direct link with dependencies.
Therefore only what is need to be build is built. A rule is executed only when the
dependencies are younger than the target for that rule.
To automate the builds regularly the construction might be run regularly via
cron jobs. However, if the time in between the
make runs is
smaller than the time required to perform a particular task, this task will be
run several time and filled the resources of the computer. To prevent it we can
setup a protection on the
Makefile to prevent it to be executed several
times at a given time.
To prevent the multiple execution of the
Makefile we will use a so called lock
file. When the
Makefile is execute it will create a file with a particular name.
This is our lock file. When it finish to execute, it just delete this file. In case
Makefile is run a second time in parallel, it will see that the lock file
exist and stop the processing.
Setting up lock files inside a Makefile
To determine the existence of the file we will use the unix command
that will return the name of the lock file if it exist else nothing. We will
catch it in a make variable:
LOCKFILEEXIST = $(shell ls $(LOCKFILE) 2> /dev/null)
Then we test if this variable is empty or not. In case it is not empty, we exit with an error:
ifneq ($(LOCKFILEEXIST), ) $(error "already running") endif
In case we the lock file does not exist we continue the process and set the lock file.
$(shell touch $(LOCKFILE))
Then follow the rest of the
Makefile like usual. We just need to remove the lock
file at the end of the rpocessing. For this we add it at the end of the all
rules that is the main run.
all: @echo "processed" $(shell rm -f $(LOCKFILE))
This command should be add to all rules that terminate the run, otherwise future
run might be blocked even no
Makefile is running
The final test
# Definition of the lockfile LOCKFILE = "test.lock" # Search for the lock file LOCKFILEEXIST = $(shell ls $(LOCKFILE) 2> /dev/null) # if the lock file exist exit ifneq ($(LOCKFILEEXIST), ) $(error "already running") endif # Create the lock file $(shell touch $(LOCKFILE)) # process and remove the lock file all: @echo "processed" $(shell rm -f $(LOCKFILE))
Without any lock file the execution is done and like this several time:
$ make all processed $ make all processed
When a lock file exist the Makefile stop with an error:
$ touch test.lock $ make all Makefile:5: *** "already running". Stop.