gcc的相关理解

gcc的基本应用

实验的源文件

//main.c
#include<stdio.h>
#include"mylib.h"

int main()
{
        int i=func1(1,2);
        func2(i);
        return 0;
}

//func1.c
#include"mylib.h"

int func1(int x,int y)
{
        return x+y;
}

//func2.c
#include<stdio.h>
#include"mylib.h"

void func2(int x)
{
        printf("The result is %d\n",x);
}

//mylib.h
int func1(int x,int y);
void func2(int x);
  1. gcc -Wall main.c -o main

直接由源文件生成可执行文件main,其中-Wall用于显示详细的编译报错信息

  1. gcc -Wall -c main.c
    生成目标文件main.o,当有多个.c文件的时候可以直接并列包含在这后面。在编译过程中只用编译.c文件,而不用考虑.h文件,因为.h文件一般被include引用到了.c文件中,.h 文件存储的是相关函数的声明,这样单独编译比如main.c文件时,虽然main.c中间没有定义其他模块中的函数,但是根据include的.h文件中的声明仍然可以编译通过,只是在目标文件中留下了一个缺口,待在连接过程来将相关的函数的定义填上。

  2. gcc main.o hello.o -o main
    对多个目标文件进行连接从而生成最终的可执行文件,2和3通常是依次进行的,先编译成目标文件然后进行连接。这样可以对每个文件进行单独的模块化编译。

  3. ar cr libhello.a func1.o func2.o
    将目标文件归档为静态库文件libhello.a,静态库文件的真实名字为hello,只是按照命名规范需要在前面加上lib,在后面加上.a。参数cr分别代表create和replace。

  4. ar t libhello.a
    分别列出一个库文件中包含的.o文件

  5. gcc -Wall main.c libhello.a -o hello
    可以直接根据源文件和库文件生成可执行文件hello,这个指令直接指定了libhello.a文件名,可以直接运行成功。注意上面的main.c必须要在libhello.a之前,否则会出现undefined reference func1之类的错误。

  6. gcc -Wall main.c -lhello -o hello
    报错:/usr/bin/ld: cannot find -lhello;collect2: error: ld returned 1 exit status
    这是因为使用-l选项会从标准库路径/usr/lib中去寻找libname.a的库文件,而我们编译的库文件只在当前路径下。有3种方法可以解决这个报错。
    (1)将静态库libname.a文件直接拷贝到/usr/lib/目录下,这样有个问题就是只能是root用户才有权限,并且如果每个程序都这样做标准库路径就变成了垃圾堆。
    (2)通过下面指令:gcc -Wall main.c -L. -lhello -o hello
    -----这条指令是通过-L指定编译过程中搜索的库文件目录,该例子是指定当前目录为搜索目录。从而可以编译成功。但仍然要注意的是main.c必须放在-lhello的前面,否则又会出现第6点中的undefined reference错误。
    (3)定义环境变量,
    export LIBRARY_PATH=/root/gcc03/:$LIBRARY_PATH
    然后再执行gcc -Wall main.c -lhello -o hello
    这样也能执行成功。
    LIBRARY_PATH指定的是库文件的搜索路径的环境变量,对应编译中的-L选项。另外C_INCLUDE_PATH是指定头文件的搜索路径的环境变量,对应于编译中的-I选项。
    如果环境变量定义错误,可以通过unset LIBRARY_PATH来删除取消该环境变量。
    通常只会采用第(2)中方法来编译。

实际场景中的情况

在实际开发中通常是将上述文件放到不同的专门对应文件夹中,如下图所示:
.
├── include
│ └── mylib.h
├── lib
│ ├── func1.c
│ ├── func1.o
│ ├── func2.c
│ ├── func2.o
│ ├── libhello1.a
│ └── libhello.a
└── main.c
(1)首先编译main.c文件成main.o文件
这时直接使用gcc -Wall -c main.c会报如下错误
main.c:2:9: fatal error: mylib.h: No such file or directory
#include"mylib.h"
^~~~~~~~~
compilation terminated.

这是因为找不到include的头文件,默认会到/usr/include/和当前目录去找,所以需要通过-I选项指定搜索头文件路径。具体编译成目标文件的指令如下:
gcc -Wall -c main.c -Iinclude ,-c选项和main.c等参数目前看来没有顺序要求。

(2)gcc -Wall main.o -Llib -lhello -o hello
通过-L指令指定库文件路径从而生成可执行文件hello。

上述两步其实可以通过一步完成:
gcc -Wall main.c -Iinclude -Llib -lhello -o hello

编译过程中的路径搜索顺序

先搜索-L和-I指定的路径,然后会搜索环境变量指定的路径,最后搜索默认路径和当前目录。其中-I(i的大写)选项对应的-l(小写字母l)库名并不会搜索当前目录,因为-l选项指定的库名就会自动到默认库中去搜索。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值