The features of amake
are implemented by changing
make
in several places:
access_commands
function writes a shell script
containing commands-executed dependencies to a file. The
script can be executed to update the target. It contains the
sequence of commands from the target's makefile rule. It
also contains a sequence of environment-variable assignments
(or unset
commands) to provide a suitable execution
environment. The file's name is the target's name, with
.cmd
appended. A .cmd
file is not created if
it already exists with the same content. If the content of
the new .cmd
file differs from the content of the
existing .cmd
file, and the ACCESS_ANYCMD
makefile variable is not set, the target is updated.
access_mustmake
function determines
whether the target must be updated due to a dependency's
checksum or last-modification-time, using exact
equality. The relevant variables are ACCESS_CHKSUM
and ACCESS_LMTIME
. Otherwise, the usual make
older-than/newer-than relative comparison is used.
access_cache
function searches the cache
for a suitable target. If one is found, it is retrieved and
the update is complete.
access_open
function creates an anonymous pipe and a pipe-arbitrating
semaphore for communication with a script named
amake-collect
. It then calls fork
and
exec
to execute the script. amake-collect
is
described in Amake-Collect, but its purpose is to
create the target's .dep
and .sib
files.
access_child
function sets two environment variables, to influence the
command's execution. The first is LD_PRELOAD
, so the
libaccess
wrappers are executed. The second variable
is set to a sequence of pipe-descriptor/semaphore-identifier
pairs. This allows a wrapper to write programs-executed and
files-accessed dependencies to one or more instances of
amake-collect
, through that many pipes. Recursive
make execution and parallel building require multiple
processes to write to the same pipe, even though there is
exactly one reader process for a particular pipe. SVR4
semaphores allow writer processes to synchronize pipe
access.
access_close
function closes the last open pipe
descriptor, allowing amake-collect
to detect an
end-of-file condition on its pipe. It also removes the
pipe's semaphore and waits for amake-collect
to
exit. Finally, if the target cache is enabled, the updated
target is put in the cache.