0

I've check this answer but I think it is not the same situation of mine.

I'm using f2py to compile my fortran code, so that I can import this fortran code in python.
For example, I have two fortran files: t.f90 and t2.f90, and using this command to compile:

$ f2py -c t.f90 -m f90t
$ f2py -c t2.f90 -m f90t2

and two .so files are generated: f90t.cpython-36m-x86_64-linux-gnu.so and f90t2.cpython-36m-x86_64-linux-gnu.so.

I want to use Makefile to compile these files. My Makefile is like this:

FILES = t.f90 t2.f90

NAMES = $(basename $(FILES))
TARGET = $(addprefix f90, $(NAMES))

all : $(TARGET)

f90% : %.f90
    @echo "Compile $< to $@"
    f2py -c $< -m $@

.PHONY : clean
clean : 
    rm f90*.so

The Makefile can work without error, but something is strange. If I change the content of one fortran file and execute Makefile, it still "compile" two fortran file, but actually the output file is not changed.

Like this:

$ ls       # run.py will execute the function of t.f90 and t2.f90
Makefile run.py t.f90 t2.f90
$ make
Compile t.f90 to f90t
....
Compile t2.f90 to f90t2
....
$ python run.py
"This line is printed by t.f90"
"This line is printed by t2.f90"
$ vim t2.f90     # adding some exclamation mark
$ make           # I only modified t2.f90, but t.f90 is also compiled
Compile t.f90 to f90t
....
Compile t2.f90 to f90t2
....
$ python run.py       # still the old result
"This line is printed by t.f90"
"This line is printed by t2.f90"
$ make clean
$ make
Compile t.f90 to f90t
....
Compile t2.f90 to f90t2
....
$ python run.py       # finally ok
"This line is printed by t.f90"
"This line is printed by t2.f90 !!!!!!!!!!!!!!!!"

I have no idea why this happened. Can anyone help?
Any suggestion is grateful. Thanks!

Chun-Ye Lu
  • 343
  • 1
  • 2
  • 10

1 Answers1

1

Your makefile expects that f90t and f90t2 are built, but as you say

two .so files are generated: f90t.cpython-36m-x86_64-linux-gnu.so

So, on next run, make does not find f90t and calls the command again. You can do something like

    @touch $@

at the end of the rule or rename the targets.

ensc
  • 6,704
  • 14
  • 22
  • Very Thanks! I misunderstood that I can ignore the extension of target file. Adding `@touch $@` can work. – Chun-Ye Lu Sep 10 '20 at 09:52
  • But using `@touch $@` would generate unneeded files `f90t` and `f90t2`. I was wondering that if I can just adding extension of target file? That is, change target from `f90t` to `f90t.cpython-36m-x86_64-linux-gnu.so`. But if I use this method, it would create folders `f90t/` and 'f90t2/' instead of .so files. How to solve this problem? – Chun-Ye Lu Sep 10 '20 at 09:56
  • 1
    it is a common practice to create such helper files/targets; usually they are "hidden" by making them a dot file (e..g ".f90x.stamp"). Of course, you can use the full name, but this seems to be complicated because it contains dynamic information (host architecture + os). – ensc Sep 10 '20 at 13:39
  • OK I see, it seems that create a hidden file `.f90t1` and `.f90t2` is a great idea. I have modified my Makefile and the result is totally what I want. Very thank you! – Chun-Ye Lu Sep 10 '20 at 14:42