Forum: Compiler & IDEs WINAVR + make


von Josef Zimmermann (Gast)


Lesenswert?

Hallo allerseits

ich experimentiere nun seit ein paar Tagen mit WINAVR herum. Dabei bin 
ich nun auf 2 Punkte gestossen, an denen ich nicht mehr weiter komme.

1.) Wie kriege ich make dazu, einen Buildlauf (make bzw. make all) zu 
protokollieren?

2.) Die Shell sh übergibt keine Parameter an make.
Wenn ich make clean aufrufe, versucht make neu zu comilieren. Im 
Dos-Fenster ohne sh klappts.

3.) Warum gibt gcc_avr eine Warnung aus wenn ich
"void main(void){.. }" verwende? Es gibt letzlich keine OS, das 
Rückmeldungen beim Beenden des Programms auswerten könnte. Damit sollte 
die Konstruktion eigentlich korrekt sein. Die Frage scheint etwas 
akademisch, allerdings bin ich bei Warnings immer Mistrauisch.

Grüsse

Josef

von Maximan (Gast)


Lesenswert?

Zu 1:
make all > log.txt
damit wird die Standardausgabe in eine Datei umgeleitet, hat allerdings 
den Nachteil, dass man nichts davon auf dem Bildschirm sieht.

2:
Bei mir gehts...

3:
Ist doch einfach ANSI C, dass main() einen int wert zurückgeben muss. 
Stimmt, aber schon, ist etwas unlogisch.

von Joerg Wunsch (Gast)


Lesenswert?

Naja, Standard-C verlangt für main() eine der beiden
Deklarationen:

int main(void);
int main(int, char **);

(bzw. Äquivalente), falls die Übersetzung in einem »hosted
environment« abgearbeitet werden soll.  Für ein sogenanntes
»freestanding environment« dagegen hat die Funktion main()
keine Sonderbedeutung mehr und kann beliebig deklariert sein
oder gar komplett entfallen.

Man könnte nun davon ausgehen, daß eine Microcontroller-Umgebung
natürlich ein klassischer Fall von »freestanding environment«
wäre, gibt -ffreestanding an, und der Fall hat sich.

Aber: in »Using the GNU tools« in der avr-libc Doku habe ich
es ein wenig schon herausgearbeitet: es ist nicht wirklich
ein freestanding environment, in dem man hier arbeitet.  Es
ist eine beachtliche Menge an Standard-C-kompatibler Bibliothek
mittlerweile vorhanden.  -ffreestanding unterdrückt nicht nur
diese Warnung, sondern auch alle internen Optimierungen, bei
denen der gcc eine Standardfunktion bekannter Funktionalität
durch einen äquivalenten Konstrukt ersetzt.  Beispielsweise
kann ich im Code schreiben:

foolen = strlen("foo");

und er wird foolen mit dem Wert 3 belegen, ohne auch nur einen
einzigen Funktionsaufruf vorzunehmen -- da das Verhalten von
strlen() im Standard eben definiert ist.  Mit -ffreestanding
dagegen würde die Funktion strlen() selbst auf einem konstanten
String aufgerufen.  (Diese Optimierungen sind ein zweischneidiges
Schwert.  Der Ersatz von printf("foo\n"); durch puts("foo");
z. B. kann den Code vergrößern, wenn damit das erste Mal
überhaupt puts() ins Spiel gebracht wird.)

Im Allgemeinen will man daher wohl doch eher nicht -ffreestanding
benutzen.  Ist aber nicht tragisch, da ein typisches main()
halt so aussieht:

int
main(void)
{
...
  for (;;) {
    ...
  }
  return 0;
}

Der Optimizer erkennt, daß die for-Schleife nie terminiert
und eliminiert den Rest von main() dann sowieso.  Es entsteht
also keinerlei Nachteil davon, daß man standard-kompatibel
geblieben ist.  (Man darf sogar in dieser Situation das
abschließende return 0; weglassen, ohne daß der Compiler
meckert, aber ganz sauber ist das natürlich nicht.)

Noch ein Grund, das nicht mit -ffreestanding zu erschlagen:
in der C++-Umgebung wird einer der beiden standardkonformen
Prototypen für main() erzwungen, alles andere ist dort
inakzeptabel.

von Josef Zimmermann (Gast)


Lesenswert?

Hallo allerseits

vielen Dank für die Infos.

1.) Die Umleitung per make >log.txt klappt, bis auf die Tatsache, dass 
Warnings und Fehlermeldungen weiter auf dem Bildschirm erscheinen, die 
eigentlichen Compileraufrufe aber im Logfile landen.

2.) Ich verwenden WIN98 und rufe make im Dos-Fenster auf. Vermutlich 
liegt hier das Problem.

3.) Andere Compiler (ICCAVR, KeilC51, Tasking) akzeptieren ein "void 
main(void)" ohne Warning. Wie auch immer, ich werde es als int 
main(void){.. return(0);} unschreiben.

von Joerg Wunsch (Gast)


Lesenswert?

Das command.com von MS-DOS (und damit Win9x, die ja nur ein
aufgebohrtes MS-DOS sind) kann leider stderr nicht umlenken.

Mit dem cmd.exe von WinNT+ kannst Du Unix-mäßige EA-Umleitungen
realisieren:

make > log.txt 2>&1

Damit bekommst Du dann auch die Fehlermeldungen ins Log.

Wenn die anderen Compiler void main(void); akzeptieren, dann
gehen sie vermutlich implizit von einem freestanding environment
aus.  (Ich möchte ihnen mal keine Nichtkonformität zum Standard
unterstellen. ;-)  Wäre natürlich interessant, inwiefern sie die
nur für hosted environments zulässigen Optimierungen (wie eben
strlen() auf einen konstanten String) dennoch realisieren...

von Josef Zimmermann (Gast)


Lesenswert?

Hallo

bezüglich der Probleme mit make werde ich dann wohl besser auf Linux als 
Entwicklungssystem umsteigen.

Logischerweise gehen diese Compiler (Keil, Tasking, etc.) von einem 
freestanding environment aus, weil es sich dabei um Cross-Compiler für 
Mikrocontroller (Einchip-Controller) handelt. Ob die Optimierung von 
strlen() funktioniert möchte ich bezweifeln. In der Regel werden diese 
Funktionen (string/stdio) erst vom Linker eingebunden. Ich habe das aber 
nicht getestet, sondern entnehme das der Doku. Wenn man aber weiss, dass 
nur ein konstanter String verwendet wird, sollte man besser sizeof 
benutzen.
Noch ein Wort zur Konformität. Gibt es überhaupt einen 100% 
normkonformen ANSI-C99 Compiler? Bei Cross-Compilern habe ich bisher 
noch keinen gefunden. Und wenn ich mich an vergangene Tests in der c't 
mit Borland/Microsoft, etc. erinnere haben auch diese ihre Abweichungen. 
Haufig ist es auch gar nicht sinnvoll/möglich diesen Standard zu 
erfüllen. Ich denke dabei an die Einschränkungen die man bei der 
Portierung eines Compilers für 8051-Controllern in kauf nehmen muss.

von Joerg Wunsch (Gast)


Lesenswert?

Der gcc sollte standardkonform sein, selbst in seiner Ausprägung
für den AVR (zumindest zu C89, zu C99 ist er es nicht).  Das
bezieht sich auf den Compiler selbst, bei der Library ist es
klar, daß diese Umgebung ihre Abstriche mit sich bringt.

Klar, strlen() würde auch beim gcc erst vom Linker eingebunden,
der Dreh ist aber eben, daß der Compiler die Funktionalität einer
Standardfunktion in einem hosted environment kennen darf und
entsprechend selbst optimieren.  Insofern halte ich eben einen
Compiler für einen Microcontroller, der von einer Bibliothek
begleitet wird, die sich am C-Standard orientiert, nicht mehr
für ein reines freestanding environment.  Es wäre andernfalls
ein Leichtes, -ffreestanding zum Default für avr-gcc zu machen
(das Gegenteil heißt -fhosted).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.