1.编译单个.c文件为可执行程序
编译hello.c文件,并列出所有警告信息(-Wall的思是warning all):
gcc -Wall hello.c -o hello
2.关于#include括号的问题
#include "file.h"编译器会首先在当前目录下寻找file.h(这里的当前目录指的是当前编译的包含file.h的.c文件所在的目录;#include <file.h>编译器会直接到系统头文件去找
3.系统头文件放在/usr/include或者/usr/local/include文件夹里
4.gcc加-v参数可以详细的显示编译过程
5.编译.c文件为目标文件(windows为.obj文件,linux为.o文件)
gcc -Wall -c main.c 将main.c文件编译为.o文件,这种情况下,无需使用-o指定输出文件的名字,输出文件的名字默认是main.o(文件名字.o)
6.C语言编写,头文件注意事项
gcc编译的时候,无需指定头文件,但是编写程序的过程一定要指定。关于头头文件包含问题可以参考下文:添加链接描述
7.链接中间文件为可执行程序
有了目标文件之后,为了产生最终的可执行文件,使用linker(链接器)将目标文件链接为最终的可执行文件,这个过程用命令实现很简单:
gcc main.o hello.o IU.o -o hello
即只需要gcc后面加上各个目标文件的名字,空格隔开即可完成链接,并且可以用-o选项来指定最终可执行文件的名字,这个过程就不需要使用-Wall参数了
8.目标文件的链接顺序:(gcc无所谓,了解即可)
目标文件中如果包含函数定义,那么该目标文件应该放在调用该函数的另外一个目标文件的后面,例如:main.c中调用了hello.c中的hello()函数,那么,链接的时候就应该这样链接:gcc main.o hello.o 即 定义应放在调用的右边
但是现在大多数编译器都不要求一定要遵从上述规则,gcc就是这样的。但是不排除少数编译器,因此要遵从上述规则
9.一般而言,链接要比编译的速度快
10.make 的基本原理
是比较各个.c文件对应的.o文件的时间戳,来判断.c文件是否在编译为.o文件之后被改动过,如果被改动过就编译这个.c文件来更新.o文件,并重新链接为新的程序
11.静态库的概念
External Libraries是已经编译好的中间文件集合成为的一个库文件。库最普遍的用处是提供系统函数,例如:开平放根的函数在C math Lib中,静态库的后缀是.a(windows平台是.lib)
12.库的分类
库分为静态库和动态链接库
13.静态库的制作
见20.
14.库主要用于链接阶段
在编译阶段用不到库,库主要用在链接阶段,对于printf等C标准库,使用gcc链接的时候不需要显式的制定链接库,gcc会自动隐式链接printf这些C标准函数的库
15.库在Linux中的路径位置
C标准库等这些系统标准库通常被放那个在/usr/lib和/usr/local/lib目录下
16.编译指定静态库的命令
gcc -Wall main.c -lm -o main
以上命令的含义:
编译main.c然后链接libm.a库和mian.c生成可执行程序main
从这里可以看出链接系统库的方法即加上参数-lNAME即表示链接libNAME.a库,这种方法只能链接名字以lib开头的系统标准库(及18所描述的库)。对于其他的第三方外部库,还需要加-L参数和库的路径,参考下文
17.编译指定静态库的注意事项
当用gcc命令编译链接.c文件为可执行程序,被编译的.c文件调用了需要显式指定的库,那么此时.c文件必须放在库的左边。例如:在main.c中用到了libhello.a库,那应该这样编译链接:gcc -Wall main.c libhello.a -o main 即main.c要放在库的前边. 否则必报错!
18.当用gcc命令链接.o文件和.a库文件,如果.o文件中调用.a库文件的函数,那么.o文件一定要放在.a库文件的左边。(和17同理即“调用在左原则
”)
19.扩展头文件和库的搜索路径:
默认情况下,gcc寻找头文件和库文件的路径如下:
/usr/local/include
/usr/include
/usr/local/lib
/usr/lib
gcc自己所在的目录等等
以上都是和系统有关的头文件和库文件,如果需要链接的库放在其他目录下,此时就需要扩大搜索路径的范围:让编译器能够找到他们,使用-I后面加搜索头文件的目录
,使用-L后面加库的目录加库的简写(注意:-L和路径之间没有空格!)(如-L/home/IU -lhello.a)
例:
gcc main.c -Wall -L. -lhello -o exe
编译main.c,链接名为libhello.a的当前路径的外部库,然后生成名为exe的可执行程序
同样,使用-I后面加头文件路径也是:-I/home/IU/include
20.创建自己的库:使用ar命令
ar cr libNAME.a file1.o file2.o file3.o ......filen.o
创建一个名为libNAME的静态库
ar还可以查看一个库文件中有多少目标文件:
ar t libNAME.A
21.以下是一个例子,供理解静态库的添加和编译方法:
leejieun@IUaena:~/文档/gcc$ ls
func1.c func1.h func1.o func2.c func2.h func2.o libhello.a main.c
leejieun@IUaena:~/文档/gcc$ cat func1.c
#include <stdio.h>
#include "func1.h"
void func1(void)
{
printf("I am func1!\n");
}
leejieun@IUaena:~/文档/gcc$ cat func1.h
void func1(void);
cat func2.h
void func2(void);
leejieun@IUaena:~/文档/gcc$ cat func2.c
#include <stdio.h>
#include "func2.h"
void func2(void)
{
printf("I am func2!\n");
}
leejieun@IUaena:~/文档/gcc$ cat main.c
#include "func1.h"
#include "func2.h"
int main(void)
{
func1();
func2();
return 0;
}
leejieun@IUaena:~/文档/gcc$ gcc -Wall main.c -L. libhello.a -o exe
leejieun@IUaena:~/文档/gcc$
leejieun@IUaena:~/文档/gcc$ ./exe
I am func1!
I am func2!
这个程序如果将func1.c和func2.c编译为中间文件,然后使用ar cr命令制作一个libhello.a库,然后使用gcc -Wall main.c -L. libhello.a -o exe命令编译生成可执行程序
未完代续。。。