Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/06/2017, à 09:21

DonutMan75

[RESOLU] [C] librairie LRT absente ?

Bonjour à tous,
je lis actuellement le bouquin de Christophe Blaess sur le développement système sous Linux et je bloque sur l'utilisation des fonctions Timers temps réel. Typiquement, il s'agit des fonctions :

timer_create()
timer_settime()

Le man me dit que je dois inclure les headers suivants :

#include <signal.h>
#include <time.h>

et lier mon programme à la librairie "real time" grâce à l'option -lrt de gcc.

Or à la compilation, j'ai le message suivant :

$ gcc -lrt exemple-timer-create.c -o exemple-timer-create
/tmp/ccVDHfPg.o : Dans la fonction « main » :
exemple-timer-create.c:(.text+0x11b) : référence indéfinie vers « timer_create »
exemple-timer-create.c:(.text+0x13e) : référence indéfinie vers « timer_create »
exemple-timer-create.c:(.text+0x192) : référence indéfinie vers « timer_settime »
exemple-timer-create.c:(.text+0x1cc) : référence indéfinie vers « timer_settime »

Est-il possible que cette librairie ne soit pas installée par défaut sur Ubuntu (j'ai la 16.04 LTS) ?
Comment puis-je l'installer le cas échéant ?

Voici le source problématique, c'est un exemple didactique : le programme ne fait qu'armer deux timers successifs.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

int compteur = 0;


void gestion_usr1(int numero)
{
compteur++;
}

void gestion_usr2(int numero)
{
fprintf(stderr, "Compteur = %d\n", compteur);
compteur = 0;
}

int main(int argc, char *argv[])
{
long int frequence;
timer_t timer1, timer2;
struct sigevent event;
struct itimerspec itimer;
int result;

sscanf(argv[1], "%ld", &frequence);

fprintf(stdout, "- Armement du timer1 sur %ld Hz --> %f seconds\n", frequence, 1 / (double) frequence);

signal(SIGUSR1, gestion_usr1);
signal(SIGUSR2, gestion_usr2);

// Construction de l'event timer1
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGUSR1;

timer_create(CLOCK_REALTIME, &event, &timer1);

// Construction de l'event timer2
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = SIGUSR2;

timer_create(CLOCK_REALTIME, &event, &timer2);


// Mise en place des temporisations

itimer.it_value.tv_sec = 0;
itimer.it_value.tv_nsec = 1000000000/frequence;
itimer.it_interval.tv_sec = 0;
itimer.it_interval.tv_nsec = 1000000000/frequence;

timer_settime(timer1, 0, &itimer, NULL);


itimer.it_value.tv_sec = 1;
itimer.it_value.tv_nsec = 0;
itimer.it_interval.tv_sec = 1;
itimer.it_interval.tv_nsec = 0;

timer_settime(timer2, 0, &itimer, NULL);

// Boucle infinie
while (1)
	{
	result = pause();
	fprintf(stderr, "-> Signl %d recu...\n", result);
	}

}

Merci d'avance pour vos retours smile
Et bonne journée !


Donut.

Dernière modification par DonutMan75 (Le 15/06/2017, à 09:00)

Hors ligne

#2 Le 14/06/2017, à 09:55

bruno

Re : [RESOLU] [C] librairie LRT absente ?

Bonjour,

Est-il possible que cette librairie bibliothèque ne soit pas installée par défaut sur Ubuntu (j'ai la 16.04 LTS) ?

C'est même a peu près sûr. Quand on veut compiler une application qui fait appel aux fichiers d'en-tête d'une bibliothèque 'libtoto', il faut installer le paquet 'libtoto-dev' qui fournit ces fichiers.

À toi de voir quels sont les paquets Ubutnu qui fournissent les fichiers signal.h, timer.h, etc.

Hors ligne

#3 Le 14/06/2017, à 11:13

alduc31

Re : [RESOLU] [C] librairie LRT absente ?

Salut,

A la fin le -lrt :

gcc  exemple-timer-create.c -o exemple-timer-create -lrt

Asus UX325EA oled (i5-1135G7,16Go) avec Lunar 23.04 (base xubuntu modifiée)

Hors ligne

#4 Le 14/06/2017, à 22:37

DonutMan75

Re : [RESOLU] [C] librairie LRT absente ?

Bonsoir Bruno, Alduc31, bonsoir à tous,

merci pour ces précisions (et pour la correction de vocabulaire ^^).
En farfouillant un peu sur le net avec les mots clefs que vous m'avez passé, je suis tombé sur cet article : http://www.golinuxhub.com/2014/03/how-t … ly-in.html
et aussi sur la partie "édition de liens" d'un tuto OpenClassRoom : https://openclassrooms.com/courses/comp … -gnu-linux

Pour progresser un peu dans ma compréhension de la compilation, j'aimerais essayer de rajouter manuellement la bibliothèque manquante (sans passer par une commande magique) mais je me pose plein de questions.... (bon je me dis que c'est plutôt cool, c'est formateur)

En gros, le #include <time.h> sert (entre autres) à définir le prototype des fonctions de la bibliothèque. Ainsi au moment de la création du fichier objet exemple-timer-create.c --> exemple-timer-create.o le compilateur sait comment gérer l'appel de la fonction timer_create() même s'il ne sait pas ce que fait cette fonction... Est-ce correct ?

Ensuite, au moment de la création de lien, le compilateur saura à quoi fait référence timer_create() et saura quelles instructions exécuter ou tout du moins (s'il s'agit d'une bibliothèque dynamique), où trouver les instructions à exécuter.

Mais comment se fait-il que sur ma distribution j'ai bien le fichier de header time.h (dans lequel j'ai effectivement le prototype de timer_create) mais sans avoir la librairie associée qui est installée ?

Par ailleurs, des fichiers timer.h j'en ai toute une platrée :

$ locate --regex '^.*/time.h$' | wc -l
116

Le site que j'ai mentionné indique par ailleurs :

To install a library file you need to copy the file inside /usr/lib and then run ldconfig (as root)

Bon, le tuto d'OpenClassRoom indique qu'il faut plutôt copier ça dans /usr/local/lib/ mais quoiqu'il en soit je ne sais absolument pas où trouver ce fichier bibliothèque et une recherche Google ne donne rien de probant. Tout au plus suis-je tombé sur cette page de Source Forge m'indiquant... qu'il n'y avait aucun fichier pour ce projet ! Existe-t'il une banque de donnée fiable où on peut trouver ces bibliothèques ? Par ailleurs, ne faudrait-il pas les compiler avant de les placer telles quelles dans /usr/local/lib/ ?

Bon, je sens que ça m'amène assez loin de ma question initiale tout ça et je ne veux pas trop vous faire perdre votre temps sur des généralités comme ça ^^... du coup, est-ce que vous pourriez me conseiller un bon bouquin qui traite un peu de ces sujets là ?

Merci d'avance pour vos conseils (super utile sur ce forum !!) et bonne soirée à tous smile

Donut

Dernière modification par DonutMan75 (Le 14/06/2017, à 23:14)

Hors ligne

#5 Le 14/06/2017, à 22:49

DonutMan75

Re : [RESOLU] [C] librairie LRT absente ?

Par ailleurs, je viens de tester la bidouille suivante (qui n'a pas marché.....)

$ ldconfig -p | grep librt
	librtmp.so.1 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/librtmp.so.1
	librt.so.1 (libc6,x86-64, Système d'exploitation ABI : Linux 2.6.32) => /lib/x86_64-linux-gnu/librt.so.1
	librt.so (libc6,x86-64, Système d'exploitation ABI : Linux 2.6.32) => /usr/lib/x86_64-linux-gnu/librt.so
$ locate librt.so
/lib/x86_64-linux-gnu/librt.so.1
/usr/lib/x86_64-linux-gnu/librt.so
$ export LD_LIBRARY_PATH=/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH
$ echo $LD_LIBRARY_PATH 
/lib/x86_64-linux-gnu/:
$ gcc -lrt exemple-timer-create.c -o exemple-timer-create
/tmp/ccn00VFe.o : Dans la fonction « main » :
exemple-timer-create.c:(.text+0x11b) : référence indéfinie vers « timer_create »
exemple-timer-create.c:(.text+0x13e) : référence indéfinie vers « timer_create »
exemple-timer-create.c:(.text+0x192) : référence indéfinie vers « timer_settime »
exemple-timer-create.c:(.text+0x1cc) : référence indéfinie vers « timer_settime »
collect2: error: ld returned 1 exit status

Avez-vous une idée de pourquoi cela a échoué ?
En particulier, le fait que ldconfig connaisse le chemin vers librt.so m'incite à penser que la librairie est bien installée sur mon système non ?

Merci d'avance et bonne soirée smile

Donut

Dernière modification par DonutMan75 (Le 14/06/2017, à 23:07)

Hors ligne

#6 Le 15/06/2017, à 05:54

pingouinux

Re : [RESOLU] [C] librairie LRT absente ?

Bonjour,
As-tu essayé la suggestion de alduc31 en #3 ? C'est à mon avis le remède à ton problème ?

gcc  exemple-timer-create.c -o exemple-timer-create -lrt

Hors ligne

#7 Le 15/06/2017, à 07:06

DonutMan75

Re : [RESOLU] [C] librairie LRT absente ?

euh.... ah tiens oui....

$ gcc -lrt exemple-timer-create.c -o exemple-timer-create
/tmp/ccODtuQ6.o : Dans la fonction « main » :
exemple-timer-create.c:(.text+0x11b) : référence indéfinie vers « timer_create »
exemple-timer-create.c:(.text+0x13e) : référence indéfinie vers « timer_create »
exemple-timer-create.c:(.text+0x192) : référence indéfinie vers « timer_settime »
exemple-timer-create.c:(.text+0x1cc) : référence indéfinie vers « timer_settime »
collect2: error: ld returned 1 exit status
$ gcc  exemple-timer-create.c -o exemple-timer-create -lrt
$

Comment est-ce possible ce comportement différent selon que l'option est déclarée avant ou après les arguments ?
Il me semblait que sous Linux les options étaient généralement définie avant les arguments non ?
Exemple :

$ cp -R toto tata
$ ls -lrt *.txt

Le man de gcc indique lui aussi :

man gcc a écrit :

SYNOPSIS
       gcc [-c|-S|-E] [-std=standard]
           [-g] [-pg] [-Olevel]
           [-Wwarn...] [-Wpedantic]
           [-Idir...] [-Ldir...]
           [-Dmacro[=defn]...] [-Umacro]
           [-foption...] [-mmachine-option...]
           [-o outfile] [@file] infile...

Plus bas dans le man

man gcc a écrit :

You can mix options and other arguments.  For the most part, the order you use doesn't matter.  Order does matter when you use several
       options of the same kind; for example, if you specify -L more than once, the directories are searched in the order specified.  Also, the
       placement of the -l option is significant.

Encore plus loin :

man gcc a écrit :

       -llibrary
       -l library
           Search the library named library when linking.  (The second alternative with the library as a separate argument is only for POSIX
           compliance and is not recommended.)

          It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the
           order they are specified.  Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o.  If bar.o refers to functions
           in z, those functions may not be loaded.

           The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a.  The linker then uses
           this file as if it had been specified precisely by name.

           The directories searched include several standard system directories plus any that you specify with -L.

           Normally the files found this way are library files---archive files whose members are object files.  The linker handles an archive
           file by scanning through it for members which define symbols that have so far been referenced but not defined.  But if the file that
           is found is an ordinary object file, it is linked in the usual fashion.  The only difference between using an -l option and specifying
           a file name is that -l surrounds library with lib and .a and searches several directories.


Bref ça marche... et je ne comprends absolument pas hmm
Bref ça marche et j'ai compris pourquoi !

A noter que cela ne concerne apparemment pas la biblkiothèque pthread puisque que la compil ci-dessous a parfaitement fonctionné :

$  gcc -pthread exemple-pthread-create-2.c -o exemple-pthread-create-2
$

Le man (encore lui) dit à ce sujet

man gcc a écrit :

       -pthread
           Adds support for multithreading with the pthreads library.  This option sets flags for both the preprocessor and linker.

Enfin bref, merci à tous et bonne journée smile

Donut.

PS : avais-je raison de dire que si "$ ldconfig -p | grep librt" renvoyait quelque chose alors cela voulait bien dire que :
1) la librairie librt est bien présente sur la machine
2) le système (ld ?) sait où la trouver quand on lui demande de la lier via l'option -lrt ??

Dernière modification par DonutMan75 (Le 15/06/2017, à 07:23)

Hors ligne

#8 Le 15/06/2017, à 07:18

pingouinux

Re : [RESOLU] [C] librairie LRT absente ?

DonutMan75 a écrit :

Comment est-ce possible ce comportement différent selon que l'option est déclarée avant ou après les arguments ?

Ce n'était pas comme ça jadis. Actuellement, quand le chargeur rencontre une librairie, il ne l'utilise que s'il en a besoin à ce moment. Si les appels à des fonctions présentes dans cette librairie apparaissent plus loin, ils seront en "référence indéfinie".

Hors ligne

#9 Le 15/06/2017, à 07:25

DonutMan75

Re : [RESOLU] [C] librairie LRT absente ?

Oui d'ailleurs le "The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended." >>> c'est bien la première fois que je vois qu'on me recommande de ne PAS utiliser POSIX :'(

Je pense que ce fil de discussion est un parfait exemple de cas "RTFM", merci à vous tous pour votre patience et vos explications smile

Donut

Dernière modification par DonutMan75 (Le 15/06/2017, à 07:26)

Hors ligne