The previous build system kept a forward-pointing single linked list of tasks
to execute: task X had a list of subsequent tasks to execute. If task X was
up-to-date, it was not created (and the next tasks were directly added to the
list of tasks to execute).
In this world it became complicated to merge output from tasks (for instance
if the output of task X and task Y should be a consumed by a single task
producing a single output, since the corresponding task would end up in both
X's and Y's list of subsequent tasks).
Example: creating a single framework from the aot-compiled output of multiple
assemblies.
So I've reversed the logic: now we keep track of the final output, and then
each task has a list of dependencies that must be built.
This makes it trivial to create merging tasks (for the previous example, there
could for instance be a CreateFrameworkTask, where its dependencies would be
all the corresponding AotTasks).
We also always create every task, and then each task decides when its executed
whether it should do anything or not. This makes it unnecessary to 'forward-
delete' files when creating tasks (say you have three tasks, A, B, C; B
depends on A, and C depends on B; if A's output isn't up-to-date, it has to
delete its own output if it exists, otherwise B would not detect that it would
have to re-execute, because at task *creation* time, B's input hadn't
changed).
Additionally make it based on async/await, since much of the work happens in
externel processes (and we don't need to spin up additional threads just to
run external processes). This makes us have less code run on background
threads, which makes any issues with thread-safety less likely.
The AOT-compilation occurs in the AOT-task now, and then we compile the result
using CompileTask.
This means that the error message in CompileTask was slightly incorrect, so
rectify it.
This makes dylibs automatically have the correct dylib id, which means no
fixups are required.
For instance: we'd build libpinvokes.armv7.dylib from libpinvokes.armv7.m,
which by default ends up with a dylib id of "libpinvokes.armv7.dylib". With
this fix no change is required, since we now build armv7/libpinvokes.dylib
from armv7/libpinvokes.m.
Compute the dependency map for assemblies earlier, and store the results.
In a later commit we'll need to know if a dependency map was successfully
computed when determining if a task is up-to-date or not.
Rework the code that copies assemblies and their related files to the app
bundle to take into account that we might be building to frameworks now.
Also strip the assemblies when they're copied (if they must be stripped),
which removes the need for custom logic to copy files related to stripped
assemblies.
Additionally change how we handle duplicated assemblies by checking for
duplication before copying them to the app bundle. This allows us to copy
assemblies to the root directory (not the .monotouch-[32|64] subdirectory) if
the 32-bit and 64-bit versions are identical, which also means we won't need
symlinks anymore.
Add support for finding assembly-related resources (debug files, config files,
satellite assemblies, aotdata files, etc) in multiple locations:
* The bundle's root directory.
* A pointer-size specific size directory (.monotouch-32|64)
* A framework's MonoBundle directory (and the framework may not be named after
the assembly, which means it's not necessarily possible to deduce the
framework's name at runtime).
* In a container bundle.
Some files may also have an arch-specific suffix.
Make the architecture a suffix instead of infix for aotdata filenames so that
it's easier to compute the filename from the assembly name without passing
printf-style format strings around.
Create a custom AssemblyCollection class that contains a dictionary with
assembly identity (name) -> Assembly mapping.
This also means that we can detect if we end up loading multiple assemblies
with the same identity, and show an error in that case (even if that case
should never happen since we cache assemblies based on the identity, it's nice
to have code that ensures it).