g++链接lib库时的顺序

来源:互联网 发布:java搭建项目的流程 编辑:程序博客网 时间:2024/05/16 18:39

这两天写代码,被makefile中的各种依赖搞晕了,本来就不怎么熟悉makefile,要引用的库又一大堆,是在是太头疼了可怜,现在乘着头脑清醒,写几个简单的程序,明确一下lib库的调用。

a.h

#ifndef A_H#define A_H#include <iostream>class A{public: A(){}    ~A(){}    void hello();};#endif

a.cpp

#include "a.h"void A::hello(){      std::cout << "hello world\n";}


b.h

#ifndef B_H#define B_H#include "a.h"#include <iostream>class B{    public:       void sayB();    private:      A a;};#endif

b.cpp

#include "b.h"void B::sayB(){    std::cout << "B is running\n";    a.hello();    std::cout << "B is end\n";}

c.cpp

#include "b.h"int main(){    std::cout << "C is running\n";    B b;    b.sayB();    std::cout << "C is end\n";}

class a是个独立的类,class B调用了A的接口,c.cpp又使用了class B类型的变量

有两种编译方法:

 (1)目标文件编译: 首先使用g++ -c *.cpp,生成对应的目标文件,然后g++ -o c a.o b.o c.o   g++ -o c b.o a.o c.o   g++ -o c c.o b.o a.o  g++ -o c a.o b.o c.cpp 都可以生成可执行程序c,./c运行输出结果,这几个.o文件在命令中的次序是无关 的, 怎么放都可以编译成功。注意:编译成.O文件时g++后面要附带包含的头文件名,由于g++默认在当前目录和标准路径中找,所以此处可以省略。

(2)生成lib库再链接:


.o文件还是第一种方法时生成的,直接g++-c b.cpp,不考虑b.cpp还调用了class A。这时-la -lb的先后顺序导致了程序能否正确编译和链接。查资料得到g++链接的原则:是“先引用, 后定义”,或者叫做“越基础的库, 越往后面写”。库文件可能出现这样的问题A库依赖B库,B库依赖C库,而C库又依赖了A库,出现了这样的问题,不只我们头大,g++也会头大。团队里之前曾经讨论过这个问题,一个相对完美的方案是,设置底层库,中间库,上层逻辑,这样的垂直关系,尽量避免循环依赖。
另外,自己还尝试了一下,这种:

 就是生成libb.a库的时候把a.o也包含进去,这样这个库就有了两个类,这种做法运行也会成功。



原创粉丝点击