Mostly experience. The gcc compiler man page says for -l library:
It makes a difference where in the command you write this option; the linker
searches and processes libraries and object files in the order they are
specified. Thus, foo.o -lz bar.o searches library z after file foo.o but
before bar.o. If bar.o refers to functions in z, those functions may not be
Most compilers (gcc, icc, nvcc, ...) follow the same rule. Determining the correct order is sometimes a non-intuitive, trial-and-error process. In this case, Magma uses Lapack, blas, and cublas, so Magma has to be first. Lapack uses blas, so blas has to be after Lapack. At the moment, Magma and Magmablas have a circular dependency, so one may need to be repeated.