A large and somewhat miscellaneous collection of utility functions used
throughout the rest of the Cabal lib and in other tools that use the Cabal
lib like cabal-install. It has a very simple set of logging actions. It
has low level functions for running programs, a bunch of wrappers for
various directory and file functions that do extra logging.

Like the unix xargs program. Useful for when we've got very long command
lines that might overflow an OS limit on command line length and so you
need to invoke a command multiple times to get all the args in.

This would copy "src/Foo.hs" to "dist/src/src/Foo.hs" and
copy "dist/build/src/Bar.hs" to "dist/src/src/Bar.hs".

This operation is not atomic. Any IO failure during the copy (including any
missing source files) leaves the target in an unknown state so it is best to
use it with a freshly created directory so that it can be simply deleted if
anything goes wrong.

installing files

Install an ordinary file. This is like a file copy but the permissions
are set appropriately for an installed file. On Unix it is "-rw-r--r--"
while on Windows it uses the default permissions for the target directory.

Install an executable file. This is like a file copy but the permissions
are set appropriately for an installed file. On Unix it is "-rwxr-xr-x"
while on Windows it uses the default permissions for the target directory.

Find a file by looking in a search path with one of a list of possible
file extensions. The file base name should be given and it will be tried
with each of the extensions in each element of the search path.

The order places files in sub-directories after all the files in their
parent directories. The list is generated lazily so is not well defined if
the source directory structure changes before the list is used.

modification time

Compare the modification times of two files to see if the first is newer
than the second. The first file must exist but the second need not.
The expected use case is when the second file is generated using the first.
In this use case, if the result is True then the second file is out of date.