2013-06-12 17 views
8

Podczas nauki modułów jądra Linux widzę (do tej pory z dwóch źródeł) dwa sposoby pisania Makefile. Pierwszym z nich jest coś takiego:Programowanie jądra Linuksa: makefile

ifneq ($(KERNELRELEASE),) 
     obj-m := module.o 
else 
default: 
     $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules 
endif 

Ten ostatni jest mniej skomplikowane:

obj-m := module.o 
all: 
     $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules 

Albo makefile kompilacja prowadzi do powodzeniem skompilowany moduł. Mojej wiedzy towarzyszy książka LDD3 i to, co do tej pory przeczytałem, jest następna:

Ten plik Makefile jest czytany dwukrotnie na typowej kompilacji. Gdy plik Makefile zostanie wywołany z linii poleceń, zauważy, że zmienna KERNELRELEASE nie została ustawiona. Lokalizuje katalog źródłowy jądra, wykorzystując fakt, że dowiązanie symboliczne zbudowane w katalogu zainstalowanych modułów wskazuje na drzewo budowania jądra. Jeśli faktycznie nie działasz jądro, które budujesz, możesz podać opcję KERNELDIR = na linii poleceń , ustawić zmienną środowiskową KERNELDIR lub przepisać linię, która ustawia KERNELDIR w pliku Makefile. Po znalezieniu drzewa źródłowego jądra makefile wywołuje domyślny: target, który uruchamia drugie polecenie make (sparametryzowane w makefile jako $ (MAKE)), aby wywołać system kompilacji jądra, jak opisano wcześniej. W drugim czytaniu plik makefile ustawia obj-m, a pliki makefile jądra zajmują się w rzeczywistości budowaniem modułu.

Jeśli plik Makefile zostanie odczytany dwukrotnie, drugie podejście powinno prowadzić do rekursji, prawda?

+5

Rekursja (w tym kontekście) jest zdefiniowana jako jedna instancja Make, która wywołuje inną instancję Make. Drugie podejście obejmuje rekurencję. Jeśli pytasz, czy drugie podejście prowadzi do nieskończonej pętli, odpowiedź brzmi "nie", ponieważ druga instancja Make ma "moduły" jako cel, a nie "wszystkie". Czy to jest odpowiedź na Twoje pytanie? – Beta

+1

Beta, powinieneś opublikować to jako odpowiedź, a nie jako komentarz. Pobiłbym cię. Dodam, że oba podejścia wykorzystują rekursję do działania, ale pierwszy wynik sprawia, że ​​bardziej oczywiste jest, że reguła "domyślna" lub "wszystkie" nie zostanie wywołana przy drugim przejściu. –

+0

@ Beta, czy możesz wyjaśnić bardziej szczegółowo, jak dokładnie to nie prowadzi do rekursji wewnątrz marki? Ewentualnie opublikuj swoją odpowiedź, a ja przegłosuję ^^. (Oglądanie kodu źródłowego Makefile kbuild nie pozwala mi dojść do punktu, w którym mogę dowiedzieć się, jakie są wewnętrzne) – mesmerizingr

Odpowiedz

3

Gdy wywołujesz Makefile po raz pierwszy, wpisując na konsoli #make, nie przekazujesz żadnego celu. Tak więc będzie domyślnie wywoływana nazwa docelowa all: w pliku Makefile.

Wewnątrz celu all: przekazujesz cel jako moduły. Tym razem zbudujesz moduły zamiast przejść do celów docelowych all:.

To nie będzie nieskończona rekursja.

Powiązane problemy