2014-09-06 32 views
7

Tutaj mam dwa pliki Fortran90 i makefile:Automatyczne Zamawianie Obejct plików "* .o" w Fortran Makefile

zawartość plikumain_mod.f90:

module main_mod 

contains 

    subroutine add(a, b) 
    implicit none 
    integer, intent(in) :: a, b 
    print *, (a+b) 
    end subroutine add 

end module main_mod 

zawartość plikumain_mod2.f90

module main_mod2 
    use main_mod 

contains 

    subroutine add2(a, b) 
    implicit none 
    integer, intent(in) :: a, b 

    call add(a, b) 
    end subroutine add2 

end module main_mod2 

aw makefile, automatycznie generuje listę „.o” plików z bieżącego katalogu:

F90 = /usr/bin/gfortran 
COMPFLAGS = -c 
%.o: %.f90 
     $(F90) $(COMPFLAGS) $*.f90 

all: $(patsubst %.f90,%.o,$(wildcard *.f90)) 

kiedy robię projektu, wieloznaczny oświadczenie w moim pliku make generuje listę plików obiektowych jak :

main_mod2.o main_mod.o 

a następnie kompilacja się nie powiedzie, ponieważ po pierwsze, plik main_mod.f90 potrzeby zostać skompilowany, które dałyby nam main_mod.o i main_mod.mod używany w main_mod2.f90. Następnie main_mod2.f90 zostanie skompilowany pomyślnie. Oznacza to, że permutacja plików obiektowych musi być:

main_mod.o main_mod2.o 

Teraz pytanie jest, w ogólnym przypadku, gdy tworzę listę plików obiektowych z wykorzystaniem wieloznaczny, w jaki sposób można egzekwować prawidłowe permutacji plików obiektowych?

+0

W tym przypadku kod w 'main_mod2' używa kodu w' main_mod'. W ogólnym przypadku, * jak w piekle może Zgadnij, który kod używa? * – Beta

+0

@Beta "jak do cholery Czy zgadnij, który kod używa?" - masz rację!!! Ale popatrz na wybitną odpowiedź Yossariana, aby coś takiego zrobić !!! – argasm

Odpowiedz

7

Podczas gcc ma -M i związanych z flagami robi dokładnie to z plików C/C++, ale niestety nie działa z gfortran. W rzeczywistości jest to możliwe, ale tylko wtedy, gdy znasz już zależności. Dlatego do wygenerowania zależności potrzebny będzie zewnętrzny program.

W moich projektach, używam this python script i dodać następujące moim makefile:

# Script to generate the dependencies 
MAKEDEPEND=/path/to/fort_depend.py 

# $(DEP_FILE) is a .dep file generated by fort_depend.py 
DEP_FILE = my_project.dep 

# Source files to compile 
OBJECTS = mod_file1.f90 \ 
      mod_file2.f90 

# Make sure everything depends on the .dep file 
all: $(actual_executable) $(DEP_FILE) 

# Make dependencies 
.PHONY: depend 
depend: $(DEP_FILE) 

# The .dep file depends on the source files, so it automatically gets updated 
# when you change your source 
$(DEP_FILE): $(OBJECTS) 
    @echo "Making dependencies!" 
    cd $(SRCPATH) && $(MAKEDEPEND) -w -o /path/to/$(DEP_FILE) -f $(OBJECTS) 

include $(DEP_FILE) 

fort_depend.py zasadzie tylko tworzy listę wszystkich modułów USE d w danym pliku.

+0

Dziękuję za tę niesamowitą odpowiedź! Jedyny problem jaki mam teraz to to, że skrypt python zawsze daje mi następujący błąd: Traceback (ostatnie ostatnie wywołanie): Plik "fort_depend.py", wiersz 161, w dla arg w args.D: TypeError: 'NoneType' obiekt nie jest iterowalny. Czy wcześniej miałeś podobny błąd? Jak mogę to naprawić? Dzięki jeszcze raz. – argasm

+0

również ten http://www.ii.uib.no/~avle/mkdep.html może być dobry, aby spróbować! – argasm

+0

Ok, chyba naprawiłem ten błąd. Czy możesz spróbować ponownie z najnowszymi zmianami? – Yossarian

2

... Określ je w swoich regułach.

main_mod2.o: main_mod.o 
+2

Jeśli zauważyłeś, w moim pytaniu, zapytałem "kiedy lista plików obiektów jest generowana za pomocą symboli wieloznacznych, w jaki sposób mogę określić permutację?". Nie chcę ręcznie określać reguły dla każdego pojedynczego pliku i to jest powód, dla którego zadaję to pytanie. A co, gdybym miał 2000 plików w moim projekcie? Czy uważasz, że ręczne podejście działałoby sprawnie? – argasm

+0

Musisz określić je * gdzieś *. Zasady są po prostu najbardziej oczywistym rozwiązaniem. –

+0

Podejrzewam, że powinien istnieć jakiś wbudowany obiekt w GNU make, który mówi programowi producenta, aby najpierw wykrył i skompilował najbardziej niezależne pliki źródłowe (nazwij je warstwą1), a następnie skompiluj warstwę2, która zależy od warstwy1, a następnie warstwy3 itd. . Może to być słowo kluczowe lub flaga lub wskazówka do producenta. Próbuję go znaleźć, jeśli istnieje :)) – argasm