Makefile - 如何正确编写依赖

时间:2015-01-18 15:56:56

标签: c++ makefile

我的想法是这样的:我SportsCar来自CarCar来自Engine,每次调用Car.drive()时,都会调用Engine.consumeGas() Gas,然后创建Gas.burn()对象并调用test.exe: main.obj Car.obj SportsCar.obj Engine.obj Gas.obj main.obj: main.cpp Car.h SportsCar.h Car.obj: Car.cpp Car.h SportsCar.obj: SportsCar.cpp SportsCar.h // Here is what went wrong Engine.obj: Engine.cpp Engine.h Gas.h Gas.obj: Gas.cpp Gas.h 。正如您在下面的源代码中看到的那样。

每个类都有自己的头文件和cpp文件。我写了一个Makefile(用于微软的NMAKE程序)。

依赖性是这样的:

test.exe

构建程序并运行engine,生成输出:

  

汽车驾驶

     

发动机消耗气体

     

燃气

     

SportsCar驱动器

     

发动机消耗气体

     

燃气

问题是,如果我从Car删除成员engine.consumeGas()并删除Car.drive()中的Car.cpp来电并重建整个程序,仅{{1}并且main.cpp被重新编译(SportsCar.cpp不是),链接器根本不会抱怨。

重建后,运行test.exe获取输出:

  

汽车驾驶

     

SportsCar驱动器

     

发动机消耗气体

     

燃气

显然这个结果完全违反了C ++的语义。

如果我像这样编写依赖项,问题就会解决。

SportsCar.obj: SportsCar.cpp SportsCar.h Car.h

因此,如果我有一个源文件A,其中包含一个头文件B,而该文件又包含另一个头文件C,并且在A中,则为{使用了{1}},我必须说C取决于AB,而不只是C取决于A

如果项目足够大,我恐怕在编写Makefile时,试图找出哪个文件取决于哪个文件会迷路。

代码:

的main.cpp

B

Car.h

#include "Car.h"
#include "SportsCar.h"

int main()
{
    Car *car = new Car();
    car->drive();
    delete car;

    car = new SportsCar();
    car->drive();
    delete car;

    return 0;
}

Car.cpp

#ifndef CAR_H
#define CAR_H

#include "Engine.h"

class Car
{
protected:
    Engine engine;
public:
    virtual void drive();
    virtual ~Car();
};

#endif // CAR_H

SportsCar.h

#include "Car.h"

#include <iostream>

using namespace std;

void Car::drive()
{
    cout << "Car drive" << endl;
    engine.consumeGas();
}

Car::~Car()
{
    // do nothing
}

SportsCar.cpp

#ifndef SPORTSCAR_H
#define SPORTSCAR_H

#include "Car.h"

class SportsCar : public Car
{

public:
    void drive();
};

#endif // SPORTSCAR_H

Engine.h

#include "SportsCar.h"

#include <iostream>

using namespace std;

void SportsCar::drive()
{
    cout << "SportsCar drive" << endl;
    engine.consumeGas();
}

Engine.cpp

#ifndef ENGINE_H
#define ENGINE_H

class Engine
{

public:
    void consumeGas();
};

#endif // ENGINE_H

Gas.h

#include "Engine.h"
#include "Gas.h"

#include <iostream>

using namespace std;

void Engine::consumeGas()
{
    cout << "Engine consuming gas" << endl;
    Gas g;
    g.burn();
}

Gas.cpp

#ifndef GAS_H
#define GAS_H

class Gas
{

public:
    void burn();
};

#endif // GAS_H

1 个答案:

答案 0 :(得分:0)

您通常不应将依赖项硬编码到makefile中。相反,您应该使用-M -MF标志在编译期间生成依赖项,并将include生成的文件生成到Makefile中。否则,您的依赖项总是与现实不同步。

可悲的是,自动依赖关系生成是一个复杂的主题,我无法在此详细解释。许多细节可以在本文中找到:Auto-Dependency Generation