Hi,

I have implemented the method described on [Paul D. Smith's 
blog](http://make.mad-scientist.net/papers/multi-architecture-builds/) for 
multi-architecture builds.
This was done for a fortran data assimilation library used at the Canadian 
Meteorological Center.
The project being in fortran 90, there is no clear separation between 
declaration of interfaces and implementation, such that if only implementation 
of a function is modified there is no simple way to tell `make` not to 
recompile every dependent objects but simply the one modified and proceed with 
relinking.

We tried to use `make --touch` to indicate not to recompile certain objects for 
these case, but through the [`target.mk`  out-of-tree 
strategy](http://make.mad-scientist.net/papers/multi-architecture-builds/#target.mk)
 it also touches empty files (named after the targets of the `make --touch` in 
the `Makefile` directory, cluttering it with a lot of useless files...

I created a simplified `Makefile` that reproduce that issue, which could be 
accessed at

https://gitlab.com/martn/makeTouchIssue

Would you be aware of a way to resolve that and keep the out-of-tree 
compilation working?

For sake of completeness, I include here the description of the simplified 
reproduction of the potential issue that one would find in the gitlab project 
`README.md`
The gitlab project itself can be cloned to reproduce the simplified usecase 
issue.


Regards,

--
Martin Deshaies-Jacques

Spécialiste en sciences physiques | Physical sciences specialist
Environnement et Changement Climatique Canada | Environment and Climate Change 
Canada
Recherche en qualité de l'air | Air Quality Research Division
2121, Autoroute transcanadienne, Dorval (Québec) H9P 1J3
514.421.5304
# `make --touch` issue with out-of-tree Makefile strategy

We use the [out-of-tree compilation strategy](http://make.mad-scientist.net/papers/multi-architecture-builds/#advanced)
described by [Paul D. Smith](http://mad-scientist.net/).

However it seems it interfere with the `--touch` feature of `make`.

In the simplified `make` scenario, we are building a program `pgm.x` that 
depends on 2 objects: `file1.o` and `file2.o` in which the later use a function
contained in `file1.o`; this is why the `Makefile` have:
```make
file2.o: file1.o
```

## Problematic usecase
Let say, after a full build
```
$ make
compiling file1.o
compiling file2.o
compiling pgm.o
linking pgm.x
:
$ tree build/
build/
├── file1.o
├── file2.o
├── pgm.o
└── pgm.x

0 directories, 4 files
$ make 
make[1]: Nothing to be done for 'all'.
:
```
A developper changes the content of a function in `src/file1.f90` in a
way that **does not modify the function interface** and recompile the object:
```
$ touch src/file1.f90 # modifying func1 implementation
$ make file1.o
compiling file1.o
:
```

Although `file1.o` needed to be recompiled, neither `file2.o` nor
`pgm.o` need to be recompiled.
Obviously, `make` can't know that:
```
$ make -n 
[ -d build ] || mkdir -p build
make --no-print-directory -C build -f .../Makefile SRC_ROOT=... 
echo "compiling file2.o"
cp .../src/file2.f90 file2.o
echo "compiling pgm.o"
cp .../src/pgm.f90 pgm.o
echo "linking pgm.x"
cp pgm.o pgm.x
:
```
`make` would recompile both `file2.o`, `pgm.o` and relink `pgm.x`.
But in this case it could only relink.

So we use the `--touch` feature to indicate that both `file2.o` and `pgm.o` 
need no recompilation:
```
$ make --touch file2.o pgm.o 
touch file2.o
touch pgm.o
touch file2.o
touch pgm.o
```
Here is the first indication of the potential issue: the repetition of `touch`.
And we see what happened:
```
$ ls
Makefile  README.md  build  file2.o  pgm.o  src  target.mk
```
It did touch both `build/file2.o` and `build/pgm.o` since now `make -n`
indicates it would only proceed to linking
```
$  make -n
[ -d build ] || mkdir -p build
make --no-print-directory -C build -f /fs/homeu1/eccc/aq/arqi/mad001/code/makeExpProjects/makeTouchBug/Makefile SRC_ROOT=/fs/homeu1/eccc/aq/arqi/mad001/code/makeExpProjects/makeTouchBug 
echo "linking pgm.x"
cp pgm.o pgm.x
:
```
but it also touched two unwanted files in the project root directory.


Is there a way to prevent that?

Reply via email to