[bug #59762] make --touch produce local spurious empty files with out-of-tree Makefile strategy

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[bug #59762] make --touch produce local spurious empty files with out-of-tree Makefile strategy

Paul D. Smith
URL:
  <https://savannah.gnu.org/bugs/?59762>

                 Summary: make --touch produce local spurious empty files with
out-of-tree Makefile strategy
                 Project: make
            Submitted by: None
            Submitted on: Thu 24 Dec 2020 03:43:44 PM UTC
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: 4.1
        Operating System: POSIX-Based
           Fixed Release: None
           Triage Status: None

    _______________________________________________________

Details:

We implemented the out-of-tree compilation strategy
(http://make.mad-scientist.net/papers/multi-architecture-builds/#target.mk)
described by Paul D. Smith on his blog (http://mad-scientist.net/).
We are very thankful for this method as it helped simplify a lot our
multi-architecture compilation process.

However, when using `make --touch` it also `touch` files in the root
directory, files named after all targets that needed to be touched (it also
touch the proper targets in their own build directories).

I observed this issue with `make` 4.1  on Ubuntu 18.04.2 LST and 4.2.1 on
Debian 10 and SUSE Linux Enterprise Server 15.

I made a simplified reproduction usecase which is available on gitlab and can
be obtained with

git clone https://gitlab.com/martn/makeTouchIssue.git

I also attach the simplified `Makefile` and `target.mk` for easier reference
(the actual sources are just dummy files).

Here is the scenario:
make
pgm.o: file1.o file2.o
file2.o: file1.o

The compilation follows the out-of-tree strategy above mentioned; it compiles
in `./build`.

0 I make a full build of a project

$ ls src/
file1.f90  file2.f90  pgm.f90
$ make
compiling file1.o
compiling file2.o
compiling pgm.o
linking pgm.x
:
$ ls build/
file1.o  file2.o  pgm.o  pgm.x


0 I touch `src/file1.f90` (simulating a modification to the code that would
not change any interface)

0 `make` would then want to rebuild everything
But in fact I would just need to recompile `file1.o` and relink `pgm.x`.

0 So I recompile `file1.o` and use `make --touch` to prevent recompiling the
other objects

$ make file1.o
compiling file1.o
:
$ make --touch file2.o pgm.o
touch file2.o
touch pgm.o
touch file2.o
touch pgm.o

Here is the issue; it did touch the object files in `./build` but also touched
two (empty) files in `./`:

$ ls
build  file2.o  Makefile  pgm.o  README.md  src  target.mk


Although I am not sure, I think it is related to the `target.mk` mechanics; so
it might not be a bug, but simply an unwanted side effect.

After concerting with my colleagues we thought pertinent to mention it.
Obviously for real project, these spurious files can seriously clutter the
root directory.



    _______________________________________________________

File Attachments:


-------------------------------------------------------
Date: Thu 24 Dec 2020 03:43:44 PM UTC  Name: Makefile  Size: 835B   By: None

<http://savannah.gnu.org/bugs/download.php?file_id=50561>
-------------------------------------------------------
Date: Thu 24 Dec 2020 03:43:44 PM UTC  Name: target.mk  Size: 322B   By: None

<http://savannah.gnu.org/bugs/download.php?file_id=50562>

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59762>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59762] make --touch produce local spurious empty files with out-of-tree Makefile strategy

Paul D. Smith
Follow-up Comment #1, bug #59762 (project make):

You target.mk contains rule

% :: $(DIR_TARGET) ; :

When you run
$ make file1.o

make finds this rule, with % being file1.o and its prerequisite being build.
Make then makes this prerequisite and then proceeds to execute the recipe to
make file1.o from this prerequisite. In this rule this recipe is :.

See that : printed after linking pgm.x?

When you run

$ make -t file1.o
make finds this rule, with % being file1.o and its prerequisite being build.
Make then makes this prerequisite (this is the first touch which creates
file1.o in the build directory) and then proceeds to make file1.o. Because -t
is specified  make touches file1.o in the parent directory.


    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59762>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59762] make --touch produce local spurious empty files with out-of-tree Makefile strategy

Paul D. Smith
Follow-up Comment #2, bug #59762 (project make):

Thank you for this explanation.

Is there a way to preserve the out-of-tree compilation (here illustrated by
the build directory), but avoid this double touch?

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59762>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/


Reply | Threaded
Open this post in threaded view
|

[bug #59762] make --touch produce local spurious empty files with out-of-tree Makefile strategy

Paul D. Smith
Update of bug #59762 (project make):

                  Status:                    None => Not A Bug              
             Open/Closed:                    Open => Closed                

    _______________________________________________________

Follow-up Comment #3:

There is no way to avoid this.  The --touch option will touch all the targets
that make wants to build.  If you say *make --touch file2.o pgm.o* then
*file2.o* and *pgm.o* are targets and make will touch them.

There is no way to avoid this: it's not possible to mark certain targets as
being "not to be touched" by the --touch option.

All I can say is that I find the --touch option somewhat dangerous and I don't
recommend its use.  It's too easy to accidentally bring some file up to date
that should instead have been rebuilt, and cause your builds to fail or worse,
your build to succeed but your generated output to fail in subtle ways.

If you really want to have this facility available and you really don't want
to have these extra files, you'll have to invent your own "touch" facility
that doesn't use make's --touch flag.

For example you could create a touch-% target that touched $* then instead of
*make --touch file2.o pgm.o* you could run *make touch-file2.o touch-pgm.o*.

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?59762>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/