2013-08-22 6 views
5

Buduję zestaw modułów jądra Linux przy użyciu współdzielonego kodu źródłowego. Z tego co rozumiem, plik Makefile musi być nazwany "Makefile", więc muszę użyć tego samego Makefile do zbudowania dwóch różnych modułów. Jak mogę zbudować dwa różne moduły w obrębie tego samego pliku Makefile z tym samym kodem źródłowym, ale z dwiema różnymi opcjami kompilacji?Z modułów jądra drzewa: Wiele modułów, pojedynczy plik Makefile, ten sam plik źródłowy, różne opcje kompilacji

Na przykład moje moduły nazywane są moduł1 i moduł2. Więc mam następujący wiersz, aby je określić:

obj-m := module1.o module2.o 

wśród innych plików, zarówno Module1 i module2 trzeba użyć tego samego pliku źródłowego code.c, ale zbudowany z różnymi opcjami kompilacji. Tak mówią na przykład, Makefile zawiera następujące wiersze:

module1-objs = module1_code.o other_code.o 
module2-objs = module2_code.o other_code.o 

Chcę module1_code.o i module2_code.o być zbudowany z code.c, ale z różnymi opcjami. W szczególności chcę jeden module1_code.o z makro zdefiniowane -DPREPROCEFFOR_FLAG=1 i module2_code.o zbudowany bez makra.

Z tego co wiem, system plików Makefile używanych w systemie Linux domyślnie sugeruje, że dla pliku obiektowego o nazwie "code.o" plik źródłowy nazywa się "code.c", więc jak mógłbym to osiągnąć? Czy to możliwe? Czy jest lepszy sposób to zrobić?

+0

Możesz nazwać swój plik Makefile, jak tylko chcesz. make jednak domyślnie szuka tylko [niektórych nazw plików] (http://www.gnu.org/software/make/manual/make.html#Makefile-Arguments). W przypadku innych nazw należy użyć argumentu '-f'. –

+0

Jeśli podasz konkretną regułę dla pliku obiektowego z warunkiem wstępnym odpowiedniego pliku źródłowego, a reguły dotyczące budowania marki docelowej będą używać tej zamiast domyślnej reguły, o której wspomniałeś. Więc 'module1_code.o: code.c; '. –

Odpowiedz

5

Trzeba tu problem, bo oczywiście mieć code.c zestawiane jest inaczej, gdy -DPREPROCEFFOR_FLAG=1 jest zdefiniowana, ale po jego skompilowany do code.o sprawiają, że nie dbają o flagi preprocesora lub cokolwiek bo code.o będą już aktualne.

Potrzebujesz sposobu na zbudowanie code.c różnych plików obiektów z różnymi flagami C. Jest prawdopodobnie czysty sposób to zrobić (nie miał szans z O= bo z modułów drzewa), ale tutaj jest jeszcze moja innelegant skutecznym rozwiązaniem w tym momencie:

my_modules: 
    cp code.c code_noflags.c 
    cp code.c code_withflags.c 
    make -C $$KDIR M=$$PWD modules 
    rm code_noflags.c code_withflags.c 

# module objects 
obj-m := module1.o module2.o 

# module1 specifics 
module1-y := code_withflags.o 
CFLAGS_code_withflags.o := -DPREPROCEFFOR_FLAG=1 

# module2 specifics 
module2-y := code_noflags.o 

Wystarczy zadzwonić:

$ make KDIR=/path/to/kernel 

You można sprawdzić flagi preprocesora jest przekazywany do pliku źródłowego do obiektu z prawej:

$ make KDIR=/path/to/kernel V=1 | grep PREPRO 

można również mieć dwa oddzielne katalogi dla każdego modułu, jeśli jest to Possi i mieć symboliczny link code.c w każdym z nich wskazuje na wspólne rzeczywiste code.c. Jest to jednak nadal hackish i nie czuje się dobrze.

+1

Rozwiązaniem (potencjalnie równie nieeleganckim) byłoby utworzenie sim-linku do code.c, tj. Code-link.c, a następnie skompilowanie pliku linku z alternatywną flagą. –

2

Prostym rozwiązaniem jest, kontynuując z Makefile

obj-m := module1.o module2.o 

module1-objs = module1_code.o other_code.o 
module2-objs = module2_code.o other_code.o 

dodać jeszcze dwa pliki źródłowe, module1_code.c i module2_code.c.

Następnie module1_code.c właśnie wygląda:

#define PREPROCEFFOR_FLAG 1 
#include "code.c" 

i module2_code.c wynosi:

#include "code.c" 

Lub jeśli chcesz zmienić nazwy w Makefile i pliki źródłowe, tak, że drugi to bez definiowania nie jest konieczne. Poza tym możesz uczynić dwa pliki źródłowe tylko dodatkiem i użyć zmiennej CFLAGS_module1_code.o, aby dodać opcję -D... do kompilatora, jeśli wolisz.

Jest to podobne do tego, co dzieje się w jądrze z arch/x86/boot/video-vesa.c upstream i arch/x86/realmode/rm/video-vesa.c itp, gdzie plik realmode tylko zawiera:

#include "../../boot/video-vesa.c" 

a kod wideo vesa.c kończy się uzyskiwanie skompilowany dwukrotnie inna flagi kompilatora.

To wydaje się lepsze niż kopiowanie plików źródłowych, ponieważ kończy się to bałaganem, jeśli chcesz użyć opcji O=... do kompilacji jądra, aby zachować czyste drzewo źródłowe i zbudować oddzielne drzewo obiektów.

Powiązane problemy