Hallo Zusammen,
vorgestern habe ich im Brustton der Überzeugung Chopperhead erklärt, dass man natürlich gegen die "richtigen" Header (in dem konkreten Fall die Header aus media_build_experimental) bauen muss. Je länger ich darüber nachdenke, um so unsicherer werde ich mir, was denn die "richtigen" Header sind.
Ich kann mich erinnern, das es vor gaaaanz langer Zeit mal so war, dass man nach einem Kernel-Update ein make header_install gemacht hat, und dann die libc neu gebaut hat. Das target im Kernel-Source gibt es auch noch, und die Doku ebenso (linux-src/Documentation/make/headers_install.txt). Nur macht das heute keiner(?) mehr. Die Distributionen (hier gentoo) bringen ein Paket linux-headers mit, gegen das dann glibc (oder ulibc oder was auch immer der jeweilige Distributor für angebracht hält) gebaut wird (gentoo) oder - bei Binär-Distributionen) gebaut wurde (passend zum header-Paket).
Wie auch immer, es gibt also nicht mehr nur die kernel-Header, sondern ein generischeres Header-Paket (dass vermutlich auch irgendwie aus den mit make header_install exportierten Linux-Quellen gemacht wurde), das von glibc an aufwärts den gesamten Userspace glücklich macht. Die Kernel-Doku sagt, dass diese Headers rückwärts- aber nicht vorwärtskompatibel sind, also mit alten Headern gebaute Progis mit einem neueren Kern (also neueren Kernel-Headern) noch laufen. Das erklärt auch, warum bisweilen die Version von (unter Gentoo) latest stable kernel und latest stable linux-headers auseinanderlaufen können. Klar, dass man mit älteren Headern neue Features nicht benutzen kann - klar aber auch, dass Programme bzw. die libc nicht nach jedem Kernel-Update neu gebaut werden müssen. Na, ja, oder vieleicht unter bestimmten umständen doch???
Ebenso klar ist mir, dass das alles nur für den Userspace gilt. Hier hat eben eine gewisse Entkopplung vom Kern stattgefunden, so dass jeder über den Weg libc und stdc (gcc) kernel-Features nutzen kann und solch lustige Dinge wie dynamisches nachladen von Programmcode hinbekommt. Für Treiber sieht das anders aus. Vereinfacht ausgedrückt findet hier das "dynamische Nachladen von Programmcode" ja direkt in Interaktion mit de Kern statt (modprobe/insmod), und deshalb muss der Treiber ja auch die Kernel-Sourcen (bzw. Header) kennen (z.B. nvidia-Treiber).
Jetzt kommt ufo daher, und sagt sich, warum soll ich die Armen mit den alten Kernen eigentlich von meiner Treiberentwicklung ausschließen? (OT: Danke dafür!) Und macht einen "Backport". Die Treiber sind aber eben nicht im Userspace, und außerdem sagt die Kernel Doku ganz klar, dass die Header rückwärts-, aber nicht vorwärts kompatibel sind. Was bleibt also anders übrig, als für die gegen neue Header entwickelten Treiber auch MIT diesen neuen Headern zu bauen. Da diese aber Rückwärtskompatibel sind, sollten ja alle Programme die gegen die älteren Header gebaut sind noch laufen - solange sie keine neuen Features, die erst mit den neuen Headern implementiert wurden nutzen.
Alles was jetzt kommt ist deshalb besonders objectiv, weil es nicht von Fachwissen getrübt wird...
Der VDR benötigt gewisse Features des Kerns (hier eben der dvb-Treiber) und fragt deshalb die APIVERSION ab, und spielt eben nicht mehr weiter mit, wenn diese Unterschritten wird. Halbwegs aktueller Kern und linux-headers und alles ist gut. Wenn man dahinter liegt, nimmt man jetzt ufos Treiber, baut gegen die von den Treibern mitgebrachten Header, und es ist ebenfalls alles gut.
Hat man aber eine Kernel-Header-Kombination, die neu genug für vdr ist, will aber trotzdem ufos Treiber benutzen, welche Header sind dann die "Richtigen"? Ufos Header sind ja - nach Kernel-Doku-Definition - rückwärtskompatibel (also laufen Programme, die gegen ältere Header gebaut sind auch noch), und der vdr ist mit der APIVERSION der OS-Header zufrieden (also nutzt er ja keine Features, die seit dieser APIVERSION dazu gekommen sind - oder doch?), kann man das dann einfach so lassen?
Und was passiert wenn man jetzt Header mischt? Aus Sicht des VDR-Binaries: es ist gegen glibc mit alten Headern gelinkt, es benutzt aber selbst -I$(DVBDIR), und weil wir im Makeprozess nicht genügend wachsam waren, werden Plugins geladen, die über includes auf vdr-header-Dateien dvb-Treiber-Header includieren, die wiederum gegen den alten Headerstand laufen, weil das -I$(DVBDIR) nicht ins allerletzte unter/unter-Verzeichnis durch gereicht wurde. Und was ist mit der Auflösung der Dependencies? Mir ist erst nachdem ich die "# error: wrong DVBDIR"-Zeile in die (älteren) os-Header eingebaut habe afgefallen, dass ALLE(!) MAKEEDEP-Aufrufe ALLER(!) Plugins IMMER(!) gegen die alten Header laufen(*).
Ich hoffe irgendein Kernel-/C-/Make-Guru kann mir das erklären, weil ich die Zusammenhänge verstehen will.
Ganz pragmatisch bewegen mich diese Fragen:
- Ab welcher linux-Header-Version kann man -I$(DVBDIR) bei der Verwendung von media_build_experimental einfach weglassen? Kann man das überhaupt?
- Wenn man vdr gegen die neuen Header bauen muss (weil letzte Frage mit "nein" beantwortet, bzw. API-Version der installiert os-header nicht ausreichend), wie bekommt man -I$(DVBDIR) überall hin durchgereicht?(*)
Oder kurz: Was sind denn nun die "richtigen Header"?
Gruß, Ingo
(*) Ich habe bei mir ganz brutal in Make.config CXX += -I$(DVBDIR) gesetzt - dann klappts auch mit den MAKEDEP...