[linux-l] Make und Ant (war: Warum gibt es keine einheitliche Dokumentation?)

Steffen Dettmer steffen at dett.de
So Jan 21 16:46:04 CET 2007


* Volker Grabsch wrote on Sat, Jan 20, 2007 at 17:57 +0100:
> On Thu, Jan 18, 2007 at 12:02:33AM +0100, Steffen Dettmer wrote:
> > vim z.B. kann make/gcc Fehler schön
> > parsen (leider zeigt er mir immer nur die erste Fehlerzeile an, weiss
> > nicht, wie man das korrigiert).
> 
> Das Problem hatte ich auch. Recherche im vim-Tutorial ergab: Man kann
> zwischen den verschiedenen Fehlern mit
>     :cn
> und
>     :cp
> navigieren. Sehr praktisch.

Ja klar, hatte ja neulich gepostet, dass das (mit <CR>) auf F4 bzw
Shift-F$ liegt. Aber pro Fehlereintrag (mit File:Line) zeigt er mir halt
leider nur die erste Fehlerzeile an. Das ist bei C ziemlich egal, aber
bei C++ meist ein Problem.

> > c) Mindestens ein Makefile je SCM Komponente ("Modul", "Package")
> 
> Okay, auch eine Methode. Aber doch nur, wenn die Modul *wirklich* in
> auch anderen Projekten verwendet werden, richtig?

Na gut, in meiner Praxis wird ein Modul immer in mindestens zwei
verwendet (auch weil wir etliche erst in eines refakturieren, wenn
Bedarf da ist :-)). Ist ja auch nicht überraschend. Einmal natürlich die
"grosse Applikation" für die es entwickelt wird, dann zum anderen ein
Testsystem (sind schon mal zwei), oft noch ein lib-system (schon allein,
damit man da ein "make distcheck" machen kann :)).

Das Problem ist ja, wenn es kein eigenes Makefile gibt, wirds evtl.
schwer, eines zu machen, weil sich Abhängigkeiten einschleichen. Rein
praktisch weiss ich sehr gut, wovon ich rede, ich habe viele viele
Manntage damit verbracht, sowas aufzulösen :)

> Innerhalb eines Moduls favorisierst du dann b). Teilst du das Wissen
> dann über mehrere Includes auf, oder hast du ein zentrales Makefile
> pro Modul?

ohne includes wird's kaum gehen, weil man z.B. für PDF Erzeugung mit
Doxygen+LaTeX oder so ja einen Regelsatz "fertig importieren" möchte.
Hab hier aber keine Erfahrungen, weil wir das automake nicht so benutzen
(und die multi-directory Features sind auch noch nicht sooo alt). Aber
klingt reizvoll. Geht bei mir nur wie gesagt rein praktisch nicht...

> > Da kann man dann oft sagen: Ein Makefile pro Untermodul. Da man
> > Untermodule machen soll (sind schliesslich nur logische
> > Verzeichnisstrukturen), hat man oft ein Makefile pro Verzeichnis
> > (welches Sourcen enthält).
> 
> Geht das nicht etwas zu weit? Ich meine, wenn diese Module sowieso
> nur innerhalb des Projektes existieren, wäre doch der Include-Ansatz
> viel sinnvoller, oder?

Nein, denn der include-Ansatz würde ja normalerweise nicht erlauben,
dieses Verzeichnis "unabhängig" zu bauen.

Das ist ja der Kernkonflikt. Macht man es unabhängig, wird Make
dezentral (rekursiv) und weniger effizient. Macht man es abhängig, wird
make gut und effizient (...), aber die Sourcen mit der Zeit automatisch
abhängig. Ist einfach so, dass passiert, erlebe ich wirklich ständig.

Ich persönlich bewerte den Vorteil "Unabhängigkeit" und "Teile und
Herrsche" (im Hinblick auf Refakturisierbarkeit, Wartbarkeit usw)
wesentlich höher als ein effizientes Make. Daher ist automake IMHO ein
guter Kompromiss. Also, eigentlich kein so guter, hat überall Schwächen,
aber ich kenne nichts Besseres.

> > Daher kann ich recht gut mit der automake-default-Idee leben, dass man
> > ein Makefile pro Verzeichnis hat.
> [...]
> > Verwendet man (nur, moderene, GNU-) Makefiles, kann man natürlich auch
> > sehr viel in make programmieren :) Auch includen etc. Allerdings legt
> > man sich da auch schnell die Karten (wenn man Makefiles automatisch
> > erzeugen muss). Da gibts eine Million Fallen. Mit automake haben wir es
> > zumindestens mit neueren Versionen immer irgendwie hingekriegt.
> 
> Moment. Mit scheint, du übersiehst die Möglichkeit, dass Automake auch
> selbst andere Automake-Dateien includen kann. 

Also, ich weiss, dass automake andere Makefiles includen kann. Dabei
included das automake die aber schon (also nicht make!), was einige
Nachteile hat (aber unterm Strich die Reproduzierbarkeit wohl ein bissel
vereinfacht, daher schützt dieser "Bug" wohl vielleicht ein bisschen vor
Dingen, die man nicht machen sollte und ist daher evlt. ein "Feature"
:)).

Diese includes sind aber schon statisch (also für make selbst kein
include mehr). Wie gesagt, kann man (meistens gut) mit leben.

Wäre mir neu, wenn ein automake ein automake includen kann (und natürlich
am Ende was sinnvolles rauskommt!!! also _SOURCES etc. funktioniert, was
ja so bei include-Makefiles schon schnell ein Problem wird, weil man
wegen der Macros aufpassen muss, schnell Reihenfolgeabhägigkeiten
reinkriegt etc).

Hast Du da einen Link und/oder ein Beispiel?

automake kann inzwischen ja sowas wie "SOURCES = subdir/file.c", aber
leider nicht in den Versionen, die ich auch unterstützen muss. Bei neuen
automake-Features bin ich seeeehr vorsichtig geworden :)

Einfache Makefiles sind oft einfach einfach :)

> > Da könnte man vielleicht noch bissel was machen, wenn man pattern
> > definieren kann. Also z.B. (ungetestet, bin mir bei $< und so nicht
> > sicher):
> > 
> > SOURCES = $(wildcard crontab-*.src)
> > HELPERS = $(patsubst %.src, %.tmp, $(SOURCES))
> > 
> > $(RESULT): $(HELPERS) Makefile
> > 	cat $(HELPERS) > $@
> > 	crontab $@
> > 
> > %.tmp: %.src
> > 	NAME=`echo "$$FILE" | sed "s,^crontab-,,"` ; \
> > 	... usw ...
> > 	sed "s, at NAME@,$$NAME,g ; s, at PWD@,$(REAL_PWD),g" \
> > 	# irgendwie $< statt $$FILE oder so:
> > 	$< > $@
> 
> Interessanter Ansatz. Das würde ich machen, wenn die Bash keine
> for-Schleife hätte. Aber wo liegt der Vorteil?

die .tmps werden nur erzeugt, wenn benötigt (insbeondere bei secondary)
UND vor allem ist es make und elegant :) 

In Deinem Beispiel hattest Du eine for-Schleife. Die andere für das
"test -nt" aber nicht, weil so lesbarer. Also doch entweder in beiden
Fällen for oder in keinem oder?

> Leichter verständlich ist es nicht wirklich, und er erzeugt viel mehr
> temporäre Dateien im Verzeichnis. Performance wird auch nicht gespart,
> da der "crontab"-Aufruf die meisten Resourcen frisst.
> 
> Worin siehst du den Vorteil dieser Variante?

Ich finde es leichter verständlich. Es ist halt regelbasiert lesbar. Ich
muss nur das lesen, was mich interessiert. Vergleichbar mit Funktionen
in Skripten - was ja meist in Makefiles nicht so gut geht, es sei denn,
man verunsichert den leser mit 
regel:
	. ./functions && dosomething ; \
	if func = 5 ; then \
usw. Das ist für mich oft vergleichbar mit altem embedded SQL Code:

int
func(int a, int b)
{
    SQL_INT RESULT;
    SQL_EXECUTE("? + ?", RESULT, a, b);
    return (int) RESULT;
}

lol sollte man natürlich in einer Sprache schreiben:

int
func(int a, int b)
{
	return a+b;
}

oder? :)

Zurück zu Makefile. Ich finde es also lesbarer.

Es gibt ein RESULT, dass wird aus HELPERS gemacht. Ganz einfach. Und als
cron installiert. Alles klar und geradeaus, finde ich.

Es gibt Quellen, die werden umgewandelt (das .tmp könnte man bestimmt
besser bennen, wenn man den konkreten Fall kennt). Das ist ja auch das,
was in der For-Schleife passiert, nur das es im Makefile auch genau so
da steht.

Wenn man statt HELPERS und .tmp was sinnvolles fände, wäre das deutlich
besser. Mir fällt auf, dass HELPERS und .tmp falsch ist. Entweder TMP
und .tmp oder HELPERS und .helper, sonst sieht Mensch den Zusammenhang
nicht gut. Besser wäre natürlich was aussagekräftiges :)

> > > > Diese tollen ant "tasks" sind IMHO eine Krankheit. Es gibt eine jar und
> > > > ein unjar task. Gut, make kommt mit Regeln, die viele Ausgaben erzeugen
> > > > auch nicht sooo einfach klar (bzw. der Mensch, der es nutzt nicht ;)),
> > > > aber es geht.
> > > 
> > > Man kann es mit ein wenig Mühe stark verbessern. Schade, dass es
> > > automake noch nicht kann. 
> > 
> > Was, jar? Kann es:
> > [...]
> 
> Du hast mich falsch verstanden: Es ging mir um die Text-Ausgabe von Make
> für den Menschen.
> 
 [...] 
> produziert. Man muss nur sicherstellen, dass im Fehlerfall der gesamte
> Befehl erscheint, nicht nur "CC  ..irgendwas.."  ... oder dass man
> dieses Verhalten durch eine Umgebungsvariable steuern kann:

Warum das denn? Wenn ich dem Makefile "traue", brauch ich das nicht
(wenn nicht, muss ich eh ALLES sehen). Meist hab ich ja Fehler in einem
.c File oder so. Da geht ja "make -s" schon. "make -s" kennen aber viele
nicht. Na, und wer vim oder so zum Compileraufruf nutzt, will kein -s,
weil vim das ja eh korrekt filtert (aber nur, wenn nicht -s, klar).

>     $ make bla.o
>         CC  bla.c
> 
>     $ make bla.o DEBUG=1
>     gcc -c bla.c
> 
> Ich hoffe, du weißt nun, was ich meine.

Ja, ich denke (aber nicht unbedingt wegen Deiner Beispiele ;))

> > > Seit ich das gesehen habe, bemühe ich mich ebenfalls, in Makefiles
> > > und Shell-Scripten für eine übersichtliche Ausgabe zu sorgen. Er
> > > bei wirklichen Fehlern braucht man Details.
> > 
> > Ja, da helfen aber auch Tools.
> 
> Das schon. Dennoch möchte ich alles, was gut gegangen ist,
> *übersichtlich* dargestellt bekommen. Das hat wirklich enorme
> Vorteile.  Ich habe festgestellt, dass diesen Zusatzaufwand mit den
> Silent-Optionen und echo-Befehlen im Nachhinein richtig Zeit spart.
> Weil man eben viel, viel schneller sieht, was los ist.

Find ich Quatsch. Was gut gegangen ist, interessiert mich eigentlich
überhaupt nicht. Also silent. Wenn aber ein Fehler auftrat, möchte ich
möglichst viele Details, z.B. auch, ob ein bestimmtes Submodul gebaut
wurde oder nicht und ob es Warnungen gab etc.

Verstehe nicht, wo silent plus echo Zeit spart?

Ich finde, entweder macht man ein "build" (erwartet Erfolg, will keine
Ausgaben etc) oder "entwickelt" (will Fehler genau sehen etc). Ersteres
hätte idealerweise einen Prozentbalken. Zweiteres erzeugt
menschenverständliche Ausgaben, die man mit einem Tool betrachtet (vim).
Find ich jedenfalls.

> Das ähnelt etwas der Diskussion über transparente Shells. Klar sieht
> das cooler aus. Genauso wie es cool aussieht, wenn ein make-Aufruf den
> ganzen Bildschirm voller Text malt. 

mmm... Ist es nicht cooler, wenn da steht CC file.c [OK] und in grün?
 
oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.





Mehr Informationen über die Mailingliste linux-l