2010-06-06 5 views
1

Mon programme nécessite au moins Linux 2.6.26 (j'utilise timerfd et d'autres fonctionnalités spécifiques à Linux).Comment vérifier la version Linux avec Autoconf?

J'ai une idée générale comment écrire cette macro mais je n'ai pas assez de connaissances sur l'écriture de macros de test pour Autoconf. Algorithme:

  1. Run "uname --release" et la sortie du magasin
  2. de sortie de Parse et soustraire le numéro de version Linux (MAJOR.MINOR.MICRO)
  3. Comparer version

Je ne savoir comment exécuter la commande, stocker la sortie et l'analyser.

Peut-être qu'une telle macro existe déjà et qu'elle est disponible (je n'en ai trouvé aucune)?

Répondre

1

Sans aller trop loin et écrire des macros autoconf correctement (ce qui serait préférable de toute façon), n'oubliez pas que configure.ac est fondamentalement un script shell prétraité par m4. Vous pouvez donc écrire des commandes shell directement.

 
# prev. part of configure.ac 
if test `uname -r |cut -d. -f1` -lt 2 then; echo "major v. error"; exit 1; fi 
if test `uname -r |cut -d. -f2` -lt 6 then; echo "minor v. error"; exit 1; fi 
if test `uname -r |cut -d. -f3` -lt 26 then; echo "micro error"; exit 1; fi 
# ... 

Ceci est juste une idée si vous voulez le faire en évitant d'écrire des macros pour autoconf. Ce choix n'est pas bon, mais devrait fonctionner ...

Le meilleur moyen est le déjà suggéré: vous devriez vérifier les caractéristiques; Donc, disons dans un futur noyau timerfd n'est plus disponible ... ou changé quelque part votre code est cassé ... vous ne l'attraperez pas puisque vous testez pour la version.

modifier

Comme foof utilisateur dit dans les commentaires (avec d'autres mots), il est un moyen naïf de vérifier major.minor.micro. Par exemple. 3.5.1 échouera à cause de 5 étant lt 6, mais 3.5.1 vient après 2.6.26 donc (probablement) il devrait être accepté. Il y a beaucoup de trucs qui peuvent être utilisés pour transformer x.y.z en une représentation qui met chaque version dans son ordre "naturel". Par exemple. si nous attendons que x, y ou z ne soit pas supérieur à 999, nous pouvons faire quelque chose comme multiplier par 1000000 majeur, 1000 mineur et 1 micro: ainsi, vous pouvez comparer le résultat avec 2006026 comme Foof suggéré en commentaire (s) .

+1

Notez que l'exemple de code se casse pour les modifications de version majeure/mineure. :-) Par exemple. La version 3.5.25 du noyau Linux échouera deux fois. (Vous pouvez simplement combiner les versions majeures, mineures et micro en un seul numéro de version 'v = $ (uname -r | awk -F '[^ [0-9]] *' {{print (1000000 * $ 1 + 1000 * $ 2 + $ 3)} ') 'et comparez ce' $ v' à '2006026' pour un test un peu plus robuste.) – FooF

+0

Bien sûr, vous avez raison. C'était un exemple immédiat bon marché de la façon d'ajouter un test sur ces chiffres. Cela aurait dû être considéré comme une "démo d'outil", pas comme "un bon usage" des outils :) Je vais ajouter quelques mots sur – ShinTakezou

+1

(Notez que certaines versions de noyau ont une version micro supérieure à 99 - auparavant la version 1.3.100 et 2.1.132 (voir sous-répertoires de https://www.kernel.org/pub/linux/kernel/) Votre réponse éditée fonctionne toujours pour * vérifier contre 2.6.26 *, mais quelqu'un lisant votre code doit utiliser une pensée supplémentaire cycles qui se souviennent/soupçonnent le débordement de la version micro, et que quelqu'un puisse copier-coller la solution dans un contexte où cela ne fonctionne pas, bien sûr il est improbable que quelqu'un utilise sérieusement cette ancienne version du noyau. sur le sujet!) – FooF

5

Je pense que vous feriez mieux de détecter les fonctions spécifiques dont vous avez besoin en utilisant AC_CHECK_FUNC, plutôt qu'une version de noyau spécifique. Cela évitera également la casse si vous vous retrouvez à croiser dans le futur

+0

Cela ne fonctionnera pas pour moi, car la fonction Linux accepte les indicateurs dans functrion timerfd_settime() depuis la version 2.6.26 et je ne peux vérifier cela qu'à l'exécution. Une autre idée? – Goofy

+0

Voulez-vous dire qu'il accepte certains drapeaux de 2.6.26 qui n'existaient pas auparavant? vous pouvez vérifier l'existence de ces drapeaux en utilisant 'AC_CHECK_DECL', et si tout échoue, vous pouvez utiliser' AC_RUN_IFELSE' pour compiler et exécuter un programme de test afin de vérifier tout ce qui peut vraiment être testé uniquement au moment de l'exécution. – Hasturkun

+0

Oui, Linux prend en charge les indicateurs dans cette fonction depuis la version 2.6.26.AFAIR sur les anciens noyaux timerfd_settime() faield avec l'erreur EINVAL, quand des drapeaux ont été utilisés. Je vais essayer d'utiliser AC_RUN_IFELSE comme vous l'avez suggéré. – Goofy

2

Je vous suggère de ne pas vérifier le numéro de version de Linux, mais pour le type spécifique dont vous avez besoin ou la fonction. Qui sait, peut-être que quelqu'un décide de rétroporter timerfd_settime() à 2.4.x? Donc, je pense que AC_CANONICAL_TARGET et AC_CHECK_LIB ou similaire sont vos amis. Si vous devez vérifier les arguments de la fonction ou tester le comportement, vous feriez mieux d'écrire un programme simple et d'utiliser AC_LANG_CONFTEST([AC_LANG_PROGRAM(...)])/AC_TRY_RUN pour faire le travail.

Questions connexes