In fact it generate single optimized exe files, but it does in multiple steps for multiple reasons, one of them is separation of concerns, but also, one of the main reasons is speed. The linker is linking (normally statically linking) different already build cached libraries, including the runtime. Without the linking ability, you would need to compile everything every time. Not only that, the linker has other responsibilities, like building some metadata that goes into the binary, for example the dynamic dispatch table.
In fact it generate single optimized exe files, but it does in multiple steps for multiple reasons, one of them is separation of concerns, but also, one of the main reasons is speed. The linker is linking (normally statically linking) different already build cached libraries, including the runtime. Without the linking ability, you would need to compile everything every time. Not only that, the linker has other responsibilities, like building some metadata that goes into the binary, for example the dynamic dispatch table.