繁体   English   中英

make文件中提到的对依赖项的修改(对makefile中提到的依赖项)是否不识别?

[英]Is modification of dependency, of a dependency mentioned in makefile, not recognized by make?

在我的代码中,我使用了三个类。 所有类都在单独的文件中。 我正在使用Makefile进行编译和链接。 请参见下面的实现:

class Medicine 
{ 
   int a;
}

class Pain:public Medicine 
{
   int b;
}

class Comb:public Pain   
{
    string salt,com;
}

在所有这三个类中,所有类都只有参数化的构造函数,虚拟析构函数和具有相同名称的函数call() call()就像

call()
{
     cout<<"You are in class the_name_of_the_class"<<endl;
}

main.cpp的代码如下:

int main()
{       
    Medicine *p[2];
    p[0]= new Comb("Salt","Com",2,110);
    p[1]= new Comb("SALT","COM",1,100);

    p[0]->call();

    delete p[0];
    delete p[1];
    return 0;
}

当我运行该程序时,我得到了预期的输出。 但是,当我将Medicine :: call()更改为虚拟函数,并再次使用make命令时,它说所有文件都是最新的。 由于我已经修改了medicine.h ,因此make应该创建medicine.o新版本。 为什么在我修改了medicine.h考虑将较旧的medicine.o更新?

Makefile如下所示:

using .PHONY:clean
OBJ:=medicine.o pain.o comb.o main.o
SOU:=medicine.cpp pain.cpp comb.cpp main.cpp

main:$(OBJ)
        g++ -o $@ $^

%.o:%.cpp
        g++ -c -o $@ $<

clean:
        rm *.o main

如果您想查看medicine.h的实现,

class Medicine
{
    int cost;

 public:

    int getCost();
    void setCost(int);

    Medicine();
    Medicine(int);
    Medicine(Medicine &a);
    virtual string getCompany(){};
    virtual string getSalt(){};
    virtual  ~Medicine ();
    virtual void call();
};

medicine.h我已经包括在medicine.cpp ,所有这些功能都定义。

问题在于medicine.o仅依赖于medicine.cpp ,而不依赖于medicine.h 因此,您必须修改规则以提供缺少的依赖关系。 它与“虚拟性”绝对无关。

您可能还希望将Makefile本身添加为依赖项,因此,如果对其进行更改并运行make,则会重新构建东西。

为了澄清,此通用规则为:

%.o:%.cpp
    g++ -c -o $@ $<

表示any something.o仅取决于something.cpp ,应使用以下命令进行构建:

g++ -c -o something.o something.cpp

$@是目标名称, $<是第一个依赖项。

格式是

target : <dependencies>
    command

make不了解语言,因此,make不知道某个函数是否是虚拟的; 实际上,它甚至不知道C ++是什么,并且那里没有函数。

make根据目标和依赖项make操作,并且必须明确指定它们。 在这里,创建对象的规则在依赖项中不包含任何.h文件,因此可以推断出没有为目标使用.8文件。

实际上很难获得构建一个.cpp文件所需的一组适当的传递性包含。 有诸如make_depend.pl类的脚本可以提供帮助。

问题是您的makefile不具有头文件对源文件的依赖关系,因此它不知道当“ yh”更改时您需要重新编译“ x.cpp”(因为包括了“ yh”通过“ x.cpp”)。

您可以通过以下规则来解决此问题:

medicine.o : medicine.cpp medicine.h 

但是,随着源文件数量的增加以及标头与源文件的关系变得越来越复杂,您将忘记/遗漏一些您实际需要的标头文件-这将总是发生。

我通常要做的是这样的:

SOU = medicine.cpp pain.cpp comb.cpp main.cpp
... 

main:$(OBJ) .depends

...

.depends: $(SOU)
     g++ -MM $(SOU) > $@

include .depends

这样做是为了让编译器将规则生成到文件.depends ,这样,当您在某个位置更新文件时,您就不会“忘记”对其进行修复。

编辑:对于大型项目,使用单个依赖项文件是个不明智的主意,因为每次更改.cpp文件时,编译器都必须整理出项目中每个文件的所有依赖项。 但是对于一个小型的业余项目来说,这很好。 对于大型项目,要花大量的.depends文件(每个源文件一个,可能在depends目录中)会带来额外的损失。

的工作make是这样的:它检查的依赖(最新修改时间medicine.cpp为EG),然后检查的最后修改时间medicine.cppmedicine.o创建。 如果两者相同,则不重新编译,否则重新编译。 就我而言, medicine.h进行了修改,但最新修改时间medicine.cpp保持不变。 这就是为什么make无法检测到此问题并且无法重新编译medicine.cpp

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM