简体   繁体   English

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

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

In my code, I have used three classes. 在我的代码中,我使用了三个类。 All the classes are in separate files. 所有类都在单独的文件中。 And I am using Makefile to compile and link them. 我正在使用Makefile进行编译和链接。 See the implementation below: 请参见下面的实现:

class Medicine 
{ 
   int a;
}

class Pain:public Medicine 
{
   int b;
}

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

All classes have just parameterized constructors, virtual destructors and a function with same name call() , in all the three classes. 在所有这三个类中,所有类都只有参数化的构造函数,虚拟析构函数和具有相同名称的函数call() And call() is like call()就像

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

The code of main.cpp goes like: 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;
}

When I run this program, I got the expected output. 当我运行该程序时,我得到了预期的输出。 But when I changed the Medicine::call() to be a virtual function, and again used make command, it says all files are up to date. 但是,当我将Medicine :: call()更改为虚拟函数,并再次使用make命令时,它说所有文件都是最新的。 As I have modified medicine.h , so make should created new version of medicine.o . 由于我已经修改了medicine.h ,因此make应该创建medicine.o新版本。 Why is it considering older medicine.o as updated when I have modified medicine.h ? 为什么在我修改了medicine.h考虑将较旧的medicine.o更新?

The Makefile goes like this: 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

If you want to see implementation of medicine.h, 如果您想查看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();
};

This medicine.h I have included in medicine.cpp , where all these functions are defined. medicine.h我已经包括在medicine.cpp ,所有这些功能都定义。

The problem is that medicine.o only depends on medicine.cpp , not on medicine.h . 问题在于medicine.o仅依赖于medicine.cpp ,而不依赖于medicine.h So you have to modify your rules to provide that missing dependency. 因此,您必须修改规则以提供缺少的依赖关系。 It has absolutely nothing to do with "virtualness". 它与“虚拟性”绝对无关。

You might also want to add the Makefile itself as a dependency, so if you change it and run make, things get re-built. 您可能还希望将Makefile本身添加为依赖项,因此,如果对其进行更改并运行make,则会重新构建东西。

To clarify, this generic rule: 为了澄清,此通用规则为:

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

means that any something.o depends on something.cpp only, and should be built with the following command: 表示any something.o仅取决于something.cpp ,应使用以下命令进行构建:

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

ie $@ is the target name and $< is the first dependency. $@是目标名称, $<是第一个依赖项。

the format is 格式是

target : <dependencies>
    command

make is not language-aware, so yes, make does not know whether a function is virtual or not; make不了解语言,因此,make不知道某个函数是否是虚拟的; actually it does not even know what C++ is and that there are functions there. 实际上,它甚至不知道C ++是什么,并且那里没有函数。

make operates in terms of targets and dependencies, and those have to be specified explicitly. make根据目标和依赖项make操作,并且必须明确指定它们。 Here, the rule to make an object does not include any .h file in the dependencies and thus it deduces that .8 files are unused for the target. 在这里,创建对象的规则在依赖项中不包含任何.h文件,因此可以推断出没有为目标使用.8文件。

It is actually quite difficult to get the proper set of transitive includes needed to build one .cpp file. 实际上很难获得构建一个.cpp文件所需的一组适当的传递性包含。 There are scripts to assist such as make_depend.pl . 有诸如make_depend.pl类的脚本可以提供帮助。

The problem is that your makefile doesn't have the dependencies for your header files to the source files, so it doesn't know that you need to recompile "x.cpp" when "yh" has changed (because "yh" is included by "x.cpp"). 问题是您的makefile不具有头文件对源文件的依赖关系,因此它不知道当“ yh”更改时您需要重新编译“ x.cpp”(因为包括了“ yh”通过“ x.cpp”)。

You can fix that by having rules like: 您可以通过以下规则来解决此问题:

medicine.o : medicine.cpp medicine.h 

However, as the number of source files get larger, and the relationship of headers to source gets more complex, you are going to forget/leave out some header files that you actually need - this will ALWAYS happen. 但是,随着源文件数量的增加以及标头与源文件的关系变得越来越复杂,您将忘记/遗漏一些您实际需要的标头文件-这将总是发生。

What I usually do is something like this: 我通常要做的是这样的:

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

main:$(OBJ) .depends

...

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

include .depends

What this does is to let the compiler generate the rules into a file .depends - that way, you don't "forget" to fix it up when you update a file somewhere. 这样做是为了让编译器将规则生成到文件.depends ,这样,当您在某个位置更新文件时,您就不会“忘记”对其进行修复。

Edit: For large projects, using a single dependency file is a poor idea, because every time a .cpp file is changed, the compiler will have to sort out all the dependencies for every file in the project. 编辑:对于大型项目,使用单个依赖项文件是个不明智的主意,因为每次更改.cpp文件时,编译器都必须整理出项目中每个文件的所有依赖项。 But for a small hobby project it's fine. 但是对于一个小型的业余项目来说,这很好。 For large projects, one would take the extra penalty of having lots of .depends files (one per source file, probably in a depends directory). 对于大型项目,要花大量的.depends文件(每个源文件一个,可能在depends目录中)会带来额外的损失。

The working of make is like this: It checks the latest modification time of the dependency ( medicine.cpp for eg) and then check the latest modification time of medicine.cpp when medicine.o was created. 的工作make是这样的:它检查的依赖(最新修改时间medicine.cpp为EG),然后检查的最后修改时间medicine.cppmedicine.o创建。 If both are same, then its not recompiled, otherwise recompiled. 如果两者相同,则不重新编译,否则重新编译。 In my case, medicine.h was modified, but the latest modification time of medicine.cpp remain unchanged. 就我而言, medicine.h进行了修改,但最新修改时间medicine.cpp保持不变。 And that's why make was unable to detect this and not recompiled medicine.cpp . 这就是为什么make无法检测到此问题并且无法重新编译medicine.cpp

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

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