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

Volker Grabsch vog at notjusthosting.com
So Feb 4 13:45:56 CET 2007


On Sun, Jan 21, 2007 at 04:46:04PM +0100, Steffen Dettmer wrote:
> > > 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.

Was genau verstehst du unter "Unabhängig". Ich persönlich verstehe
darunter, dass ein Stück Software einen eigenständigen Zweck erfüllt
bzw. dass es sich um eine von sehr vielen Programmen gemeinsam benutzt
Bibliothek handelt.

Man muss hier sehr aufpassen, und muss aufpassen, *auf welcher Ebene*
man Wiederverwendbarkeit bzw. Modularität haben will.

> Das ist ja der Kernkonflikt. Macht man es unabhängig, wird Make
> dezentral (rekursiv) und weniger effizient.

Nein, das ist nicht der Kernkonflikt. Lange Bauzeiten sind ein kleiner
Aspekt, der ebenfalls nerven kann. Das war aber nicht das Kernthema des
Artikels. Dort ging es um Korrektheit, Zuverlässigkeit und einfachere/
sauberere Regeln. Es ging hauptsächlich darum, dass ein rekursives Make
mek nichttrivialen Abhängigkeiten sehr viele Hacks und unsinnige
Abhängigkeiten erfordert, die im *freundlichsten* Fall nur lange
Bauzeiten bedeuten. Im schlimmsten Fall gibt es falsche bzw. gar nicht
erfasste Abhängigkeiten.

Da du den Artikel offenbar noch nicht genauer angeschaut hast: Mach es
mal. Er ist wirklich lesenswert.
(zur Erinnerung:
    http://members.pcug.org.au/~millerp/rmch/recu-make-cons-harm.html
 ... erster Suchtreffer in Google mit den Suchbegriffen "recursive make")

> 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.

Dann ist vielleicht folgender Ergänzungs-Artikel interessant für dich:
    http://www.xs4all.nl/~evbergen/nonrecursive-make.html

Ein sehr schönes praktisches Beispiel:
    http://www.mindcontrol.org/~hplus/makesample.html


> 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.

Ich auch. Aber kann ein Modul, dass praktisch nur in deinen Apps
eingesetzt wird, tatsächlich "unabhängig" sein? Könntest du jedes
deiner "Module", auch wenn sie von mehreren Applikationen gemeinsam
genutzt werden, auch als eigenständige RPM-Pakete vertreiben?

Wenn ja, wäre das sinnvoll und macht ihr das auch?

"Teile und Herrsche" geht IMHO auch ohne rekursives Make ziemlich gut.

> Daher ist automake IMHO ein
> guter Kompromiss. Also, eigentlich kein so guter, hat überall Schwächen,
> aber ich kenne nichts Besseres.

Was ich beschrieben habe, geht auch mit Automake sehr gut. Das einzige,
was mich daran hindert, ein Unterverzeichnis als eigenständige Lib zu
compilieren und zu starten, ist ein billiges Makefile.am und eine sehr
kleine configure.ac. Diese beiden Dateien hinzuzufügen und das Ding
getrennt als Paket zu behandeln, das ist ne Sache von höchstens ner
halben Stunde (inkl. Testen).

Dieser Aufwand ist einmalig und kann jederzeit bei Bedarf erfolgen.

Macht man das zu früh, handelt man sich längere Build-Zeiten und
aufwändigere Wartung ein. Das ist einer der Hintergründe dieser Python-
Richtlinie: Solange das Modul nur in wenigen Applikationen verwendet
wird, sollte es mit diesen jeweils zusammen vertrieben werden. Erst,
wenn es *wirklich* eigenständig genutzt wird, auch von völlig anderen
Personen und Projekten, dann ist es sinnvoll, das Ding als extra Paket
zu vertreiben.

> > > 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!),

Finde ich gut. So muss es sein.

> 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"
> :)).

Versteh ich nicht. Wo ist das Problem?

Das eingebundene Makefile ist schließlich nicht dazu da, das Modul
eigenständig in eine Shared-Library umzuwandeln, oder? Wenn dem so
wäre, wär das Ding schon ein eigenständiges Paket und nicht mehr
Bestandteil des Pakets "app1".

Ich meine, das Makefile (bzw. Makefile.am.inc) muss doch lediglich
dafür sorgen, dass es auch vom Haupt-Makefile.am der "app2/" und "app3"
mit eingebunden werden kann.

Das heißt, entweder "internes Modul" oder "externes Modul", wobei die
meisten Module wohl intern (also nur von app1, app2, app3) gebraucht
werden, während nur gaaanz wenige tatsächlich "externe Module" sind,
also eigenständige Pakete vertrieben werden.

> Wäre mir neu, wenn ein automake ein automake includen kann (und natürlich
> am Ende was sinnvolles rauskommt!!!

Das meinte ich auch nicht, und das finde ich auch nicht sinnvoll.
Entweder ist das Modul bestandteil der Pakete für app1, app2 und app3,
oder es ist ein eigenständiges Paket.

Wozu musst du beides gleichzeitig haben? Auf den C++-Code hat es
keinerlei Auswirkung. Und der Sprung von einem internen Modul zum
eigenständigen Paket ist ein einmaliger, kleiner und sehr seltener
Aufwand, rechtfertigt also keinen ständigen höheren Wartungsaufwand.

Wer weiß, vielleicht müsste das Modul eh noch eine ganz andere API
kriegen, wenn es für projekt12 wiederverwendbar sein soll, das mit
euren bisherigen app1, app2 und app3 nichts gemeinsam hat.

Früher hätte ich mich auch auf jede globale Form der
Wiederverwendbarkeit eingerichtet. Und es ist ja auch nichts falsch
daran, gewisse einfache Grundsätze zu befolgen. Aber alles, was an
Aufwand darüber hinausgeht, gleicht IMHO der Verallgemeinerung aus
einem einzigen Beispiel. Modul1 wird nur in den eigenen App1, App2
und App3 eingesetzt, aber es wird ein Wartungs-Aufwand und Overhead
im Build-System betrieben, als ob es weltweit in hunderten von Projekten
eingesetzt wird. Das ist Wunschdenken. Es wäre eine großartige Leistung,
wenn auch nur ein einziges dieser Module dermaßen berühmt wird.

> 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?
[...]
> 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.

Das stimmt. Da ist eine gewisse Inkonsistenz. Ich muss auch zugeben,
dass For-Schleifen in Makefiles bei mir immer ein mulmiges Gefühl
verursachen, obwohl ich damit noch keine schlechten Erfahrungen gemacht
habe.

Trotzdem: Ich habe ein Verzeichnis, das nur aus einem "Makefile", der
generierten "crontab" und vielen (extern gepflegten) Teilstücken
"crontab-*" besteht. Das ist *sehr* übersichtlich, und erst seit einem
kleinen Refactoring der Fall.

Das möchte ich ungern mit unnötigen temporären Dateien zukleistern.
Da Make solche Dinger aber wieder löscht, wäre das tatsächlich ne
Alternative.

> > 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?

Du siehst, an welcher Stelle es fehlgeschlagen ist bzw. wieviel schon
korrekt gebaut wurde. Diese Zusatzinfo war für mich immer sehr
praktisch. Nicht unbedingt beim Compilieren von C-Programmen, obwohl
die die Ausgabe vom Kernel recht schick finde.

Nein, ich hatte z.B. ein Script, das verschiedene Sachen überprüft,
und nicht bei jedem Kleinkram, sondern bei jedem größeren Bereich ein
"echo" machte. Dieser grobe Kontext verliert sich leicht in den
letztendlichen Fehlermeldungen.

Manchmal ist dieser Kontext sogar wichtiger als die eigentliche
Fehlermeldung, und ich weiß schon bescheid, ohne die konkrete Detail-
Fehlermeldung zu lesen.

> 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.

Ein "Baue Modul X ..." fände ich sehr viel aussagekräftiger als einen
Prozentbalken. Die sind eh recht ungenau, und so vieles ich auch
manchmal beim Programmieren vermisse: Einen Build-Prozentbalken ganz
sicher nicht. ;-)

> > 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?

Ja, das meine ich ja. :-)

Aber irgendwie scheinen die meisten darauf zu stehen, von Make die
Konsole vollgemüllt zu bekommen.


Viele Grüße,

    Volker

-- 
Volker Grabsch
---<<(())>>---
Administrator
NotJustHosting GbR



Mehr Informationen über die Mailingliste linux-l