In a perfect world the answer would be: always 🙂 Now in this perfect world everything would be so fast that linking (or any extra step) would never matter.
Is linking slow ? it’s an extra step, so it takes extra time – but that extra step can also save time later…
The only time when you should avoid linking is when doing builds on the simulator. In that case MonoTouch will optimize the process – i.e. it will symlink (instead of copy) the assemblies and use a pre-generated, native launcher application (instead of invoking gcc to create a custom one). This fast-path is made to allow you to iterate hack-build-debug cycles rapidly – even if it differs, quite a bit, from the final device builds (another major difference is using the JIT, instead of AOT, on the simulator).
However when you’re building for devices linking can speed-up your builds – by far more than the time invested by the linker. That’s because AOT-ing all assemblies takes quite some time so reducing the size (and perhaps number) of your assemblies, by linking them, generally results in faster AOT-ing, hence faster build times. Also smaller binaries will upload faster to your device(s).
So you should, for devices, always use “Link all assemblies“. In fact I would be grateful if people could try this on their solutions and report any issue they encounter. Why ? There are a few cases, mostly reflection-related (e.g. xml serialization), where you’ll need to:
- add [Preserve] attributes inside your code to ensure the linker won’t remove code that’s actually needed; or
- switch to “Link SDK assemblies only” so the linker won’t process any code from your solution (that’s a bit drastic since you’ll lose a lot of the linker advantages); or
- add one (or a few) –linkskip argument(s), e.g. –linkskip=MySerializationAssembly, to your main project settings.
Now I’d like to make the linker smarter about (some of) the existing limitations so your real life experience would be very helpful to me and, eventually, to everyone.