The short answer is that you've got the relationship the wrong way around: csc.exe depends on Roslyn, not vice versa.
The long answer requires a short history lesson:
Originally in the .NET framework, csc.exe was a self-contained binary responsible for compiling C# source code to IL. But it was opaque and its command-line interface limited what could be achieved by invoking it.
Microsoft introduced the System.CodeDom namespace and classes as a way for their own tools to generate code (e.g. the Windows Forms designer in Visual Studio), but pretty much everyone started using it because it was miles better than csc.exe. However given what it was created for, CodeDOM suffers from numerous limitations and edge cases that make it less than ideal for certain non-compilation tasks - and at the end of the day it simply invokes csc.exe to produce compiled code.
Ultimately this approach was unable to satisfy Microsoft's own need for better static analysis of code in their flagship IDE. To achieve this requirement a new API was required, and Microsoft realised that if they designed it to be accessible to ordinary developers, they could kill two birds with one stone. Thus the Roslyn project was born: a complete set of independent and complete APIs that could be used by anyone, thereby fulfilling the needs of both developers and Visual Studio.
The ultimate result is that all the logic that had lived in csc.exe migrated into Roslyn's APIs, and the way those APIs are invoked determines what C# language version will be used. Passing -langversion to csc.exe or /p:TargetFrameworkVersion to msbuild.exe ultimately ends up setting the Roslyn language version for compilation, but there is nothing stopping you from creating your own Roslyn compilation instance to achieve the same.
Reference: https://stackoverflow.com/a/7854697/70345