As for the standard libraries, as a rule you want to
avoid linking the standard libraries to the kernel, or at least the versions of them that are used on your development system, as they are written to run on that development operating system, not yours. I'm guessing that what you meant is, why do you have to link the versions of the libraries that you wrote and compiled for your own OS when you don't need to do that when developing for the system you are running on. Well, the answer to this is three-fold: first, you
do need to link the standard libraries in to your executable programs when you compile them for the OS you are developing them on, its just being done for you by the compiler scripts; and second, you need to do it explicitly (rather than just as part of the compiler configuration) because you didn't tell the compiler which libraries to use when you configured your cross-compiler, or more likely, you never did configure one; and third, because even if you had configured your cross-compiler correctly, you often need finer-grained control than the existing build scripts give you.
I am assuming you are using GCC as your compiler suite, though the basic issues apply to any compiler you might be using.
When you install the GCC compiler package - which is actually several programs, including the C and C++ compilers (and possibly several others), the C/C++ preprocessor, various utilities, and most important of all, a set of standard scripts for driving the compilation process - by default it gets configured by the installer to produce executable programs that the local operating system can use. Usually, this is exactly what you want it to do, when writing everyday application programs, as it means you don't need to reinvent the wheel every time you write a source file, but for OS cross-development, it will assume a lot of things that you won't want it to, including which set of standard libraries to use. Since many parts of the standard libraries are basically simplified wrappers around system calls, those parts of the library need to be specific to the operating system, so you need a separate copy of the compiled specifically f. or the operating system you are targeting. To develop for your own OS using the existing GCC configuration, you end up having to explicitly instruct it not to use the local libraries, and use your cross-development libraries instead.
Needless to say, this becomes a serious issue, as it becomes harder and harder to keep track of this even with
Makefiles and
Linker Scripts, and the chances of making a mistake rise over time. To avoid this, we usually recommend setting up a
GCC Cross-Compiler configured to target your OS specifically, and using that instead of the GCC that you have for local development. While it means extra work up front, it usually avoids a lot of more work over time.
However, even with the cross-compiler, when you compile from the shell you are often using the default compilation scripts for that compiler configuration, which may not be right for all the things you need to do with the compiler. This is where the aforementioned Makefiles and linker scripts come in. The make utility is a specialized interpreter for automatic build scripting, with special support for automatically checking if a given source file needs to be recompiled, among other things. While there are many similar tools around, make is the standard one for Unix and Linux, and most C and C++ compilers for other operating systems have a version of it as well.
The linker scripting facility for ld allows you to specify several key aspects of the linking process on a file-by-file or even link-by-link basis. In kernel development, this can be needed for a number of reasons, such as when you are generating a kernel loader binary image.