命令链接编译
假设有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