moin,
gibt es einen fachbegriff für sowas, ich meine gelesen zu haben,
compiler direktive, aber das denke ich ist nicht das was ich suche:
kann man irgendwo im makefile / in einer header datei etwas vorgeben,
sodass der compiler dann im code selbst dies oder jenes dann
verwendet, beispiel als ein header file mit define:
header:
#define voreinstellung beta
code:
if (voreinstellung== beta) dann printf("beta");
if (voreinstellung==release) dann printf("release");
ich würde gerne sowas im makefile machen wollen,
kann ich das genauso steuern? was muss ich im makefile angeben
kann ich da eine variable angeben und die im code verwenden,
wie muss ich das im code schreiben.
und, gibt es eine möglichkeit das als attribut z.B. in eclipse irgendwo
als vorlagen abzuspeichern, je nach dem was man aussucht,(beta,release)
macht dann make das oder jenes. hoffe es war verständlich gefragt.
danke
Timmo H. schrieb:> Im Makefile mit -D voreinstellung>> Aber im Code würde ich dann eher mit ifndef, ifdef etc abfragen
hallo Timmo,
vielen dank, kannst du mir ein kurzes beispiel gebenm bitte.
ich habe es so verstanden:
#ifndef voreinstellung==beta printf("release");
solange das nicht irgendwo mit beta vorbelegt ist, ist es ein release,
richtig?
wie meinst du das mit -D im makefile, da stehe ich auf dem schlauch.
kann ich im makefile ein "define" einfügen, dass im code berücksichtigt
wird?
danke!
c schüler schrieb:> Timmo H. schrieb:>> Im Makefile mit -D voreinstellung>>>> Aber im Code würde ich dann eher mit ifndef, ifdef etc abfragen>> hallo Timmo,> vielen dank, kannst du mir ein kurzes beispiel gebenm bitte.
Du weisst, was Preprozessor Makros sind?
> ich habe es so verstanden:>> #ifndef voreinstellung==beta printf("release");>> solange das nicht irgendwo mit beta vorbelegt ist, ist es ein release,> richtig?
Nein.
Du musst dich mal schlau machen, was es mit diesen # auf sich hat und
wer da dahinter steckt. Kurz, das ist der Preäprozessor.
Den kann man sich wie einen Texteditor vorstellen, der sich deinen
Programmtext als erstes vornimmt und der seine Kommandos (also das was
er tun soll) tricktreicherweise aus genau diesem Programmtext bezieht.
Und erst das Ergbenis davon, der Text der dabei entsteht, dieser Text
geht dann zum eigentlichen C-Compiler.
Die Kommandos an den Präprozessor, das sind genau die Zeilen, die mit
einem # anfangen.
Eine der Möglichkeiten des Präprozessor besteht darin, dass man ihn zb
anweisen kann, in weiterer Folge ein im QUelltext durch etwas anderes zu
ersetzen. So wie du das im Edito mit Suchen/Ersetzen machst. Nur das das
der Präprozessor bei jedem COmpilerlauf macht.
So etwas nennt man ein Makro.
Schreibst du
1
#define PI 3.141592654
2
3
intmain()
4
{
5
printf("%f\n",PI);
6
}
dann schnappt sich als erstes der Präprozessor diesen Text und findet
dabei den #define. Das ist genau die Anweisung an ihn: Wenn in weiterer
Folge im Programmtext irgendwo das Wort 'PI' steht, dann ersetzt du das
mit dem text '3.141592654'.
Und genau das macht der Präprozessor auch. Als Ergebnis entsteht dieser
neue Programmtext
1
intmain()
2
{
3
printf("%f\n",3.141592654);
4
}
und der macht genau das gewünschte.
>> wie meinst du das mit -D im makefile
das -D beim gcc macht nichts anderes als ein Makro zu definieren.
WEnn du im Programmtext
1
#define PI 3.141592654
schreiben kannst, dann kannst du genau das gleiche auch erreichen, indem
du den Präprozessor beim COmpileraufruf von der Commandline aus bittest,
dieses #define vorzunehmen.
Der Sinn der Sache ist es, dass man am eigentlichen C-Programm nichts
ändert, die Möglichkeiten des Präprozessors trotzdem ausschöpft, indem
man zb Makros im Code benutzt oder das Vorhandensein von Makros im
Präprozessor abfrägt um darauf aufbauen wieder andere C-Code Teile zu
compilieren oder vom compilieren auszuschliessen.
Aber: anstatt jetzt in irgendwelchen Files (meistens Header Files) die
entsprechenden #define zu haben, die die Makros definieren (oder eben
nicht definieren), gibt man dem Compiler beim COmpileraufruf schon mit,
welche Makros man haben will.
Das wird man natürlich nicht für alle Makros machen, aber gerade für
derartige Makros, die sich der Programmierer zb für Konfigurationssachen
ausgedacht hat, ist das schon eine praktische Sache, wenn man im
Makefile die Makros einstellt, anstatt in Header Files rumgraben zu
müssen.
https://www.mikrocontroller.net/articles/C-Pr%C3%A4prozessor
Hier hängt es vom VOrhandensein des Makros 'DEBUG_VERSION' ab, welcher
Code eigentlich compiliert wird. Gibt es das Makro, dann wird der erste
printf compiliert, gibt es das Makro nicht, dann eben der zweite.
Um das Makro zu kriegen gibt es 2 Möglichkeiten.
Entweder du definierst es in deinem Code
1
#define DEBUG_VERSION
2
3
intmain()
4
{
5
#ifdef DEBUG_VERSION
6
printf("Debug Version\n");
7
#else
8
printf("Release Version\n");
9
#endif
10
}
oder du weisst den gcc beim Aufruf (zb aus dem Makefile) an, er möge das
Makro als definiert ansehen
1
gcc ..... -DDEBUG_VERSION .....
Aber egal wie: Gibt es das Makro, dann bearbeitet der Präprozessor
deinen Code zu dem hier
1
intmain()
2
{
3
printf("Debug Version\n");
4
}
und schleust das durch den Compiler.
Gibt es das Makro für den Präprozessor nicht, dann bearbeitet er
folgerichtig deinen Code zu dem hier
1
intmain()
2
{
3
printf("Release Version\n");
4
}
und schleust das durch den C-Compiler.
Effekt: unterschiedliche Ausgaben, je nachdem ob ein bestimmtes Makro
definiert ist oder nicht.
DANKE!!! Karl Heinz!!!
~~~~~~~~~~~~~~~~~~~~~~
es muss also nicht zwingend ein header existieren
#define voreinstellung beta
und dort voreinstellung mit beta definiert stehen,es reicht aus, wenn
'voreinstellung' definiert wurde,bzw
wenn man im makefile -DBeta stehen hat, dann führt
#ifdef beta printf("beta version");
zur deren ausführung,
wenn man eine weitere wahl haben will,
muss man es mit '#' einäuten und kann dann schreiben
#else
..
#endif
ich glaube ich habe das auf anhieb verstanden?..
;-)
danke!
nachfrage:
wenn man mehrere -DSachen machen will,
kann man eine liste verwenden, oder schreibt man dann
-DBeta -DDebugInfos
oder
-DBeta + DebugInfos
oder
-DBeta DebugInfos
danke
extern compiler tool mit datenbank anbindung für registered user data
je nach grad ( registriert oder nicht ) wird das makefile individual
erstellt. also entweder mit -DREGKEY oder ohne und so die passende
'user' firmware ausgegeben.
Besten Dank an euch beiden! Ihr habt mir den richtigen Weg gezeigt!
Karl Heinz schrieb:> Halt die Dinge fürs erste erst mal einfach.
Oh Karlheinz, manchmal bist du des Teufels Advokat.
Ich hab genug Quellen vor die Nase gekriegt, wo oberschlaue
Programmierer mit solchen Defines auf der Kommandozeile hantiert haben,
so daß die Quelle an sich tatsächlich unübersetzbar ist.
Ich hasse sowas wie die Pest.
Nichts ist schlimmer, als 99 Quellen für 99 verschiedene Architekturen
in einer Quelle per #ifdef #elseif vereint zu haben und dann dort irgend
einen verdammten Fehler suchen zu müssen.
Also: ich rate von solchen Praktiken ab. Wenn irgend ein Projekt "beta"
ist, dann kann das auch so bleiben, bis es reif für's Release ist. Da
braucht man sowas nicht.
W.S.
W.S. schrieb:> Karl Heinz schrieb:>> Halt die Dinge fürs erste erst mal einfach.>> Oh Karlheinz, manchmal bist du des Teufels Advokat.>> Ich hab genug Quellen vor die Nase gekriegt, wo oberschlaue> Programmierer mit solchen Defines auf der Kommandozeile hantiert haben,> so daß die Quelle an sich tatsächlich unübersetzbar ist.
Das mag ich auch nicht.
Mit "einfach" war eigentlich der Link gemeint, den er da gepostet hat.
Da wird irgendeine Options-Datenbank besprochen (ich habs nicht genauer
studiert). Das war mit 'einfach halten' gemeint. Erst mal mit normalen
#define, ob jetzt in einem Header File oder im Makefile find ich jetzt
nicht so schlimm, solange es ein paar Varianten sind und nicht mehr.
> Nichts ist schlimmer, als 99 Quellen für 99 verschiedene Architekturen> in einer Quelle per #ifdef #elseif vereint zu haben und dann dort irgend> einen verdammten Fehler suchen zu müssen.
Da bin ich komplett bei dir.
Aber 2, 3 steuernde #define find ich nicht so schlimm.
Wie immer gilt: man kann alles übertreiben.
ich verstehe das, was ihr mir noch sagen wollt.
es bleibt bei maximal drei solcher kriterien.
eine davon wird dementsprechend formuliert oder nicht abhängig der
datenbank, ob der user registriert ist oder nicht.
und das fügt ein -DREGKEY dem makefile dazu oder nicht.
auf das kams mir jetzt mal an und es klappt so weit.
wenn ich aber viele solche kriterien habe zu entscheiden,
wird es unübersichtlich, und die makefile zeile wird sehr lange.
gibt es noch einen anderen sinnvollen ersatz weg falls es 10 oder mehr
werden?
mir war das wichtig, vom makefile aus 'zu steuern', und das hat mir
geholfen. ein -DREGKEY oder nicht, sagt, registriert oder demo.
super! danke nochmals!
Hallo,
ich würde tatsächlich eine c if Bedingung wann immer es geht vorziehen
Timmo H. schrieb:> Aber im Code würde ich dann eher mit ifndef, ifdef etc abfragen
der Vorteil ist, dass dann auch ausgeschalteten Code Teile durch den
Compiler mindestens mal auf den Syntax hin überprüft werden.
Und es wird auch die Rechtschribung überprüft.
DerDan schrieb:> ich würde tatsächlich eine c if Bedingung wann immer es geht vorziehen>> Timmo H. schrieb:>> Aber im Code würde ich dann eher mit ifndef, ifdef etc abfragen>> der Vorteil ist, dass dann auch ausgeschalteten Code Teile durch den> Compiler mindestens mal auf den Syntax hin überprüft werden.> Und es wird auch die Rechtschribung überprüft.>>>>
1
>if(release==1)
2
>{
3
>MachWasFuersRelease();
4
>}else{
5
>MachWasFuersBeta();
6
>}
7
>
8
>#defineRelease
9
>
10
>#ifdefRELEASE
11
>komischwirdnichtübersetzt(Rechtschreibfehler)
12
>#endif
13
>
14
>
gut ok, aber das steht dann auch im compilierten code drin,
oder? also wenn ich dann den asm code ansehe, habe ich da
ein compare mit zwei jmp sachen drin
wenn ich das über das makefile mache, dann bekommt der user/hacker
nur den code, den er auch bekommen soll
;)
oder?
Am besten testen.
Normalerweise werden nicht erreichbare Code Teile vom Compiler entfernt.
Meistens leider mit einer Warnung.
Außerdem stört unbenutzert Flash Speicher nicht unbedignt. Das Geld für
freien Speicher bekommst du vom Hersteller nicht zurück.
Wie immer muss man sich entscheiden, entweder wartbaren Code zu haben
oder Resourcen optimierten Code.
Mir ist wartbar lieber.
mfg
DerDan