Linux下C语言多文件链接编译命令

命令链接编译

假设有main.c

#include<stdio.h>
#include"fun.h"
int main()
{
    int a, b, c, d;
    printf("please enter a, b");
    scanf("%d %d", &a, &b);
    c = add(a,b);
    printf("a + b = %d\n", c);
    d = sub(a, b);
    printf("a - b = %d\n", d);
    return 0;
}

其中main函数调用的add、sub函数分别包含在
fun1.c

#include"fun.h"
int add(int x, int y)
{
    return x+y;
}

fun2.c

#include"fun.h"
int sub(int a, int b)
{
	return a-b;
}

以及包含两个函数声明的头文件fun.h

#ifndef FUN_H
#define FUN_H
int add(int x, int y);
int sub(int a, int b);
#endif

Step 1. 要将它们链接编译出可执行程序,首先编译源程序(*.c)生成目标程序(*.o)

gcc -c main.c  
  • *.c文件用gcc编译,*.cpp文件用g++编译
  • 完整表述为gcc -c main.c -o main.o,缺省部分默认生成与源文件同名的目标文件
  • 当有多个源程序是可进一步简写为
gcc -c *.c  

运行后生成main.o, fun1.o, fun2.o共3个目标文件

Step 2. 打包创建静态库文件(libxxx.a)

ar -crv libfun.a fun1.o fun2.o  
  • 其中 crv 是 ar 的命令选项,具体可见ar --help
  • 通过 ar t libfun.a 可以查看其中包含的目标文件
  • 注意库的文件名必须形如 libxxx.a ,这样我们在之后链接这个库时,就可以用 -lxxx

运行后得到 libfun.a,这就是我们需要的静态库

Step 3. 程序链接静态库文件,生成可执行文件

gcc main.o -o main.out -L. -lfun  
  • 使用 gcc 还是 g++ 取决于源程序 main 是 .c 还是 .cpp
  • -L. 表示指定库文件所在目录,“ . ”表示在当前目录,其他位置用目录完整路径代替
  • -lfun 表示指定库文件名,省略了完整名 libfun.a 前面的 lib 和后面的 .a

运行后得到 main.out 程序,用命令 ./main.out 执行即可

Makefile链接编译

当程序并未完善时,尤其是还要对源程序进行修改,每一次都要逐条敲命令执行效率较低,故可编写 Makefile 文件进行操作
对于上面的例子,Makefile 文件编写如下

.PHONY: build test

build: libfun.a

libfun.a: fun1.o fun2.o
	ar crv $@ fun1.o fun2.o

fun1.o: fun1.c
	gcc -c fun1.c

fun2.o: fun2.c
	gcc -c fun2.c

test: a.out

a.out: main.cpp
	g++ main.cpp -L. -lfun
  • 实际上在这里并像上面一样没有先将 main.c 先编译成 main.o ,而是在库文件搭建好后,用最后一行 gcc main.c -L. -lfun 直接完成了编译和链接两个步骤,这种思路也是可以的
make build  

运行后将会构建 libfun.a, 对已有的文件覆盖重写

make test  

运行后将会生成链接 libfun.a 的可执行程序 a.out

碰到的问题

Error: undefined reference

  • 当在 c++ 代码中链接 c 语言的库就会出现该种错误提示

比如将上述例子中的 main.c 修改为如下的 main.cpp

#include<iostream>
#include"fun.h"
using namespace std;
int main()
{
    int a, b, c, d;
    cout<<"please enter a, b"<<endl;
    cin>>a>>b;
    c = add(a,b);
    cout<<"a + b = "<<c<<endl;
    d = sub(a, b);
    cout<<"a - b = "<<d<<endl;
    return 0;
}

此时 main.cpp 为 c++ 代码,调用了 c 语言库的函数,因此链接的时候就会找不到

解决办法

  • 在 main.cpp 中,把与 c 语言库 libfun.a 相关的头文件包含添加一个 extern “C” 的声明即可(注意C大写)
#include<iostream>
using namespace std;
extern "C"
{
    #include"fun.h"
}
int main()
{
    int a, b, c, d;
    cout<<"please enter a, b"<<endl;
    cin>>a>>b;
    c = add(a,b);
    cout<<"a + b = "<<c<<endl;
    d = sub(a, b);
    cout<<"a - b = "<<d<<endl;
    return 0;
}

其他 undefined reference 相关问题可参考https://blog.51cto.com/ticktick/431329

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.Lance

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值