#!/bin/bash
v="0.1a"
arg=""
index=1
infile=""
outfile=""
hstr="usage: compile <mode> file <trailing>\n
- mode: -s=<std> ansi, c99 (default = none)
-x=<arg> set a argument manually (e.g. \"02\"
-o=<file> outputfile (default inputfile.c = outputfile)
-h show this message and exit
-v version and copyright
- inputfile(s) files only (suffixes .c and .h)
- trail trailing arguments
Example: compile -s=ansi -o=test1file testfile.c -lfoo -lbar"
vstr="$v (c) Anton Steiner, GPL v3.0 or later"
param1="-Wall -Wfloat-equal -Wshadow -Wpointer-arith -Wbad-function-cast \
-Wcast-qual -Wcast-align -Wstrict-prototypes -Wold-style-definition \
-Wmissing-prototypes -Wredundant-decls -Wunreachable-code"
if [ "$#" -eq 0 ]
then
echo -e "$hstr"
exit 1
fi
for arg in "$@"
do
ifp=0
case "${arg:0:2}" in
"-s") case "${arg:3}" in
"ansi") param2="$param1 -pedantic"
ifp=1 ;;
"c99") param2="$param1 -pedantic -std=c99"
ifp=1 ;;
* ) ifp=1 ;;
esac ;;
"-o") outfile="${arg:3}"
ifp=1 ;;
"-x") if [ "$param2" ="" ]
then
param2="$param1 ${arg:3}"
else
param2="$param2 ${arg:3}"
fi
ifp=1 ;;
"-h") echo -e "$hstr"
exit 1 ;;
"-v") echo -e "$vstr"
exit 1 ;;
* ) ;;
esac
if [ "${arg: -2}" = ".c" -o "${arg: -2}" = ".h" ]
then
if [ "$infile" = "" ]
then
of="$arg"
fi
infile="$infile $arg"
ifp=1
fi
if [ "$ifp" -ne 1 ]
then
trail="$trail $arg"
fi
let "index+=1"
done
if [ "$infile" = "" ]
then
echo "no Inputfile"
echo -e "$helpstring"
exit 1;
fi
if [ "$outfile" = "" ]
then
outfile="${of%\.c}"
fi
param3="$param2 -ggdb $infile -o $outfile $trail"
gcc $param3
-----
Vielen Dank und Servus
Anton
in a world without walls and fences - who needs windows and gates ?
IPA-member Linux Registered User # 178376 OE2AZM
oe2...@oevsv.at oe2...@yahoo.de
Ich hab ein Makefile, dass ich einmal zusammengebastelt und jetzt immer
anpasse. Ist praktisch, weil ich die GLib und/oder Gtk+ verwende, die
pkg-config brauchen (aber dafür auch nicht unbedingt den
autoconf-bloat). Vor allem aber kompiliert sich's damit schneller.
# Makefile
CC = gcc
APP = test
CFLAGS = `pkg-config --cflags glib-2.0` -Wall -ansi -pedantic
LDFLAGS = `pkg-config --libs glib-2.0`
SOURCES = file1.c \
file2.c \
main.c
OBJECTS = $(SOURCES:.c=.o)
all: $(APP)
$(APP): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.c.o:
$(CC) -c $(CFLAGS) $< -o $@
clean:
rm -f *.o $(APP)
tags:
ctags *.[ch]
> Ich habe deshalb ein Script gebastelt. Es funktioniert, aber
> vielleicht könnt ihr es einmal einer anschauen und paar Verbesserungs-
> vorschläge geben.
Fesch, fesch. Dein Skript gefällt mir. Vor allem erinnert es mich daran,
warum ich keine Shellskripte mehr verwende. Ausdrücke wie
> case "${arg:0:2}" in
sind zwar herrlich knackig, aber halt doch etwas schwer zu warten. Aber
ich weiß, dass es Spaß macht, sowas zu schreiben: Ich habe vor ein paar
Jahren "man bash" inhaliert. Doch später habe ich aber erkannt, dass
Shell-Skripte des Teufels sind, wenn sie esoterische Features benutzen
und länger als ein paar Zeilen sind. Trotzdem genier ich mich nicht,
dein Skript zu kommentieren:
- Die Namen param1, param2 und param3 gefallen mir nicht. Ich würde
ihnen entweder aussagekräftige Namen geben, oder nur eine einzige
Variable "param" verwenden. Die kann bei Bedarf verlängert werden:
PARAM="$PARAM -pedantic"
- Es war einmal Usus, Shell-Variablen nur mit Großbuchstaben zu
schreiben. Das schaut auch so herrlich antik aus.
- Nochwas zum Stil, diesmal Syntax und ebenfalls Geschmackssache:
Ich schreibe
if (foo) {
/* ... */
}
und deshalb auch jedes "then" und "do" in die gleiche Zeile:
if [ "$#" -eq 0 ]; then
# ...
fi
- Da du ohnehin /bin/bash verwendest, kannst du für die Argumente gleich
"getopts" verwenden. Hier eine halbgare getopts-Fassung deiner
Auswertungs-Routine. Ich verwende auch Funktionen und die Macht von
"cat << EOF":
#!/bin/bash
version ()
{
cat << EOF
(C) 2008 MeinName <i...@developers.developers.developers.com>
License: Microsoft Public License
EOF
}
usage ()
{
cat << EOF
usage: $0 [OPTIONS] FILE [FILES ...]
Dieses Skript kompiliert FILE und FILES und rettet die Welt
OPTIONS:
-h Show this message
-s C-Standard. can be 'ansi' or 'C99'.
-x Set arguments manually
-o Outputfile
-v Version and copyright information
EOF
version
}
STANDARD=
MORE_ARGS=
while getopts "hs:r:x:o:v" OPTION ; do
case $OPTION in
h)
usage
exit 0
;;
s)
STANDARD=$OPTARG
;;
x)
MORE_ARGS=$OPTARG
;;
o)
OUTPUTFILE=$OPTARG
;;
v)
version
exit 0
;;
?)
usage
exit
;;
esac
done
shift $(($OPTIND-1)) # $* auf restliche Argumente setzen
if [[ -z $STANDARD ]]; then
STANDARD="ansi"
fi
# usw. für andere Argumente
echo "C-Standard: $STANDARD"
echo "Argumente: $MORE_ARGS"
echo "Outputfile: $OUTPUTFILE"
echo "Dateien: $*"
Johannes
> Anton Steiner <Anton....@salzburg-online.at> wrote:
> Ich hab ein Makefile, dass ich einmal zusammengebastelt und jetzt immer
> anpasse.
> Vor allem aber kompiliert sich's damit schneller.
Für ein paar Projekte z.b. Treiber für einen USB-Blutdruckmesser vom
Hofer samt Frontend, die ich gerade in der Arbeit habe (Treiber
funktioniert, aber keine Angst, ich werde die Umwelt damit nicht
belästigen) verwende ich auch Make und Konsorten. Aber für jedes
kleine Programm das Makefile umbauen ist mir zuwider.
Einfach ein compile blahfasel.c ist für kleine Dateien schon fast zuviel.
>> Ich habe deshalb ein Script gebastelt.
> Fesch, fesch. Dein Skript gefällt mir. Vor allem erinnert es mich
> daran, warum ich keine Shellskripte mehr verwende.
Na, recht lang ist das Scripterl ja eh nicht und ein wüster Hack ist
es auch. Ich bin eigentlich kein Experte in bash.
> Trotzdem genier ich mich nicht, dein Skript zu kommentieren:
Danke. Ich hab das in ein paar Stunden hingeschmiert, was soll man bei
dem Regen sonst machen. Jetzt nicht sagen, du weißt wass besseres :-)
Ich bin ein alter Mann:
> - Die Namen param1, param2 und param3 gefallen mir nicht. Ich würde
> ihnen entweder aussagekräftige Namen geben, oder nur eine einzige
> Variable "param" verwenden. Die kann bei Bedarf verlängert werden:
>
> PARAM="$PARAM -pedantic"
Da werde ich nachhaken.
> - Es war einmal Usus, Shell-Variablen nur mit Großbuchstaben zu
> schreiben. Das schaut auch so herrlich antik aus.
Mh, meine Gewohnheit, nur Konstanten großzuschreiben.
> - Nochwas zum Stil, diesmal Syntax und ebenfalls Geschmackssache:
> Ich schreibe
>
> if (foo) {
> /* ... */
> }
Geschmackssache. Mir kommt es besser lesbar (auch in C und C++) vor,
wenn die einleitenden Klammer in der nächsten Zeile steht.
> und deshalb auch jedes "then" und "do" in die gleiche Zeile:
>
> if [ "$#" -eq 0 ]; then
> # ...
> fi
schaut besser aus, das werd ich ändern.
> - Da du ohnehin /bin/bash verwendest, kannst du für die Argumente gleich
> "getopts" verwenden. Hier eine halbgare getopts-Fassung deiner
> Auswertungs-Routine. Ich verwende auch Funktionen und die Macht von
> "cat << EOF":
cat vermeide ich, wenn es nicht unbedingt sein muß. Ich wurde schon
ein Mal wegen "useless use of cat" gesteinigt. Getopt ist mir bekannt,
ich habe aber gar nicht daran gedacht.
Servus und nochmals Danke
Anton
--
> Ich interessiere mich für C, übersetze mir öfter einmal Code-Schnipsel
> aus Tutorials und Newsgroups und schreibe auch manchmal auch manchmal
> kleine Progrämmchen (nur für mich), für die sich die Erstellung eine
> Makefiles nicht auszahlt.
Wenn keine besonderen Optionen gefordert und nur aus einem .c oder .cpp File
gebaut werden soll, funktioniert auch einfach:
make program
(wenn z.b. Datei program.c existiert) um das Programm zu bauen. (ohne dass
ein Makefile vorhanden ist)
> Andererseits geht mir das händische Eintippen von "gcc blahfasel..."
> auf die Nerven (ich möchte ja möglichst viele Warnungen einschalten
> bzw. auf ANSI ode C99 Standard prüfen).
export CFLAGS="-ansi -pedantic -Wall"
und wie oben bauen. LDFLAGS und CC wird natürlich auch berücksichtigt.
Bei auch leicht komplizierteren Setups (z.b. mehrere Dateien,
include-Pfaden, pkg-config usw.) ist ein Makefile oder sogar
automake/autoconf dann Pflicht, sonst ärgerst du dich wenn du es nach
einigen Jahren wieder bauen willst.
mfg Markus Raab
--
Linux, the choice | Für Konqi, Tux und GPL!
of a GNU generation -o) |
Kernel 2.6.6 /\ |
on a i686 _\_v |
Ein einfaches Makefile (war zu faul Dein Skript zu lesen, deshalb kenn
ich die Anforderungen jetzt leider nicht
----snip----
prog: prog.c
gcc <gewünschte Optionen> -o prog prog.c
----snip----
Makefiles schauen zwar oft kompliziert aus, aber wenn man eh nicht viel
braucht, sinds sehr einfach.
prog ist das Ding was erzeugt wird. Des heißt target. Das Kompilieren
wird nur gemacht, falls prog.c (eine Abhängigkeit) neuer ist als prog.
In der zweiten Zeile steht der Befehl zum Bauen. Wichtig ist, daß vor
dem gcc ein Tab steht, und zwar nur ein Tab.
Des schaut in Aktion bei mir so aus:
----snip----
grueni@sabi ~ > nano prog.c
grueni@sabi ~ > nano Makefile
grueni@sabi ~ > make
gcc -o prog prog.c
grueni@sabi ~ >
----snip----
Es lassen sich auch mehrere Targets definieren, die man dann mit
make <target> baut. Die Targets kann man auch in die Abhängigkeiten
einbauen. Zusätzlich werden Makefiles von vielen Editoren unterstützt
(z.Bsp. emacs, vi, ...).
Ich empfehle Dir Makefiles zu verwenden. Wenn Deine Anforderungen klein
sind, sind die Teile eh einfach und falls Deine Anforderungen höher
werden arbeitest schon mit einem guten Werkzeug.
viel Glück
Mario
Um Markus Raabs Posting anzuwenden (und obiges noch einfacher zu machen):
----snip----
CPPFLAGS=<gewünschte Optionen, die mit -I oder -D anfangen>
CFLAGS=<alle anderen gewünschte Optionen>
prog: prog.c
----snip----
Ja, das kann man noch schöner machen, aber für den Anfang reicht es mbMn.
Bernd
--
Bernd Petrovitsch Email : be...@bofh.at
"For I was talking aloud to myself. A habit of the old: they choose
the wisest person present to speak to; the long explanations needed
by the young are wearying." --- Gandalf, the White
> Anton Steiner <Anton....@salzburg-online.at> wrote:
>> ... für die sich die Erstellung eine
>> Makefiles nicht auszahlt...
>
> Ein einfaches Makefile (war zu faul Dein Skript zu lesen, deshalb kenn
> ich die Anforderungen jetzt leider nicht
> ----snip----
> prog: prog.c
> gcc <gewünschte Optionen> -o prog prog.c
> ----snip----
>
> Makefiles schauen zwar oft kompliziert aus, aber wenn man eh nicht viel
> braucht, sinds sehr einfach.
Nein, das sind sie nicht. Ich arbeite damit und habe mir make & Co
intensiv hineingezogen :-)
Was ich allerdings nich wusste, dass man einfach make ohne Makefile
aufrufen kann und es dann funktioniert (offensichtlich manpage doch
nicht so genau gelesen).
Das ist für Code Schnipsel ideal.
Der Sinn hinter meinem Script war nicht, es bei größeren Programmen
einzusetzen, sondern eben nur bei kleineren Codeschnipseln mit
verschiedenen Bedingungen (z.b. einmal mit Std99 oder 89, mit dem
verschiedenen Versionen von gcc usw.) ohne jedes Mal das Makefile zu
ändern zu müssen. Es war vielleicht keine so gute Idee, aber ich hab
das Script weiter gebaut und geändert und es funtioniert zu meiner
Zufriedenheit.
> Es lassen sich auch mehrere Targets definieren, die man dann mit
> make <target> baut. Die Targets kann man auch in die Abhängigkeiten
> einbauen. Zusätzlich werden Makefiles von vielen Editoren unterstützt
> (z.Bsp. emacs, vi, ...).
Ich benutze make, autoconfig, automake... und bei KDE verwende ich sowieso
kdevelop. Leider funktioniert ein make ohne Makefile aus emacs heraus
nicht.
> Ich empfehle Dir Makefiles zu verwenden. Wenn Deine Anforderungen klein
> sind, sind die Teile eh einfach und falls Deine Anforderungen höher
> werden arbeitest schon mit einem guten Werkzeug.
Wenn es ein bißchen größer wird, ist sowieso make erste Wahl.
Danke für die Ideen und
Servus
Anton
--