The features of
amake are implemented by changing
make in several places:
access_commandsfunction 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
unsetcommands) to provide a suitable execution environment. The file's name is the target's name, with
.cmdfile is not created if it already exists with the same content. If the content of the new
.cmdfile differs from the content of the existing
.cmdfile, and the
ACCESS_ANYCMDmakefile variable is not set, the target is updated.
access_mustmakefunction 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_LMTIME. Otherwise, the usual
makeolder-than/newer-than relative comparison is used.
access_cachefunction searches the cache for a suitable target. If one is found, it is retrieved and the update is complete.
access_openfunction creates an anonymous pipe and a pipe-arbitrating semaphore for communication with a script named
amake-collect. It then calls
execto execute the script.
amake-collectis described in Amake-Collect, but its purpose is to create the target's
access_childfunction sets two environment variables, to influence the command's execution. The first is
LD_PRELOAD, so the
libaccesswrappers 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_closefunction closes the last open pipe descriptor, allowing
amake-collectto detect an end-of-file condition on its pipe. It also removes the pipe's semaphore and waits for
amake-collectto exit. Finally, if the target cache is enabled, the updated target is put in the cache.