Okej, wszyscy widzieliśmy te pytania w Internecie, takie jak Arduino kontra C ++ lub inne podobne pytania. Zdecydowana większość odpowiedzi nawet nie dotyka różnic w kompilacji inaczej niż poprzez abstrakcyjne informacje.
Moje pytanie ma na celu rozwiązanie faktycznych różnic (a nie preferencji) w sposobie kompilacji pliku .ino na plik .cpp lub inne podobne rozszerzenie dla c ++ przy użyciu GCC-AVR. Wiem, że co najmniej musisz dołączyć plik nagłówkowy Arduino, ale poza tym, co spowodowałoby błąd kompilacji, gdyby kompilacja wspomnianego pliku .ino do pliku .cpp przy użyciu, powiedzmy, na przykład GCC-AVR. Dla uproszczenia, skorzystajmy z klasycznego przykładu mrugnięcia, aby wyjaśnić różnice. Lub jeśli masz lepszy fragment kodu do użycia, należy w jakikolwiek sposób dołączyć ten fragment do swojej odpowiedzi i dokładnie wyjaśnić różnice.
Proszę nie opiniować, który jest lepszym sposobem lub narzędziem do użycia.
Do Twojej wiadomości Używam Platformio do programowania i zauważam, że proces kompilacji zachodzi za kulisami podczas kompilacji. Próbuję zrozumieć, co się tam właściwie dzieje, więc kiedy piszę w Arduino, rozumiem również „czystą” wersję C ++.
Dziękuję za z góry przemyślane odpowiedzi na moje pytanie.
źródło
gcc
komputer, czy kompilator GCC for AVRavr-gcc
? istnieje o wiele większa różnica niż pomiędzy plikiem.ino
a.cpp
plikiem.Odpowiedzi:
Zobacz moją odpowiedź tutaj: Klasy i obiekty: ile i jakich typów plików faktycznie muszę ich używać? - w szczególności: jak IDE organizuje rzeczy .
Tak, musisz to zrobić.
IDE generuje dla Ciebie prototypy funkcji. Kod w pliku .ino może, ale nie musi tego potrzebować (prawdopodobnie będzie to konieczne, chyba że autor jest wystarczająco zdyscyplinowany, aby kodować w zwykły sposób w C ++ i robić je sami).
Jeśli „szkic” zawiera inne pliki (np. Inne pliki .ino, .c lub .cpp), należy je włączyć do procesu kompilacji, jak to opisałem w mojej odpowiedzi wspomnianej powyżej.
Musisz także (skompilować i) link w dowolnych bibliotekach używanych w szkicu.
Nie pytałeś o linkowanie rzeczy, ale oczywiście różne skompilowane pliki muszą być połączone razem, a następnie przekształcone w plik .elf i .hex do celów przesyłania. Patrz poniżej.
Przykładowy plik makefile
Na podstawie danych wyjściowych IDE zrobiłem jakiś prosty plik makefile :
W tym konkretnym przypadku plik .ino skompilowano bez żadnych problemów po zmianie nazwy pliku na Blink.cpp i dodaniu tej linii:
źródło
Chciałbym tylko dodać kilka punktów do odpowiedzi Nicka Gammona:
-x c++
), zignoruje nietypowe rozszerzenie pliku i skompiluje go jako C ++.#include <Arduino.h>
pliku .ino: możesz powiedzieć kompilatorowi, aby zrobił to za Ciebie (-include Arduino.h
).Używając tych sztuczek, mogę skompilować Blink.ino bez modyfikacji , po prostu wywołując avr-g ++ z odpowiednimi opcjami wiersza poleceń:
Kilka uwag na temat powyższego wiersza poleceń:
/usr/local/lib/arduino/uno/libcore.a
to gdzie zapisałem skompilowany rdzeń Arduino. Nienawidzę kompilowania w kółko tych samych rzeczy.-x none
jest potrzebne, aby poinformować kompilator o tym, żeby pamiętał o rozszerzeniach plików. Bez tego zakładałby, że libcore.a jest plikiem C ++.Nauczyłem się tych sztuczek z Arduino-Makefile Sudar Muthu . Jest to bardzo ogólny plik Makefile, który działa z wieloma tablicami i bibliotekami. Jedyne, czego brakuje w stosunku do Arduino IDE, to deklaracje forward.
źródło
libcore.a
plik. Przypuszczam, że wiersze w mojej odpowiedzi, która kompilacjacore.a
może być wykonana z wyprzedzeniem, więc nie muszą być częścią każdej kompilacji. Doświadczenie pokazuje, że bardziej złożone szkice (np. Przy użyciu Wire lub SPI) wymagają dodania większej liczby plikówcore.a
.