Forum: Mikrocontroller und Digitale Elektronik c code beta, release je nach gesetzter auswahl compilieren


von c schüler (Gast)


Lesenswert?

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

von Timmo H. (masterfx)


Lesenswert?

Im Makefile mit -D voreinstellung

Aber im Code würde ich dann eher mit ifndef, ifdef etc abfragen

von c schüler (Gast)


Lesenswert?

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!

von c schüler (Gast)


Lesenswert?

https://www.freebsd.org/doc/de/books/porters-handbook/makefile-options.html

schimpft sich das was ich suche Optionen?

danke!

von Karl H. (kbuchegg)


Lesenswert?

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
int main()
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
int main()
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

von Karl H. (kbuchegg)


Lesenswert?

c schüler schrieb:
> https://www.freebsd.org/doc/de/books/porters-handbook/makefile-options.html
>
> schimpft sich das was ich suche Optionen?

Halt die Dinge fürs erste erst mal einfach.

mach einen Quelltext, der ja nach Vorhandensein eines Makros was anderes 
macht

1
int main()
2
{
3
#ifdef DEBUG_VERSION
4
  printf( "Debug Version\n" );
5
#else
6
  printf( "Release Version\n" );
7
#endif
8
}

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
int main()
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
int main()
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
int main()
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.

: Bearbeitet durch User
von c schüler (Gast)


Lesenswert?

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!

von c schüler (Gast)


Lesenswert?

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

von Timmo H. (masterfx)


Lesenswert?

Genau, aber beachte -Dbeta!  -DBeta. Gewöhn dir an Präprozessor 
Direktiven nur in Großbuchstaben zu schreiben, so wie von Karl Heinz 
gezeigt.

: Bearbeitet durch User
von c schüler (Gast)


Lesenswert?

DANKE!!! Euch beiden!!!
Also:

-DBETA -DDEBUGINFO
1
int main()
2
{
3
#ifdef BETA
4
  printf( "Beta Version\n" );
5
#else
6
  printf( "Release Version\n" );
7
#endif
8
9
#ifdef DEBUGINFO printf( " mit Debug Ausageb\n" );
10
#endif
11
12
}

von c schüler (Gast)


Lesenswert?

PERFEKT!

soeben ausprobiert:

-DREGKEY

1
/*  user.h
2
 *  
3
 *
4
 *
5
 */
6
7
#ifndef __USER_H__
8
#define __USER_H__
9
10
#ifdef REGKEY
11
#define regkey "registriert"
12
#else
13
#define regkey "demo"
14
#endif


programm:
1
void info(void) {
2
3
printf (regkey);
4
5
}
6
7
8
9
main() {
10
11
info();
12
..
13
14
..
15
16
17
}


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!

von W.S. (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von c schüler (Gast)


Lesenswert?

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!

von DerDan (Gast)


Lesenswert?

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.


1
if (release == 1)
2
{
3
  MachWasFuersRelease();
4
} else {
5
  MachWasFuersBeta();
6
}
7
8
#define Release
9
10
#ifdef RELEASE
11
komisch wird nicht übersetzt (Rechtschreibfehler)
12
#endif

von c schüler (Gast)


Lesenswert?

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
> #define Release
9
> 
10
> #ifdef RELEASE
11
> komisch wird nicht ü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?

von ;-) (Gast)


Lesenswert?

;-)

von DerDan (Gast)


Lesenswert?

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

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.