Creating a C Library: Difference between revisions

m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (/* Corrected typo*)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(5 intermediate revisions by 3 users not shown)
Line 9:
Then you can simply build your C library source files using:
 
<sourcesyntaxhighlight lang="bash">
x86_64-myos-gcc -c strfoo.c -o strfoo.o
x86_64-myos-as x86_64/crt0.s -o x86_64/crt0.o
x86_64-myos-ar rcs libc.a strfoo.o x86_64/crt0.o
</syntaxhighlight>
</source>
 
Note that unlike the kernel, you don't need to add extra special options that disable standard include directories and libraries. After all, this is the C library meant for user-space. You don't need to add -I options to the compiler if you already have installed your libc and kernel headers into your sysroot. Otherwise, simply add the appropriate -I options to the above commands. It may be useful to use the same libc for both user-space and the kernel, in that case don't make the mistake of thinking that user-space-libc and kernel-libcs are the same thing. First of all many user-space things don't make sense (or even work) in the kernel. Secondly, a kernel-usable libc must be built differently than the user-space libc because it is <em>freestanding</em>. A kernel libc must have all the special options that a kernel binary is passed. For instance, don't forget to add -mno-red-zone on x86_64 to both your kernel and libc, or interrupts may corrupt the stack.
Line 20:
:''See also: [[Calling Global Constructors]]''
 
The first and most important thing to implement in a C library is the _start function, to which control is passed from your program loader. It'sIts task is to initialize and run the process. Normally this is done by initializing the C library (if needed), then calling the global constructors, and finally calling exit(main(argc, argv)). You can change the name of the default program entry point by adding ENTRY=_my_start_name in your OS-specific binutils emulparams script (binutils/ld/emulparams). You can change which start files are used by modifying gcc/gcc/config/myos.h in your OS-specific GCC. The macros STARTFILE_SPEC and ENDFILE_SPEC define the object files to use in the GCC spec language. See gcc/gcc/config/gnu-user.h for examples on how to use this. If you decide to use the conventional (GNU-like) names and semantics for these initialization files, the following information applies:
 
=== crt0.o ===
Line 125:
C library headers conventionally use include guards to prevent multiple declarations. It may be wise to use the same format as GNU's libc as some programs (and GCC fixincludes) may erroneously rely on these macros to detect whether a given header has been included. GNU libc's headers usually follow this simple scheme:
 
<sourcesyntaxhighlight lang="c">
#ifndef _STDIO_H
#define _STDIO_H 1
Line 132:
 
#endif
</syntaxhighlight>
</source>
 
== Repeated Declarations ==
Line 146:
'''For GCC versions < 9''', telling GCC that your headers understand C++ is done by having the following in your OS-specific gcc/gcc/config/myos.h:
 
<sourcesyntaxhighlight lang="c">
/* Don't assume anything about the header files. */
#undef NO_IMPLICIT_EXTERN_C
#define NO_IMPLICIT_EXTERN_C 1
</syntaxhighlight>
</source>
 
'''For GCC versions >= 9''', [https://patchwork.ozlabs.org/patch/934478/ this patch] changed the behaviour; they have made <tt>NO_IMPLICIT_EXTERN_C</tt> a so-called "poisoned identifier", so compiling your OS-specific toolchain will fail. If you read the linked patch above, you will realise that they decided to invert the behaviour, such that system headers are assumed to understand C++ by default. So, in theory, you do not need those two lines above at all, and it should Just Work (tm).
Line 158:
Adding support for C++ in your C header files (such as stdio.h) is very simple. Previously GCC automatically added extern "C" around all headers if compiling C++, but now we'll need to do it ourselves. The key feature is that we don't need to do this on C++-only headers, meaning that C++ headers will now actually work, instead of GCC assuming they have C-linkage. For instance, you can change your stdio.h to be of this form:
 
<sourcesyntaxhighlight lang="c">
#ifndef _STDIO_H
#define _STDIO_H 1
Line 173:
 
#endif
</syntaxhighlight>
</source>
 
[[Category:C]]
[[Category:Standard Libraries]]
[[Category:Porting]]
[[Category:Tutorials]]