bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Make does not build a missing prerequisite.


From: Maxim Yegorushkin
Subject: Re: Make does not build a missing prerequisite.
Date: Thu, 09 Oct 2014 11:31:46 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1

On 07/10/14 15:51, Reinier Post wrote:
On Tue Oct  7 13:09:11 2014, address@hidden (Maxim Yegorushkin) wrote:
My dependencies are:

build/Linux-x86_64-64.g++-release/lib/libdata_access.so :
build/Linux-x86_64-64.g++-release/obj-mt-pic/data_access/data_access.o
build/Linux-x86_64-64.g++-release/obj-mt-pic/data_access/data_access.o :
src/c++/data_access/data_access.cc
src/c++/data_access/data_access.cc :
src/c++/data_access/data_access.reflect.h
src/c++/data_access/data_access.reflect.h :
src/c++/data_access/data_access.h src/c++/reflect/generate.py

This is not a complete list.

True.

I am attaching two complete make outputs when using a clean build on two different machines from the same commit of my source tree. One build always succeeds (m.txt) another one always fails (m2.txt).

What happens is that make correctly identifies that data_access.cc depends
on data_access.reflect.h, finds an implicit rule that generates
data_access.reflect.h, rebuilds the dependencies of data_access.reflect.h
but neglects to build data_access.reflect.h itself.

Really?  That's not what I'm seeing below.

Why does it not build data_access.reflect.h please?

I am using GNU make-4.0. Below is the relevant bit from `make -r -d` output:

    Considering target file
'build/Linux-x86_64-64.g++-release/lib/libdata_access.so'.
     File 'build/Linux-x86_64-64.g++-release/lib/libdata_access.so' does not 
exist.
[...]
'src/c++/data_access/data_access.reflect.h'.
         Pruning file 'src/c++/data_access/data_access.h'.
         Considering target file 'src/c++/reflect/generate.py'.
          Looking for an implicit rule for 'src/c++/reflect/generate.py'.
          Trying pattern rule with stem 'generate'.
          Trying rule prerequisite 'src/python/olivetree_c.py'.
[...]
            Finished prerequisites of target file 'src/python/olivetree_c.py'.
           Must remake target 'src/python/olivetree_c.py'.
cd src/python && ln -fs olivetree_c.py.release olivetree_c.py
Putting child 0x1e74d10 (src/python/olivetree_c.py) PID 4317 on the chain.
Live child 0x1e74d10 (src/python/olivetree_c.py) PID 4317
Reaping winning child 0x1e74d10 PID 4317
Removing child 0x1e74d10 PID 4317 from chain.
           Successfully remade target file 'src/python/olivetree_c.py'.
          Considering target file 'src/python/olivetree_c.py'.
          File 'src/python/olivetree_c.py' was considered already.
          Finished prerequisites of target file 'src/c++/reflect/generate.py'.
          Prerequisite 'src/python/olivetree_c.py' of target 
'src/c++/reflect/generate.py' does not exist.

This is weird.  You just 'created' it, except that you really didn't:
all you did was create a symbolic link to what is supposedly
a pre-existing file.  There are two risks wih this:

1) Does that file actually exist?  Make claims it doesn't.

It does exist.

2) Even if it exists, you didn't update its modification time;
    make will notice it's older than the target,
    so why should it remake the target?

         Must remake target 'src/c++/reflect/generate.py'.
         Successfully remade target file 'src/c++/reflect/generate.py'.

Well, it successfully remade generate.py anyway by doing nothing.

         Pruning file 'etc/rules.mk'.
       Finished prerequisites of target file 
'src/c++/data_access/data_access.cc'.
       Prerequisite 'src/c++/data_access/data_access.reflect.h' of target
'src/c++/data_access/data_access.cc' does not exist.

But for some reason make does not remake data_access.reflect.h.

      No need to remake target 'src/c++/data_access/data_access.cc'.
      Finished prerequisites of target file
'build/Linux-x86_64-64.g++-release/obj-mt-pic/data_access/data_access.o'

I looked at the diff of successful and unsuccessful build logs and the peculiar thing is how make handled all .d files on two different machines.

On the machine where build always succeeds make does:

Considering target file '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. File '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d' does not exist. Looking for an implicit rule for '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. No implicit rule found for '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. Finished prerequisites of target file '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. Must remake target '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. Failed to remake target file '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'.

On the machine where make fails it does:

Considering target file '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. Looking for an implicit rule for '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. No implicit rule found for '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. Finished prerequisites of target file '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'. No need to remake target '/home/max/otsquant/build/Linux-x86_64-64.g++-release/obj-mt-pic/util/odbc.d'.

Please note, I was doing clean builds, no .d files existed prior to the build and there was no rule to make them. And I invoke `make -r` to disable all built-in rules.

So, what I did, I added the following rule to my makefile:

    # Do not fail remaking .d files.
    ${build_root}/%.d : ;

And now my build succeeds on the machine where it was previously failing. When I compare debug outputs now on both machines, they are identical (apart from pids).

On both machines make-4.0 was build from sources. The machine where make always succeeded runs Fedora 20, the other one runs CentOS-6.5.

Strange...

-- Maxim



Attachment: make-debug-outputs.tar.xz
Description: application/xz


reply via email to

[Prev in Thread] Current Thread [Next in Thread]