一、gcc编译器
编译器:把文件经过处理,生成对应的可执行文件。
//test.c文件:
X86平台上面:
gcc编译器,可以在x86平台上面运行。
ARM平台上面的:
arm-linux-gcc
交叉编译器:在一个平台编译生成可执行文件,在另外一个平台运行可执行文件。
例如windows下面的keil就是一个交叉编译器。
代码语言:javascript复制#include <stdio.h>
void main(){
printf("hello world!n");
}
gcc编译
代码语言:javascript复制gcc main.c -o main
例子:
下面以一个很简单的 main.c 来探讨这个过程。
代码语言:javascript复制#include <stdio.h>
#define NUM 3
int main(){
int t;
#if 0
printf("hello worldn");
#endif
t = NUM;
printf("t=%dn",t);
return 0;
}
(1) 预处理:gcc -E main.c -o main.i。
我们用cat查看main.i的内容如下:
(2) 编译:gcc -S main.i -o main.s
(3) 汇编:as main.s -o main.o
nm main.o
(4) 链接:gcc -o main mian.o
二、多个文件的编译
如果仅仅只有一个文件,直接:gcc main.c -o main.o
但是如果你的程序是使用模块化编程的,又该怎么处理?
demo文件如下:
sequence.h
代码语言:javascript复制#ifndef _SEQUENCE_H_
#define _SEQUENCE_H_
void sequence(unsigned char*sp,unsigned char num);
#endif
sequence.c
代码语言:javascript复制#include "sequence.h"void sequence(unsigned char *sp,unsigned char num)
{
unsigned char i,j;
unsigned char a;
for(j=0;j<num-1;i )
{
for(i=j 1;i<num;i )
{
if(sp[j]>sp[i])
{
a=sp[i];
sp[i]=sp[j];
sp[j]=a;
}
}
}
}
main.c
代码语言:javascript复制#include <stdio.h>
#include "sequence.h"
unsigned char dis_num[8] = {10,9,17,92,2,8,35,12};
int main(void)
{
unsigned char i;
sequence(dis_num,sizeof(dis_num));
for(i=0;i<8;i )printf("%d ",dis_num[i]);
printf("rn");
return 0;
}
处理如下:
代码语言:javascript复制gcc -o sequence.o -c sequence.c
gcc -o main.o -c main.c
gcc -o main sequence.o main.o
./main
三、Linux的静态库和动态库
上面2个文档:sequence.c、sequence.h 可以做出库的形式,让其他的文件调用。
库:可以分为静态库.a和动态库.so;
静态库:会把库相应的编译到你的可执行文件里面;
动态库:不会编译到可执行文件里面,只有在执行时会调用库的内容。
1、先制作静态库:
代码语言:javascript复制gcc -o sequence.o -c sequence.c
ar crsv libsequence.a sequence.o
gcc -o main main.c -L./ -lsequence -I./
./main
2、制作动态库:
代码语言:javascript复制gcc -fPIC -Wall -c sequence.c -o sequence.o
gcc -shared -o libsequence.so sequence.o
gcc -o main main.c -L./ -lsequence
sudo cp libsequence.so /lib #拷贝
或者
#gcc -o main main.c -L./ -Wl,-rpath,${PWD} -lsequence #指明路径
./main
后面 Makefile工程管理