19

Objective-C 有一个运行时,可以将其语法转换为可组织和编译的函数。C 有运行时库吗?另外,如果有人可以回答这个问题,GCC 在 C 编译期间采取了哪些步骤?例如 main.c >> main.s >> main.bin

4

3 回答 3

10

Yes, the C language features a standard library; that is, a number of standard macros, routines and types one can use in his programs, apart from any in the core language itself.

In popular implementations, there is a separate library file containing the code for the C standard library. For example, in GNU/Linux environments, the GNU C library (libc) is almost always present. Microsoft provides the msvcrt.dll runtime library for the Windows system, and so on.

Also, the C standard library might not be available in freestanding implementations. Sometimes it is possible to compile a program without linking against the C standard library from your system. As an example, the Windows API is well known for behaving as a freestanding C programming environment (although one might need to link against other system libraries specific to Windows).

Regarding GCC, the following illustrates briefly the compilation pipeline:

  1. The input source is preprocessed with GNU cpp, resulting in a translation unit. (Actually, as Basile pointed out, nowadays no cpp process is created; the entire preprocessing work is done within cc1. Nevertheless, the resulting behavior is most likely the same as with cpp.)
  2. The translation unit is then interpreted and compiled to assembly source with GCC cc1;
  3. The assembly source is then assembled into object code with GNU as;
  4. Finally, object files and libraries are linked together to produce a binary image with GNU ld.

Naturally, each of these steps may be altered or not executed at all depending on the driver options; the above is just a rough explanation of the overall process.

于 2012-10-16T03:54:41.900 回答
4

C 有一个标准库(libc在 Linux 上,它提供了标准函数,如诸如<stdio.h>fprintf所有系统调用之类的函数),即使您在独立模式下使用(例如编译一个或某些内核)它链接一个提供语言内置功能的小型库(例如 32 位平台上的 64 位加法)。<stdlib.h>mallocgccgcc -ffreestandinglibclibgcc

要了解gcc命令在做什么,请将-v标志传递给它。(不要忘记养成始终编译-Wall以获取警告和-g调试信息的习惯),例如

 % gcc -v -g -Wall hello.c -o hello
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.2 (Debian 4.7.2-4) 
COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/cc1 -quiet -v -imultiarch x86_64-linux-gnu hello.c -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -g -Wall -version -o /tmp/ccsWt3UC.s
GNU C (Debian 4.7.2-4) version 4.7.2 (x86_64-linux-gnu)
    compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.7/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C (Debian 4.7.2-4) version 4.7.2 (x86_64-linux-gnu)
    compiled by GNU C version 4.7.2, GMP version 5.0.5, MPFR version 3.1.0-p10, MPC version 0.9
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c5f63dedeacd449634699df94fe3d914
COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/ccO5i3pU.o /tmp/ccsWt3UC.s
GNU assembler version 2.22 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.22
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.7/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-g' '-Wall' '-o' 'hello' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.7/collect2 --sysroot=/ --build-id --no-add-needed --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.7 -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.7/../../.. /tmp/ccO5i3pU.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o

请注意,collect2是为执行其他操作而包装的链接器,libc.so几乎每个 Linux 可执行文件都使用它(因为它包装了syscalls)。

于 2012-10-16T04:57:46.630 回答
2

C 有一个标准库(例如strlen,malloc等)

步骤是:编译使用标准库的代码,然后将代码链接到标准库。libc可以包含在静态库或动态库中,具体取决于;通常两者都可用。

于 2012-10-16T03:31:18.207 回答