以经典的helloworld.c为例说明linux下C语言的编译过程
helloworld.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
C语言的编译过程分为四个步骤:
1、预处理--Preprocessing
xiongf@ubuntu:~/Test$ ls
helloworld.c
xiongf@ubuntu:~/Test$ cpp helloworld.c -o helloworld.i
xiongf@ubuntu:~/Test$ ls
helloworld.c helloworld.i
helloworld.c的内容部分如下:
......
# 1 "/usr/include/bits/types.h" 1 3 4
# 28 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 29 "/usr/include/bits/types.h" 2 3 4
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
......
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 936 "/usr/include/stdio.h" 3 4
# 2 "helloworld.c" 2
int main(void)
{
printf("hello world\n");
return 0;
}
2、编译--Compile
xiongf@ubuntu:~/Test$ cc1 helloworld.i -o helloworld.s
xiongf@ubuntu:~/Test$ ls
helloworld.c helloworld.i helloworld.s
helloworld.s的内容如下所示:
.file "helloworld.i"
.section .rodata
.LC0:
.string "hello world"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call puts
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
3、汇编--assembly
xiongf@ubuntu:~/Test$ as helloworld.s -o helloworld.o
xiongf@ubuntu:~/Test$ ls
helloworld.c helloworld.i helloworld.o helloworld.s
4、链接--linking
xiongf@ubuntu:~/Test$ ld --dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o helloworld.o -o helloworld -lc
xiongf@ubuntu:~/Test$ ls
helloworld helloworld.c helloworld.i helloworld.o helloworld.s
xiongf@ubuntu:~/Test$ ./helloworld
hello world
关于上述用到的四个工具,后面会有博客详细介绍。