这两天写代码,被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也包含进去,这样这个库就有了两个类,这种做法运行也会成功。