Einer der ersten Schritte jedes Freetz-Benutzers ist die Auswahl
der gewünschten Firmware (FW)-Konfiguration mit make menuconfig
. Die
Menükonfiguration (MK) ist mithin die primäre Benutzerschnittstelle
neben der Linux-Shell für alle Nicht-Entwickler. Fehler und
Unstimmigkeiten, welche dort auftauchen, können bestenfalls zu
Verwirrung und Fragen im IPPF
Freetz-Forum
führen, aber auch zu seltsamen Warnungen auf der Konsole nach dem
Speichern der Konfiguration, zu fehlenden oder überflüssigen
FW-Bestandteilen oder schlimmstenfalls zu Freetz-Boxen, die nicht mehr
booten oder in Reboot-Schleifen festhängen. In jedem Fall entsteht
Support-Aufwand. Am billigsten sind, gemäß dem agilen Mantra “fail
early”, jedoch Fehler, die frühestmöglich bemerkt werden oder am besten
gar nicht erst entstehen. Die Pflege der Menükonfiguration ist ein
wichtiger Qualitäts-Baustein unseres Projektes.
Pflichtlektüre jedes Entwicklers, bevor er zum ersten Mal die MK anpaßt, sollte die tools/kconfig/kconfig-language.txt sein. Dort werden Syntax-Features und deren Gebrauch grundlegend erklärt. Die Beschreibung entstammt der Dokumentation des Linux-Kernels, welchem wir (und auch andere quelloffene Projekte) diese Art der MK und die dazu notwendigen Werkzeuge entlehnt haben.
Die wichtigste Dateien und Make-Targets, mit welchen wir es im Folgenden zu tun haben werden, sind
source
-Direktive weitere MK-Definitionen, welche ebenfalls
Namen wie Config.in, externals.in o.ä. tragenmake menuconfig
zu verringern.make menuconfig
aufgerufen wird,
um die MK anzuzeigen und zu speichernmake tools
bzw. make kconfig-host
automatisch
gebaut, sobald es benötigt wirdmenuconfig-single
, welches die KM
als Baumstruktur ohne Unterseiten darstellt (manchmal nett, wenn
man die Gesamtstruktur sehen bzw. bearbeiten möchte)make tools
bzw. make kconfig-host
automatisch gebaut, sobald es benötigt wirdconfig
, oldconfig
,
oldnoconfig
, defconfig
, allnoconfig
, allyesconfig
,
` randconfig,
listnewconfig,
config-clean-deps und
config-clean-deps-keep-busybox` benutztzeigt folgende Hilfe an, wenn ohne Parameter aufgerufen (klappt Stand 15.10.2011 im Trunk, nicht in älteren Stable-Versionen, also frühestens ab Freetz 1.2):
Usage: tools/kconfig/conf [option] <kconfig-file>
[option] is _one_ of the following:
--listnewconfig List new options
--oldaskconfig Start a new configuration using a line-oriented program
--oldconfig Update a configuration using a provided .config as base
--silentoldconfig Same as oldconfig, but quietly, additionally update deps
--oldnoconfig Same as silentoldconfig but set new symbols to no
--defconfig <file> New config with default defined in <file>
--savedefconfig <file> Save the minimal current configuration to <file>
--allnoconfig New config where all options are answered with no
--allyesconfig New config where all options are answered with yes
--allmodconfig New config where all options are answered with mod
--alldefconfig New config with all symbols set to default
--randconfig New config with random answer to all options
Siehe vorerst Ticket #1532 “enhancement: Warnings im Zusammenhang mit neuem Kconfig (menuconfig) (closed: fixed)” , insbes. Kommentare Nr.
Ticket #1532 “Kommentar 10 für Ticket #1532”: Erklärung einer Warnung mit Vorschlägen zur Problembehebung
Diese unmet dependencies behebt am besten jeder so, wie der gerade drauf stößt. Es sind ja nur Warnings, aber die sind auch wichtig, damit wir Unsauberkeiten aus den Config.in heraus bekommen. Das ist also gut für die Projekthygiene. Ich gebe mal ein Beispiel:
warning: (FREETZ_PACKAGE_AUTOFS_NFS && FREETZ_PACKAGE_NFSROOT) selects FREETZ_MODULE_nfs which has unmet direct dependencies (FREETZ_KERNEL_VERSION_2_6_13_1 || FREETZ_KERNEL_VERSION_2_6_28 || FREETZ_KERNEL_VERSION_2_6_32)
Aha, hier hat also jemand (ich) NFS-Root ausgewählt. Klar, daß dazu auch das NFS-Kernelmodul ausgewählt werden muß. Jetzt hat dieser Jemand aber bspw. eine 7270_v1 mit Kernel 2.6.19.2. Das Problem liegt auf der Hand: Entweder sollte beim NFS-Modul dieser Kernel mit in die Dependencies-Liste, oder für diesen Kernel sollten alle NFS-relevanten Sachen deaktiviert werden. Alles andere ist ein Widerspruch, und der wird moniert von Kconfig. Was in diesem Fall sachlich zutreffend ist, weiß ich momentan nicht, dafür war ich zu lange zu weit weg von der Entwicklung.
Ticket #1532 “Kommentar 31 für Ticket #1532”: konkretes Beispiel einer von Alexander Kriegisch eingecheckten Problembehebung
Ich versuche es einfach statt in Prosa mal schematisch: :-)
::: {.code} FREETZ_PACKAGE_DAVFS2 select FREETZ_REMOVE_WEBDAV if FREETZ_HAS_AVM_WEBDAV
FREETZ_REMOVE_WEBDAV depends on FREETZ_HAS_AVM_WEBDAV FREETZ_HAS_AVM_WEBDAV depends on FREETZ_TYPE_FON_WLAN_7240 || ... :::
Das sieht mir sauber genug aus, obwohl das “if FREETZ_HAS_AVM_WEBDAV” - da gebe ich Dir recht - in Deinem Sinne doppelt ist. Aber es sagt dafür genauer, was Du wirklich tun willst (man kann die Konfigurationsanweisung diesmal wirklich wie Prosa lesen): Wähle den Remove-Patch aus, falls es überhaupt etwas zu entfernen gibt. Ich denke, das macht es hinreichend klar und dokumentiert nochmals, was gewollt ist. Zudem vermeidet es die Warnung nach dem Speichern der Konfiguration. Ohne das If würde die Warnung erscheinen.
Ticket #1532 “Kommentar 54 für Ticket #1532”: verallgemeintertes “Kochrezept” zur Problembehebung bei Remove-Patches
Ich weise nochmals auf meinen Kommentar #31 hin, aus dem man im Grunde sehr schön ablesen kann, wie einfach, elegant und lesbar man viele Situationen beheben kann:
::: {.code} FREETZ_PACKAGE_FOO select FREETZ_REMOVE_MY_FEATURE if FREETZ_HAS_AVM_MY_FEATURE
FREETZ_REMOVE_MY_FEATURE depends on FREETZ_HAS_AVM_MY_FEATURE FREETZ_HAS_AVM_MY_FEATURE depends on FREETZ_TYPE_A || FREETZ_TYPE_B || ... :::
Kochrezept für Remove-Patches (RP):
- Automatische RP-Auswahl absichern durch
if FREETZ_HAS_AVM_MY_FEATURE
- RP-Sichtbarkeit abhängig machen durch
depends on FREETZ_HAS_AVM_MY_FEATURE
- Durch RP entfernbares Feature abhängig machen von Hardware oder Firmware usw. durch
depends on FREETZ_TYPE_A
Ticket #1532 “Kommentar 55 für Ticket #1532”: weitere Erläuterungen zur Umsetzung des Kochrezepts
Replying to oliver:
Wo ist der Sinn darin eine dependency herauszunehmen, die (bis auf wenige Fälle) richtig ist?
Jetzt habe ich mir den ersten Patch doch schnell mal angeschaut. Es ist weder korrekt, sie so drin zu lassen, wenn sie auch nur in wenigen Fällen falsch ist, noch, sie ersatzlos zu streichen, wenn unsinnige Optionen dafür in neuen, falschen Fällen angezeigt werden. Was hingegen Sinn (und etwas Mühe) machen würde, wäre, mein Kochrezept anzuwenden und neue Variablen FREETZ_HAS_AVM_AURA_USB, FREETZ_HAS_AVM_PRINTSERV und FREETZ_HAS_AVM_RUNCLOCK anzulegen. Die könnte FREETZ_HAS_USB_HOST ja von mir aus in den Fällen, wo es keine gegenteiligen Erkenntnisse gibt, automatisch auswählen. Sobald aber auch nur eine einzige Ausnahme bekannt ist, ist eine Box-Liste beim jeweiligen FREETZ_HAS_AVM_* zu hinterlegen. Die Remove-Patches sollten immer von FREETZ_HAS_AVM_* abhängen, nie von einem billigen Ersatz der nur fast immer funktioniert.
Das ist keine Kritik i.S.v. “das hättest Du aber vorher wissen sollen”, denn die Erkenntnisse sind ja relativ neu und m.E. ein Segen des neuen Kconfig. Ich will durch meine Hinweise den anderen Entwicklern Hilfe zur Selbsthilfe geben.
Ergänzung: Es ist auch sowas vorstellbar:
::: {.code} FREETZ_HAS_AVM_MY_FEATURE depends on FREETZ_HAS_USB_HOST && !(FREETZ_TYPE_A || FREETZ_TYPE_B) :::
So hält man die Boxen-Liste klein, indem man einfach klar sagt, was Sache ist. Es ist wieder fast wie Prosa lesbar: “Zeig das AVM-Feature X an, wenn die Box einen USB-Host hat, außer in den Ausnahmefällen A und B.”
Wir sehen einen Fehler wie diesen:
$ make menuconfig
Config.in.cache:4951: syntax error
Config.in.cache:4950: unknown option "xconfig"
Config.in.cache:4951:warning: prompt redefined
make: *** [menuconfig] Error 1
Gemäß Beschreibung in
Changeset r8466
gibt es zwei Wege, bei einem von make menuconfig
angezeigten
Syntax-Fehler schnell die fehlerhafte Stelle zu finden:
Config.cache.in
direkt zu der Fehlerzeile 4950 springen, die
auf der Konsole angezeigt wurde. Von dort aus rückwärts(!) suchen
nach INCLUDE_BEGIN
- voilà, dort steht der Dateiname, wo die
fehlerhafte MK zu finden ist.make menuconfig-nocache
aufrufen und die problematische Datei
(make/davfs2/Config.in) direkt von der Konsole ablesen:
$ make menuconfig-nocache
make/davfs2/Config.in:2: syntax error
make/Config.in:84: missing end statement for this entry
Config.in:851: missing end statement for this entry
make/davfs2/Config.in:1: invalid statement
make/davfs2/Config.in:2: unexpected option "bool"
make/davfs2/Config.in:3: unexpected option "select"
make/davfs2/Config.in:4: unexpected option "select"
make/davfs2/Config.in:5: unexpected option "select"
make/davfs2/Config.in:6: unexpected option "select"
make/davfs2/Config.in:7: unexpected option "select"
make/davfs2/Config.in:8: unexpected option "select"
make/davfs2/Config.in:9: unexpected option "default"
make/davfs2/Config.in:10: invalid statement
make/davfs2/Config.in:11: unknown statement "davfs"
make/davfs2/Config.in:12: unknown statement "WebDAV"
make/davfs2/Config.in:13: unknown statement "HTTP"
make/davfs2/Config.in:14: unknown statement "resources"
make/Config.in:199: unexpected end statement
Config.in:862: unexpected end statement
make: *** [menuconfig-nocache] Error 1
Gemäß tools/developer/kconfig.pygments.patch habe ich (Alexander Kriegisch, kriegaex) zunächst einen sog. Lexer für Pygments gebaut (siehe auch Pygments-Doku), welcher es ermöglicht, MK-Dateien mit Syntax-Hervorhebung zu versehen. Pygments wird von Trac, also dem System, auf welchem unser Wiki und der Repository Browser basieren, automatisch benutzt, sofern es installiert ist.
Trac erkennt den MIME-Typ einer Datei aber nur aufgrund der Endung
(also z.B. .py, .sh, .pl, .c, .h) oder aufgrund Infos wie
Shebang
oder Vi-/Emacs-Header, und das ist ein Problem bei MK-Dateien, da es
keine standardisierte Dateiendung im Allgemeinen und auch nicht bei uns
im Projekt gibt. Unsere einzige Chance ist es, den Wildwuchs an
Dateinamen (z.B. Config.in, external.in, standard-modules.in,
external.in.libs) so im Zaum zu halten, daß man mit Regex
Matching
die entsprechenden Dateien identifizieren kann. Das ist Stand heute
möglich, allerdings beherrscht Trac von Haus aus kein Regex Matching,
weswegen tools/developer/mime_map_patterns.trac.patch
notwendig wird. (Anm.: Bevor es Patch 2 gab, war es notwendig, in SVN
die Eigenschaft svn:mime-type
für jede MK-Datei manuell zu setzen, was
inzwischen zum Glück obsolet ist, aber auch nicht schaden würde.)
Auf unserem Webserver sind beide Patches nebst der notwendigen
Konfiguration in trac.ini
aktiv, so daß MK-Dateien aus dem
SVN-Repository automatisch mit Syntax-Hervorhebung versehen werden.
Noch ein kleiner Tip: Wie man Syntax Highlighting im Trac-Wiki direkt
in Code-Blocks einsetzt, sieht man hier direkt im Artikel für MK- und
Shell-Code: Entweder man erwähnt am Anfang des Code-Blocks mit führendem
Shebang den MIME-Typ (text/x-kconfig
, übrigens selbst erfunden und
kein allgemeiner Standard) oder das in trac.ini
konfigurierte
Schlüsselwort kconfig
, also in etwa so:
}
Oder so:
}