Next: , Previous: Execution Architecture, Up: Amake Features

13.6 Implementation

The features of amake are implemented by changing make in several places:

  1. As the processing of a target begins, the 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.
  2. If a target update is not triggered due to different commands, the 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.
  3. Just before updating a target, if the target cache is enabled, the access_cache function searches the cache for a suitable target. If one is found, it is retrieved and the update is complete.
  4. As the updating of a target begins, The 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.
  5. Before the execution of a command in the sequence of commands that update a target, the 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.
  6. After the execution of the last command to update a target, the 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.