Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[avr-gcc][c] - Jak skompilować program do plików pośrednich.

cavendish 06 Kwi 2013 16:36 1266 4
  • #1 06 Kwi 2013 16:36
    cavendish
    Poziom 17  

    W skrypcie programu make znajduje się dyrektywa:

    Code:
    $(PRG).elf: $(OBJ)
    
       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)

    Powoduje ona wygenerowanie pliku elf wraz ze wszystkimi plikami pośrednimi będącymi wynikiem pracy kompilatora i linkera. Moje pytanie brzmi: jak powinna wyglądać prawidłowa procedura, która spowoduje wygenerowanie tylko plików pośrednich, obiektowych (.o). Kompilator to oczywiście avr-gcc.
    Jak dotąd próbowałem napisać prostą procedurę (typu %.o: %.c), która generowała plik .o z danego pliku źródłowego po czym pojawiał się błąd linkera, iż nie widzi on funkcji main(). Przy czym moim zamierzeniem nie było uruchamianie linkera i nie przekazałem w tym celu żadnych instrukcji sterujących.

    0 4
  • Pomocny post
    #2 06 Kwi 2013 19:17
    krru
    Poziom 32  

    gcc -c

    0
  • #3 06 Kwi 2013 21:01
    cavendish
    Poziom 17  

    Dzięki. Klasyczna sytuacja, w której potrzeba świeżego spojrzenia z zewnątrz - patrzysz na problem i nie widzisz jego banalnego rozwiązania...

    -----------------------------------------------------------------------------
    To w takim razie jeszcze jedno pytanie.
    Mam zdefiniowaną taką oto regułę:

    Code:
    all: hello obj/watchdog.o
    

    %.o: ../watchdog/watchdog.c
       $(CC) $(CFLAGS) -c $< -o $@

    Dostaję taki wynik działania gcc:
    Code:
    avr-gcc -g  (...) -c ../watchdog/watchdog.c -o obj/watchdog.o
    
    avr-gcc -g  (...) -c ../watchdog/watchdog.c -o all.o
    avr-gcc --gc-sections, -Wl,-Map,out/main.map  all.o hello obj/watchdog.o   -o all
    avr-gcc: hello: No such file or directory

    Czyli tak jakby gcc próbował utworzyć plik .o dla "all" a na końcu, żeby było jeszcze śmieszniej chce zlinkować 'all' i 'hello'.


    Co ciekawe wystarczy zmienić rozszerzenie pliku obiektowego na dowolne inne:
    Code:
    all: hello obj/watchdog.ob
    

    %.ob: ../watchdog/watchdog.c
       $(CC) $(CFLAGS) -c $< -o $@

    i wszystko działa jak należy:
    Code:
    avr-gcc -g  (...) -o obj/watchdog.ob

    a w odpowiednim katalogu znajduje się plik wynikowy. Ktoś potrafi wytłumaczyć ten fenomen?

    0
  • Pomocny post
    #4 07 Kwi 2013 01:05
    krru
    Poziom 32  

    Troche pokręcony jest ten makefile.
    Cel 'all' jest zbędny, gdy ma być utworzony tylko jeden plik. Używa się go, gdy wynikiem ma być niż jeden
    program. Oczywiście sama nazwa 'all' nie ma znaczenia - make bez parametrów bierze pierwszy cel z pliku.

    Wynikiem jest tylko hello, watchdog.o to cel pośredni, a nie ostateczny, nie powinny być na tym samym poziomie drzewa.

    hello: hello.o obj/watchdog.o

    No i taka reguła:
    %.o: ../watchdog/watchdog.c

    Oznacza, że dowolny plik .o jest utworzony z kompilacji watchdog.c, stąd kompilacja all.o
    Make ma wiele domyślnych zależności, w tym utworzenie .o z .c itp.
    Albo musisz to redefiniować, albo podać, że kompilatorem jest avr-gcc

    CC = avr-gcc

    W drugim przypadku nie ma domyślnych reguł na .ob

    0
  • #5 07 Kwi 2013 10:36
    cavendish
    Poziom 17  

    Cytat:
    Troche pokręcony jest ten makefile. (...)
    Wiem. Na ogół przerabiałem makefile nie musząc pisać ich od postaw. Teraz w "iteracyjny" sposób uczę się organizować projekt "od zera" według własnych potrzeb. Wycinki wyżej to jeden z przejściowych etapów mojej nauki. Plików do kompilacji będzie dużo więcej niż jeden.

    Cytat:
    Wynikiem jest tylko hello, watchdog.o to cel pośredni, a nie ostateczny, nie powinny być na tym samym poziomie drzewa.

    hello: hello.o obj/watchdog.o
    Nie rozumiem. Do makefile z pakietu winavr, który wcześniej przerobiłem, dodałem do all tylko wyrzucanie na konsolę opcji jakie dostępne są do wywołania z make'iem:
    Code:
    all: hello $(PRG).elf lst text eeprom
    

    hello:   
       @echo    "all"
       @echo    "clean"
       @echo    "rebuild"

    I wszystko dobrze działało.

    Cytat:
    Oznacza, że dowolny plik .o jest utworzony z kompilacji watchdog.c, stąd kompilacja all.o
    O to mi chodziło, dzięki.
    Cytat:
    Albo musisz to redefiniować, albo podać, że kompilatorem jest avr-gcc

    CC = avr-gcc
    Tak też mam zrobione... ?

    0