静态库调用静态库&静态库加载静态库------谈谈undefined reference to和linker input file unused because linking not done

          静态库可以调用静态库吗? 静态库可以加载静态库吗?  搞清这些东西, 对于linux开发很重要, 本文我们来探讨这些问题。

 

          先看程序:

          business.h:

#include <iostream>
using namespace std;

void business();

          business.cpp:

#include <iostream>
#include "business.h"
using namespace std;

void business()
{
	printf("business code\n");
}

        main.cpp

#include <iostream>
#include "business.h"
using namespace std;

int main()
{
    business();
    printf("main code\n");
}

       我们来编译运行看下:

 

xxxxxx:~/liblearn> g++ -c business.cpp
xxxxxx:~/liblearn> ar rcs libbusiness.a business.o
xxxxxx:~/liblearn> ls
business.cpp  business.h  business.o  libbusiness.a  main.cpp
xxxxxx:~/liblearn> g++ main.cpp -L. -lbusiness
xxxxxx:~/liblearn> ls
a.out  business.cpp  business.h  business.o  libbusiness.a  main.cpp
xxxxxx:~/liblearn> ./a.out 
business code
main code
xxxxxx:~/liblearn> 

 

       一切正常。

 

 

        我们再看看:

 

        basic.h

#include <iostream>
using namespace std;

void basic();

        basic.cpp

#include <iostream>
#include "basic.h"
using namespace std;

void basic()
{
    printf("basic code\n");
}

 

        business.h:

#include <iostream>
using namespace std;

void business();

        business.cpp:

#include <iostream>
#include "basic.h"
#include "business.h"
using namespace std;

void business()
{
    basic();
    printf("business code\n");
}

       main.cpp内容为:

#include <iostream>
#include "business.h"
using namespace std;

int main()
{
    business();
    printf("main code\n");

    return 0;
}

      来看看结果:

 

xxxxxx:~/liblearn> ls
basic.cpp  basic.h  business.cpp  business.h  main.cpp
xxxxxx:~/liblearn> g++ -c basic.cpp 
xxxxxx:~/liblearn> g++ -c business.cpp 
xxxxxx:~/liblearn> strings business.o | grep "basic code"
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> ar rcs libbasic.a basic.o
xxxxxx:~/liblearn> g++ -c business.cpp -L. -lbasic
g++: -lbasic: linker input file unused because linking not done
xxxxxx:~/liblearn> strings business.o | grep "basic code"
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> ar rcs libbusiness.a business.o
xxxxxx:~/liblearn> g++ main.cpp -L. -lbusiness
./libbusiness.a(business.o): In function `business()':
business.cpp:(.text+0x79): undefined reference to `basic()'
collect2: ld returned 1 exit status
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> g++ main.cpp -L. -lbusiness -lbasic
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> 
xxxxxx:~/liblearn> ./a.out 
basic code
business code
main code
xxxxxx:~/liblearn> strings a.out | grep "basic code"
basic code
xxxxxx:~/liblearn> 

       分析一下, 我们看到, 在编译business.cpp后, strings命令的结果没有basic code信息, 也就是business没有加载basic模块的任何东西, 因为这里只是编译, 没有链接. 即使主动链接一下, 也没有鸟用, 还会有warning提示linker input file unused because linking not done,   所以, 很自然地, g++ main.cpp -L. -lbusiness找不到basic, 很自然地需要g++ main.cpp -L. -lbusiness -lbasic, 这就带来了一个问题: libbusiness.a/business.h并不能独立地对外提供能力, 略蛋疼。

 

       怎么办呢? 这里可以考虑两种方法:

       a.  把libbasic.a库和libbusiness.a库合成新的libbusiness.a库, 但我个人不建议这么做。

       b.  专门为libbusiness.a搞一个宏, 使得每次链接libbusiness.a的时候, 自动也链接到libbasic.a,  这对于使用libbusiness.a的人来说, 是透明的, 不可见的, 不需要管的, 比较爽。

   

       综上所述: 

       1.  静态库 .a文件(这里更准确的说法应该是.o文件)不能加载其他静态库, 因为只涉及到编译,不涉及到链接。

       2.  静态库 .a文件(这里更准确的说法应该是.o文件)可以调用其他静态库(调用其中的函数), 此时并不会链接, 也不需要链接, 也链接不了。

           

 

        很多时候, 当我们的business模块要调用新的basic模块的静态库时, 要特别特别小心, 否则就会坑后面的同学, 后面同学在编译main的时候(或者其他so需要依赖于business静态库的时候), 肯定会undefined reference to xxx,  不好意思, 我曾经坑过两位同学大哭大哭

 

        其实, “加载”和“链接”的意思是差不多的。 好了, 本文先说道这里, 又有进步啦。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值