FR 2823871 A1 20021025 FR 0105385 A 20010420 adaptées pour obtenir un poids total de pommeau compris entre 80 et 200 g. 1 2823871 La présente invention concerne un procédé de génération du code exécutable d'un programme informatique. Plus précisément, I'invention vise un procèdé de génération du code exécutable d'un programme comportant plusieurs sous-programmes, ces sousprogrammes partageant, dans des contextes propres, différentes 1 0 ressources. Cette invention s'applique en particulier à la génération du code exécutable mis en _uvre dans un système numérique embarqué multifonctions, dans lequel différents sous-programmes réalisent des tâches de haut niveau en parallèle. C'est le cas par exemple des photocopieurs numériques de dernière génération, qui proposent, en sus de leur fonction première de photocopieur classique, des fonctions d'imprimante réseau, ou de serveur de fichiers. Ces sous-programmes partagent en effet différentes ressources, telles que la carte de connexion résaau, la mémoire ou le processeur, chacun avec ses contraintes propres, ou autrement dit dans un contexte d'utilisation propre. Le développement de tels systèmes, de plus en plus complexes, est traditionnellement réalisé en assemblant les différents sous-programmes précités, ces sous-programmes ayant été développés avec une connaissance limitée voire inexistante de leur contexte d'utilisation dans le système. L' intog ration de ces différents sous-p rog rammes est trad ition nel lement réalisée au sein d'une architecture en couches qui va maintenant être décrite en référence à la figure 1. La figure 1 représente un exemple typique d'architecture en couches d'une application logicielle, par exemple un système embarqué. 2 2823871 L'application logicielle représentée à la figure 1, comporte quatre couches, respectivement la couche matérielle, le système d'exploitation (Operating System ou a OS " en anglais), les librairies et les applications. Une telle représentation en couches, est connue de l'homme du métier. On rappellera néanmoins que le système d'exploitation inclut l'ensemble des mécanismes de partage des ressources telles que le réseau, la mémoire ou le processeur, cités précédemment. On rappellera également, qu'une couche donnse utilise les services offerts par la couche inférieure, typiquement par l'envoi de requêtes. Une couche donnée est donc susceptible de rencontrer, et donc d'arbitrer un conflit lorsqu'elle reçoit, de la part de couches supérieures distinctes, des requêtes incompatibles entre elles. Ces conflits sont traditionnellement gérés de manière implicite, par la mise en ceuvre d'un mécanisme d'arbitrage implémenté dans une librairie par exemple. Cette méthode de développement traditionnelle, qui permet avantageusement d'obtenir un bon niveau de réutilisation des différents sous- programmes, pose en revanche un problème d'optimisation des performances de tels systèmes. En effet, les différents sous-programmes constitutifs du système embarqué représenté figure 1, sont développés et compilés séparément, puis rassemblés au moment de l'édition de liens dans un exécutable. Le mécanisme d'arbitrage, " enfoui " dans une librairie, implémente donc une politique générique de partage de ressource, c'est-à-dire une politique applicable pour toute configuration de couches. Cette politique n'est pas forcément la plus efficace pour une configuration donnée des couches, ou le nombre et les besoins des clients sont connus a priori. Une méthode, récemment décrite dans le document " Interface Compilation, Step towerd compiling program interfaces as languages " par D. Engler, et publiée dans le numéro " IEEE Transactions on Software Engineering 25(3), pp. 387-400, May/June 1999", permet d'intégrer, lors de la compilation d'un sous-programme, des informations relatives aux librairies utilisées par ce sous-programme. 3 2823871 Selon ce document, cette méthode permet d'associer à une librairie donnée, un " optimiseur-croisé " (" cross-optimizer " en anglais) permettant d'optimiser, le code d'un sous-programme client de cette librairie. La méthode exposoe dans le document précité, permet donc une première approche d'optimisation des sous-programmes clients, non plus pris isolément, mais considérés au sein d'un système complexe,en prenant en compte des informations associées aux librairies utilisées par ces clients. Cependant, certains problèmes ne sont pas résolus par la méthode décrite brièvement ci-dessus. Premièrement, cette méthode ne permet pas d'optimiser une librairie en fonction d'un de ses clients. Deuxièmement, cette méthode ne permet pas d'optimiser un sous programme pour satisfaire plusieurs besoins d'optimisation différents. Par exemple, lorsqu'une librairie est utilisoe par plusieurs clients, ce qui est en pratique souvent le cas, la méthode ne fournit aucun support pour optimiser la librairie en fonction des demandes de plusieurs clients, que ces demandes soient compatibles ou contradictoires les unes avec les autres. La présente invention propose une méthode et un cadre de spécialisation d'un système complexe constitué de différents sous-programmes, visant à résoudre les problèmes précités. Ainsi, la présente invention concerne, selon un premier aspect, un procédé de génération du code exécutable d'un programme comportant au moins une librairie et au moins un sous-programme client de la librairie, le client utilisant au moins une ressource informatique gérce par la librairie. Le procédé comporte les étapes suivantes: -obtention d'un contexte d'utilisation de la ressource par le client; - -vérification de la conformité du contexte d'utilisation de la ressource par le client visà-vis de règles de conformité prédéfinies d'utilisation de la ressource; déclenchement d'une première action correctrice en cas de non conformité du contexte d'utilisation. 4 2823871 Le procédé permet ainsi de vérifier de façon statique, c'est à dire avant l'exécution du code exécutable, que la ressource est utilisée selon des règles de conformité prédéfinies, et si besoin est. de déclencher une action correctrice. Ceci permet, en particulier, d'éviter des erreurs d'exécution. Selon une caractéristique particulière, le procédé de génération de code exécutable, dans lequel le programme comporte au mons deux sous programmes clients de la librairie, les clients partageant au moins une ressource informatique gérée par la librairie, comporte en outre les étapes suivantes: -vérification de la compatibilité des contextes d'utilisation de la ressource, associés respectivement aux clients, vis-à- vis de règles de compatibilité prédéfinies d'utilisation de la ressource; déclenchement d'une deuxième action correctrice en cas d'incompatibilité des contextes d'utilisation. Cette caractéristique particulière permet avantageusement, pour une librairie donnée, de gérer les conflits résultants d'optimisations contradictoires demandées par ses clients. Selon une autre caractéristique particulière, le procédé de génération de code exécutable comporte une étape d'optimisation du code exécutable de la librairie en fonction du contexte d'utilisation du client. Par exemple, les informations relatives d'une part au nombre de clients utilisant une ressource gérée par une librairie, et d'autre part aux contextes d'utilisation de cette ressource, peuvent être utilisées pour optimiser les mécanismes de cette librairie relatifs à la synchronisation et au partage de cette ressource. Selon une autre caractéristique particulière, le procédé de géné ration de code exécutab le comporte u ne étape d'optimisation d u code exécutable du client, en fonction d'au moins une librairie dont il est client. Ceci permet d'optimiser le code du client en fonction de plus d'une librairie, par exemple de façon itérative. 2823871 Selon une autre caractéristique particulière, le procédé de génération de code comporte une étape de recherche des dépendances entre les sous-programmes. Ceci permet d'établir et de mettre à jour une information globale associée à chaque sous-programme, constituée par l'ensemble des clients de ce sous-programme et par son contexte d'utilisation. Selon une autre caractéristique particulière, I'étape d'obtention du contexte d'utilisation comporte une sous-étape d'analyse du code source du client. Cette sous-étape d'analyse du code source permet de repérer automatiquement les ressources utilisées par ce client, et le contexte dans lequel elles sont utilisoes. Selon une autre caractéristique particulière, I'étape d'obtention du contexte d'utilisation comporte une sous-étape d'interprétation d'annotations du code source du client, les annotations étant soit dans le fichier source correspondant, soit dans un fichier séparé et associé au fichier source. Dans un mode de réalisation, ce fichier associé, porte par exemple le nom du fichier source, avec une extension différente. Ceci permet avantageusement de spécifier, par ces annotations, ie contexte d'utilisation d'une ressource par un sous-programme, ces spécifications étant fournies dans un fichier spécifique accompagnant le sous programme. Selon une autre caractéristique particulière, I'étape de déclenchement d'une première action correctrice, ou d'une deuxième action correctrice comporte une sous-étape d'alerte d'un utilisateur du procédé de génération de code. Ceci permet avantageusement, de présenter, aussi tôt que possible dans le cycle de génération de code exécutable, les conflits de partage de ressource au programmeur. Selon une autre caractéristique particulière, I'étape de déclenchement d'une première action correctrice, ou d'une deuxième action 6 2823871 correctrice, comporte une sous-étape de modification du contexte d'utilisation de la ressource par au moins un client. Par exemple, les contextes d'utilisation d'origine associés à différents clients utilisant une ressource, peuvent être avantageusement remplacés par un contexte d'utilisation de cette ressource, ce nouveau contexte d'utilisation étant un compromis entre les contextes d'utilisation d, origine. Selon une autre caractéristique particulière, I'étape de déclenchement d'une deuxième action correctrice comporte une sous-étape d'ajout d'une stratégie de partage dynamique de la ressource, la stratégie étant mise en _uvre au cours d'une exécution du code exécutable. Un mécanisme de verrouillage particulier peut par exemple être avantageusement implémenté dans une librairie gérant une ressource mémoire partagée, pour éviter des conflits de demandes de lecture/écriture de cette mémoire, par différents clients de cette librairie. Selon une autre caractéristique particulière, I'étape de déclenchement d'une deuxième action correctrice comporte une sous-étape de duplication de la librairie, et une sous-étape de modification d'au moins une copie de cette librairie en fonction d'un contexte d'utilisation de la ressource par un client. Cette duplication du code de la librairie est une solution permettant, par exemple, de résoudre un conflit d'utilisation d'une ressource par deux clients de cette librairie. Selon un deuxième aspect, I'invention concerne un dispositif de génération du code exécutable d'un programme comportant au moins une librairie et au moins un sous-programme client de la librairie, le client utilisant au moins une ressource informatique gérce par la librairie. Le dispositif est remarquable en ce qu'il comporte: - des moyens d'obtention d'un contexte d'utilisation de la ressource par le client; - des moyens de vérification de la conformité du contexte d'utilisation de la ressource par le client vis-à-vis de règles de conformité prédéfinies d'utilisation de la ressource; 7 2823871 -des moyens de déclenchement d'une première action correctrice en cas de n on conform ité d u contexte d' utilisation. L'invention vise aussi un support d'informations, éventuellement totalement ou partiellement amovible, lisible par un système informatique, remarquable en ce qu'il contient des instructions d'un programme d'ordinateur, permettant la mise en _uvre d'un procédé de génération de cde exécutable tel que décrit brièvement ci-dessus, lorsque ce programme est chargé et exécuté par un système informatique. L'invention vise aussi un programme d'ordinateur stocké sur un support d'informations, et comportant des instructions permettant de mettre en _uvre le procédé de génération de code exécutable tel que décrit brièvement ci-dessus, lorsque ce programme d'ordinateur est chargé et exécuté par un système informatique. L'invention vise aussi un système informatique, remarquable en ce qu'il comporte un dispositif de génération de code exécutable tel que décrit brièvement ci-dessus. Les avantages de ce d is pos itif de géné ration de code exécutable, du support d'informations, du programme d'ordinateur et du système informatique, découlent de ceux du procédé de génération de code exécutable tel que succinctement exposé plus haut, et ne seront par conséquent pas .. rappeles c'. D'autres aspects et avantages de la présente invention appara^tront plus clairement à la lecture de la description détaillée qui va suivre, cette description étant donnée uniquement à titre d'exemple non limitatif et faite en référence aux dessins annexés sur lesquels: - la figure 1, déjà décrite, représente un exemple typique d'architecture en couches d'un système embarqué; -la figure 2 représente les principales étapes d'un procédé de génération de code en conformité avec l'invention; -la figure 3 représente le graphe de dépendance correspondant aux sous-programmes du système embarqué de la figure 1, donné à titre d'exempie; 8 2823871 -les figures 4a et 5a, représentent respectivement des lignes du code source des sous-programmes App1 et App2 de la figure 1, en conformité avec l'invention; -les figures 4b et 5b, représentent respectivement des contextes d'utilisation des sous-programmes App1 et App2 de la figure 1, en conformité avec l'invention; - la figure 6 représente un contrat contenant des règles de conformité et de compatibilité, permettant de résoudre des conflits de gestion de ressources selon l'invention; -la figure 7 représente les modules fonctionnels d'un dispositif de génération de code selon l'invention; et - la figure 8 représente schématiquement un système informatique adapté à mettre en _uvre un procédé de génération de code selon l'invention. Dans la description qui va suivre, nous utiliserons les définitions suivantes: Client: On dira qu'un sous-programme " X " est client d'un sous programme " Y ", lorsque le sous-programme " X " utilise les services offerts par le sous-programme " Y ". Dans un modèle en couches, le sous-programme " X " appartient à une couche au dessus de celle du sous-programme " Y ". Librairie: On dira qu'un sous-programme " Y " est une librairie d'un sousprogramme " X ", lorsque le sous-programme " X " est un client du sousprogramme " Y ". Une librairie est aussi couramment dénommée " bibliothèque ". Contexte d'utilisation d'un sous-programme: toute information nécessaire pour optimiser la compilation de ce sous-programme. Cette information comprend en particulier les modalités d'utilisation de l'interface de ce sous-programme. L'obtention de ce contexte d'utilisation est explicitée ci après en liaison avec la définition du terme " optimiseur-croisé ". Information globale associce à un sous-programme: information co nstituée par l'ensem ble d es cl ie nts d' un sous-programme et par son contexte d'utilisation. 9 2823871 Oplimiseur-croisé d'une librairie "X" (" cross-optimizer " en anglais): extension de logiciel, (" plug-in " en anglais), chargée dans le compilateur au moment de la compilation de tout sous-programme " Y ", a Y " étant client de le librairie " X ". Il permet, d'une part, de modifier le code source du sous-programme " Y " afin d'optimiser les appels de fonctions au sein du sous-programme " Y ", et, d'autre part, de collecter, par exemle par analyse du code source du sous-programme " Y ", toute information nécessaire pour optimiser la compilation de la librairie " X ", c'est-à-dire son contexte d'utilisation. Optimiseur-propre d'un sousprogramme " X " (" self-optimizer " en anglais): extension de logiciel (" plug-in " en anglais) chargée dans le compilateur au moment de la compilation de ce sous-programme. Il permet de modifier le code source de ce sous-programme ou d'optimiser sa compilation, par exemple à partir de contextes d'utilisations collectés précédemment par I'optimiseur-croisé de ce sous-programme. Il appara'^t donc ici, que pour un sous-programme donné, les optimiseurscroisés des librairies de ce sous-programme doivent être mis en ceuvre avant les optimiseurs-propres de ces librairies, ce qui revient à traiter les différents sous-programmes dans un ordre tel que les clients sont traités avant les librairies. Contrat d'un sous-programme: Comme décrit ci-dessus, un optimiseur-propre permet d'optimiser un sous-programme, à partir de contextes d'utilisations propres à des clients de ce sous-programme. Le cadre de développement permet de spécifier, pour un sous-programme donné, un ensemble de règles de conformité et de compatibilité utilisées pour résoudre les conflits potentiels dus aux divergences de ces différents contextes d'utilisation. L'ensemble de ces règles est appelé contrat de ce sous-programme. La figure 2 représente les principales étapes E200 à E294 d'un procédé de génération de code suivant l'invention. Cette figure va être décrite en prenant à titre d'exemple la génération de code des sous-programmes App1, App2 et Lib1 du système embarqué décrit précédemment en référence à la figure 1. 2823871 La première étape E200 du procédé de génération de code est une étape de recherche de dépendance entre les sous-programmes. Les dépendances sont obtenues par un outil permettant de générer un graphe de dépendances entre les différents sous-programmes. Dans un mode préféré de réalisation utilisant le système Unix, I'utilitaire " makedepend " permet de générer un tel graphe. Le graphe de dépendance correspondant aux sous-programmes du système embarqué de la figure 1 est donné à titre d'exemple à la figure 3. Sur ce graphe, connu de l'homme du métier, chaque flèche représente une relation clienVlibrairie. Par exemple, les sous-programmes App1 et App2, sont tous les deux clients de la librairie Lib1. Cette étape E200 permet en particulier d'obtenir pour un sous programme donné l'ensemble des librairies utilisées par ce sous-programme. Ainsi, le sous-programme App2 utilisent deux librairies, Lib1 et Lib2. 11 appara^'t sur ce graphe de dépendances, que App1 et App2 sont des clients de Lib1, App2 étant en outre client de Lib2. L'étape E200 est suivie par une boucle constituée par les étapes E210 à E280, de génération du code des sous-programmes SP, ces sous programmes étant traités dans l'ordre des dépendances. Comme décrit précédemment en liaison avec la définition d'un " optimiseurpropre ", il est nécessaire de traiter les sous-programmes dans un ordre tel que les clients sont traités avant les librairies. Dans l'exemple de génération de code des sous-programmes App1, App2 et Lib1, les clients App1 et App2 seront donc traités avant Lib1. L'étape E210 permet d'assurer cet ordonnancement. Le premier sous-programme (SP) traité par le procédé est ainsi App1. L'étape E210 est suivie par une boucle constituée des étapes E220 à E240 de prise en compte, par le procédé, des librairies LlBj utilisées par App1. Au cours de l'étape E220, la première librairie LlBj utilisée par le sous-programme App1 est sélectionnée, soit Lib1. L'étape E220 est suivie par une étape E230 d'obtention du contexte d'utilisation des ressources gérées par la librairie Lib1 et utilisées par le sous-programme App1. L'obtention de ce contexte se fait par un optimiseur-croisé de Lib1, appelé Lib1.cross. Le fichier Lib1.cross est en effet chargé dans le compilateur au moment de la compilation du sous-programme App1, App1 étant client de la librairie Lib1. L'optimiseur-croisé de Lib1, procède, au cours de l'étape E230, à une analyse du code source de App1. Dans l'exemple décrit ici, les sous programmes sont écrits en langage C. Des lignes du code source de App1, contenues dans le fichier App1.c, sont données à la figure 4a. Le fichier App1.c comporte en particulier une ligne L40, identifiée par la syntaxe #pragma en C, cette ligne étant une directive de compilation permettant de spécifier un contexte d'utilisation, défini aux lignes L42 et L44, pour les ressources mémoire et CPU gérées par la librairie Lib1, paramétrables par les constantes BUFFER_SIZE et DEBUG. L'optimiseur-croisé de Lib1, Lib1.cross, par analyse de ces lignes L40, L42 et L44, obtient le contexte d'utilisation de ces ressources par le sous programme App1. Ce contexte d'utilisation est archivé dans un fichier App1.out représenté à la fiigure 4b. Le fichier App1.out comporte une ligne L50, d'en-tête d'une section (lignes L52 et L54), définissant le contexte d'utilisation, par le sous programme App1, des ressources gérées par Lib1. En variante, le contexte d'utilisation pourrait être obtenu par interprétation d'annotations contenues dans un fichier associé à App1. De retour à la figure 2,1'étape E230 est suivie par une étape E240 d'optimisation du sous-programme App1 en fonction de la librairie Lib1. L'optimiseur-croisé Lib1.cross peut, en effet, modifier le code source du sous programme App1, afin d'optimiser les appels de fonctions au sein de ce sous programme. 12 2823871 Dans l'exemple décrit ici, App1, n'utilisant qu'une librairie Lib1, la boucle constituée par les étapes E220 à E240 se termine. L'étape E240 est alors suivie par une étape E250, de vérification de conformité et de compatibilité du contexte d'utilisation des ressources utilisées par les clients SPj du sous-programme SP en cours de traitement. Dans i'exemple décrit ici, App1 n'ayant pas de cliet, l'étape E250 est sans effet. L'étape E250 est suivie par un test E260, dont le résultat est positif si les conditions de conformité et de compatibilité sont vérifiées. Lorsque le résultat du test E260 est négatif, ce test est suivi par l'étape E290 de déclenchement d'une action correctrice. Lorsque le résultat du test E260 est positif, ce test est suivi par une étape E270 d'optimisation du sous-programme en cours de traitement, soit App1, en fonction des contextes de ses clients SPj. Dans l'exemple décrit ici, App1 n'ayant pas de client, l'étape E270 est sans effet. L'étape E270 est suivie par une étape E280 de génération du code objet de App1, soit le fichier App1.o. Cette étape de génération de code est connue de l'homme du métier et ne sera pas décrite ici. L'ensemble des sous-programmes App1, App2 et Lib1 n'ayant pas été traité, la boucle constituée par les étapes E210-E280 n'est pas termince. L'étape E280 est donc suivie par i'étape E210, au cours de laquelle ie sous programme SP suivant App1, dans l'ordre des dépendances identifié à l'étape E200, est sélectionné. Dans l'exemple décrit ici, il s'agit du sous-programme App2. L'étape E210 est suivie par une boucle constituée des étapes E220 à E240 de traitement, par le procédé, des librairies utilisses par App2, soit Lib1 et Lib2. Cette boucle E220-E240 permet d'obtenir le contexte d'utilisation (App2. out) des ressources gérées par les librairies Lib1 et Lib2, et utilisées par le sous-programme App2. 13 2823871 L'obtention de ce contexte se fait, comme décrit précédemment, par les optimiseurs-croisés de Lib1 et Lib2, respectivement Lib1.cross et Lib2. cross. Ces optimiseurs-croisés sont en effet chargés dans le compilateur au moment de la compilation du sous-programme App2, App2 étant client des librairies Lib1 et Lib2. r Les fichiers App2.c et App2.out sont représentés respectivement aux figures 5a et 5b. En référence à la figure 5a, le fichier App2.c comporte en particulier une directive de compilation permettant de spécifier un contexte d'utilisation pour la ressource mémoire gérée par la librairie Lib1, paramétrable par la constante BUFFER_ALLOCATE. II comporte également une directive de compilation permettant de spécifier un contexte d'utilisation pour la ressource réseau gérée par la librairie Lib2, paramétrable par la constante TCP_TIMER. En référence à la figure 5b, le fichier App2.out, comporte deux sections définissant le contexte d'utilisation, par le sous-programme App2, des ressources gérées par Lib1 et Lib2. Ces sections sont obtenues respectivement par Lib1.cross et Lib2.cross, selon le mécanisme décrit cidessus en référence à la figure 4b. Les étapes E250 à E280, se déroulent, pour la génération du code de App2, App2.o, comme elles s'étaient déroulées pour la génération de App1.o. Elles ne seront donc pas à nouveau décrites. L'ensemble des sous-programmes App1, App2 et Lib1 n'ayant pas été traité, la boucle constituée par les étapes E210-E280 n'est pas terminée. L'étape E280 est suivie par l'étape E210, au cours de laquelle le sous programme SP suivant App2, dans l'ordre des dépendances identifié à l'étape E200, est sélectionné. Dans l'exemple décrit ici, il s'agit du sous-programme Lib1. L'étape E210 est suivie par une boucle constituée des étapes E220 à E240 de traitement, par le procédé, des librairies utilisées par Lib1, soit OS. 14 2823871 Ces étapes sont similaires aux étapes E220 à E240 décrites précédemment. Elles permettent en, particulier d'obtenir le contexte Lib1.out, grâce à l'optimiseur-croisé du système d'exploitation (OS), OS.cross. L'étape E240 est alors suivie par une étape E250, de vérification de conformité et de compatibilité du contexte d'utilisation des ressources utilisoes par les clients (App1 et App2) du sous-programme en cours de traitement (Lib1). Cette étape est effectuée par l'optimiseur-propre de Lib1, appelé Lib1. self, qui est chargé dans le compilateur au moment de la compilation du sous-programme Lib1. La conformité et la compatibilité de ces contextes d'utilisation est effectuée vis à vis d'un contrat, Lib1.rule, contenant des règles prédéterminées (R1, R2, R3) de conformité et/ou de compatibilité. Le contrat Lib1.rule est représenté à la fiigure 6. Les règles prédélinies dans le contrat Lib1.rule vont maintenant être explicitées. La première règle, R1, définit les règles d'utilisation de la ressource mémoire gérée par la librairie Lib1, paramétrable par la constante BUFFER_SIZE. Cette règle spécifie que les valeurs BUFFER_SIZE spécifiées par les différents clients de Lib1, doivent être cumulées (mot-clef " sum "),jusqu'à une limite égale à 64*1024 octets, cette limite correspondant à la quantité de mémoire maximale gérable par la librairie Lib1. Cette règle R1 constitue donc d'une part une règle de conformité, car elle déclenche une action correctrice si un client spécifie, dans son contexte d'utilisation propre, une valeur de BUFFER_SIZE supérieure à la limite précitée. Cette règle R1 constitue d'autre part une règle de compatibilité, car elle déclenche une action correctrice si le cumul des valeurs BUFFER_SIZE spécifiées par les clients de Lib1, dépasse cette limite. La règle R1 spécifie enfin une valeur de BUFFER_SIZE par défaut, 32 * 1024, pour les clients de Lib1, ne spécifiant pas dans leur contexte propre, de valeur pour BUFFER_SIZE, ce qui est le cas de App2. 1 5 2823871 La deuxième règ le, R2, d éfin it d'autres règ les d ' util isation de la ressource mémoire, gérée par la librairie Lib1 et paramétrable par la constante BUFFER_ALLOCATE. Cette règle spécifie que chaque client de Lib1 peut utiliser un pointeur de fonction d'allocation mémoire propre (my_alloc pour App2), à partir du moment o chaque client utilise une copie propre des variables globales de la librairie. La troisième règle, R3, définit les règles d'utilisation de la ressource CPU gérée par la librairie Lib1, et paramétrable par la constante 1 0 DEBUG. Elle constitue une règle de compatibilité, car elle spécifie que le code de la librairie Lib1 doit être dupliqué si des clients de Lib1 définissent des contextes d'utilisation différents pour ce paramètre. Au cours de l'étape E250 de la figure 2, I'optimiseur-propre de Lib1, Lib1.self, vérifie donc la compatibilité des contextes d'utilisation App1. out et App2.out vis-à-vis de Lib1.rule. Il appara^'t donc dans cet exemple deux conflits: -d'une part, le conflit sur le paramètre DEBUG nécessite de dupliquer le code de la librairie Lib1; et -d'autre part, le conflit sur le paramètre BUFFER_ALLOCATE nocessite de dupliquer les données globales de Lib1. Le résultat du test E260 qui suit l'étape E250 est donc négatif, à cause de ces deux conflits. Le test E260 est donc suivi par l'étape E290 de déclenchement d'une action correctrice. Une action correctrice selon l'invention peut comporter, entre autres: I'alerte d'un utilisateur, par exemple si le conflit ne peut pas être résolu par les règles prédéterminées; -la modification du contexte d'utilisation de la ressource par un client ou le remplacement de ce contexte d'utilisation par un nouveau contexte d'utilisation, ce nouveau contexte d'utilisation étant un compromis entre plusieurs contextes d'utilisation; 16 2823871 -I'ajout d'une stratégie de partage dynamique de la ressource, comme par exempie un mécanisme de verrouillage permettant d'éviter des conflits de lecture/écriture dans une mémoire partagée; et -la création d'une copie de la librairie. Parfois, le code de certaines librairies est considéré comme non modifiable et par conséquent, on s'interdit de faire des optimsations sur ce code. C'est en particulier le cas lorsqu'une librairie appartient aux parties les plus critiques du système d'exploitation (OS). De telles librairies peuvent néanmoins bénéficier du présent cadre de génération de code exécutable, en fournissant un optimiseur-croisé pour optimiser leur clients, et en déclenchant des actions correctrices en cas de conflit, comme l'arrét de la compilation avec alerte de l'utilisateur par exemple. Dans le cas présent, I'action correctrice consiste, en modifiant le fichier de compilation MF (" makefile " en angiais), à: -dupliquer la librairie Lib1, la copie de Lib1 étant appelée Lib1v2; et à -spécifier des règles de compilation de Lib1 et Lib1v2, permettant de satisfaire l'utilisation des ressources mémoire et CPU par les sous programmes App1 et App2, à travers les paramètres BUFFER_ALLOCATE et DEBUG. Par exemple, les lignes suivantes seront substituéçs à la ligne de compilation de Lib1.c dans le fichier de compilation: cc DBUFFER_SIZE=64*1024 -DB UFFER_ALLOCATE=N U LL \ -DDEBUG=ON Lib1.c-o Lib1. o cc -DBUFFER_SIZE=32*1024 -DBUFFER_ALLOCATE=my_alloc \ Lib1.c-o Lib1v2.o, Lib1.o et Lib1v2.o étant liés, lors de l'étape d'édition de liens non décrite ici, respectivement avec App1 et App2. L'étape E290 est suivie par un test E292 dont le résultat est positif lorsque le conflit n'a pas pu être résolu. Ce test est alors suivi par une phase 17 2823871 E294 d'arrêt de la compilation. Le programmeur peut alors modifier un sous- programme, un contexte d'utilisation ou une règle de résolution de conflit et * relancer le procédé de génération de code, (étape E200). Lorsque le conflit est résolu, le test E292 est suivi par l'étape E270 d'optimisation de Lib1 en fonction de ces clients App1 et App2. Par exemple, l'information relative d'une part au nonbre de clients utilisant une ressource gérée par une librairie, et d'autre part aux contextes d'utilisation de cette ressource, peut être utilisée pour optimiser les mécanismes de cette librairie relatifs à la synchronisation et au partage de cette ressource. L'étape E270 est suivie par l'étape E280 de génération du code de Lib1, selon les commandes de compilation insérées dans le fichier de compilation à l'étape E290. En résumé, ie procédé de génération de code permet effectivement. d'optimiser les librairies en fonction de leurs clients; et -de gérer les conflits d'utilisation de ressources. La figure 7 représente les modules fonctionnels d'un dispositif 70 de génération de code selon l'invention. Le dispositif de génération de code selon l'invention est constitué d'éléments matériels et logiciels, les éléments logiciels incluant les différents modules fonctionnels constitutifs du programme de génération de code exécutable en conformité avec l'invention. Selon un mode préféré de réalisation, ce dispositif est incorporé dans un système informatique, tel un micro-ordinateur, décrit ultérieurement en référence à la figure 8. Le fonctionnement de ce système informatique est commandé par un programme de génération de code selon l'invention, ce programme ayant préalablement été chargé dans ce système informatique. Le dispositif 70 comporte un module 71 de recherche des dépendances entre les sous-programmes. Ce module de recherche 71 permet en particulier d'obtenir, à partir d'un fichier de compilation MF, l'ensemble des librairies utilisées par un sous-programme donné. 18 2823871 Le dispositif 70 comporte un module 72 d'interprétation d'un fichier de compilation MF (" makefile " en anglais). Ce module permet en particulier de déclencher la compilation de chaque sous-programme. Dans un mode préféré de réalisation utilisant le système Unix, ce module d'interprétation 72 correspond à l'utilitaire " make ". Cet utilitaire est connu de l'homme du métier et ne sera pas décrit ici. " Le module 71 de recherche des dépendances et le module 72 d'interprétation d'un fichier de compilation (M F) constituent un pilote de compilation du dispositif 70. Le dispositif 70 comporte également un module de compilation 73 et un module 74 de représentation et de transformation de code. Ces modules permettent de traduire les instructions d'un programme source App1.c écrit en langage de haut niveau en code machine directement exécutable par un ordinateur. Le dispositif 70 comporte un module 75 de chargement dynamique de code. Ce module 75 de chargement dynamique de code permet en particulier de charger l'optimiseur-croisé Lib1.cross et l'optimiseurpropre Lib1.self respectivement pendant la compilation de App1.c et de Lib1.c. Le code chargé dynamiquement est capable d'interagir avec le module de compilation 73 et le module de représentation et de transformation 74 précités, afin de modifier le processus de compilation. Un compilateur comportant un tel module de chargement dynamique de code est appelé compilateur extensible. Le dispositif 70 comporte également des optimiseurs-croisés 76, chaque optimiseur-croisé 76, étant associé à une librairie. Un optimiseur-croisé 76, tel Lib1.cross, comporte un module 76a d'obtention d'un contexte d'utilisation (App1.out) et un module d'optimisation 76b. Le module d'obtention 76a d'un contexte d'utilisation (App1.out) prend en entrée la représentation du programme source (App1.c), générée par le moduie de représentation 74, et fournit en sortie le contexte d'utilisation (App1.out). En variante, le module d'obtention 76a peut également interpréter des annotations du programme source (App1.c) pour générer le contexte d'utilisation (App1.out). 1 9 2823871 Le module d'optimisation 76b permet de fournir, à partir du contexte d'utilisation (App1.out), des commandes d'optimisation pour le module 74 de représentation et de transformation de code du dispositif 70. Le dispositif 70 comporte également des optimiseurs-propres 77, chaque optimiseur-propre 77 étant associé à un sous-programme. Chaque optimiseurpropre 77, tel Lib1.self, comporte un module 77a devérification de conformité et de compatibilité des contextes d'utilisation (App1.out), vis-à-vis d'un contrat (Lib1.rule), tel que décrit précédemment en référence à l'étape E250. Un optimiseur-propre 77 comporte également un module 77b d'optimisation et de déclenchement d'une action correctrice. Ce module permet en particulier d'optimiser un sous-programme Lib1, à partir du contexte d'utilisation App1.out collecté par un optimiseurcroisé Lib1.cross associé à ce so us-prog ram me. 11 permet également de déclencher une action, déterminée par le module de vérification 77a, en cas de non compatibilité ou de non-conformité des contextes d'utilisation App1.out, App2.out vis-à-vis du contrat Lib1. rule. Ce module 77b de déclenchement d'une action correctrice permet en particulier de modifier le fichier de compilation (MF) ou la représentation du programme dans le compilateur, d'alerter l'utilisateur, de dupliquer une librairie, ou d'ajouter une stratégie de partage dynamique de la ressource. En référence à la figure 8, on va maintenant décrire un système informatique 1 adapté à mettre en _uvre un procédé de génération de code exécutable selon l'invention. Autrement dit, ce système informatique incorpore un dispositif de génération de code exécutable tel que décrit précédemment en liaison avec la figure 7. Selon le mode de réalisation choisi et représenté à la figure 8, un système informatique mettant en _uvre l'invention est par exemple un micro ordinateur 1. Le dispositif 1 comporte un bus de communication 102 auquel sont reliés: une unitécentrale 103 (microprocesseur), 2823871 -une mémoire morte 104, comportant un programme "Progr", - une mémoire vive 106, comportant des registres adaptés à enregistrer des variables modifiées au cours de l'exécution du programme précité, -un écran 108 permettant de servir d'interface avec l'utilisateur, à l'aide d'un clavier 110 ou de tout autre moyen, tel que par exemple une souris, -un disque dur 112, -un lecteur de disquette 114 adapté à recevoir une disquette 116, une interface de communication 118 avec un réseau de communication 120 permettant de recevoir des fichiers tels App1.c, MF, ou Lib 1. rule. Le bus de communication permet la communication entre les différents éléments inclus dans le système informatique 1 ou reliés à lui. La représentation du bus n'est pas limitative et, notamment, I'unité centrale est susceptible de communiquer des instructions à tout élément du micro ordinateur 1 directement ou par l'intermédiaire d'un autre élément du micro ordinateur 1. Le programme noté "Progr" permettant au système informatique 1 de mettre en _uvre l'invention, peut être stocké par exemple en mémoire morte 104 (appelée ROM sur le dessin) comme représenté sur la figure 8. Selon une variante, ia disquette 116, tout comme le disque dur 112 peuvent contenir des donnses codées ainsi que le code de l'invention qui, une fois lu par le système informatique 1, sera stocké dans le disque dur 112. En seconde variante, le programme pourra être reçu pour être stocké de façon identique à celle décrite précédemment par l'intermédiaire du réscau de communication 120. Les disquettes peuvent être remplacées par tout support d'information tel que, par exemple, un CD-ROM ou une carte mémoire. De manière générale, un support d'information, lisible par un ordinateur ou par un microprocesseur, intagré ou non au dispositif, éventuellement amovible, mémorise un programme mettant en _uvre le procédé de génération de code selon l'invention. 21 2823871 De manière plus générale, le programme pourra étre chargé dans un des moyens de stockage du dispositif 1 avant d'être exécuté. L'unité centrale 103 va exécuter les instructions relatives à la mise en _uvre de l'invention, instructions stockées dans la mémoire morte 104 ou dans les autres éléments de stockage. Lors de la mise sous tension, le programme de génération de code exécutable d'un programme d'ordinateur selon l'invention (Progr), ainsi que le fichier source (App1.c) dont le code exécutable doit étre généré, qui sont stockés dans une mémoire non volatile, par exemple le disque dur 112, sont transférés dans la mémoire vive RAM 106. La mémoire vive RAM 106 contiendra alors le code exécutable du programme de génération de code selon l'invention, ainsi que des registres pour mémoriser les variables nécessaires à la mise en _uvre de l'invention. Bien entendu, la présente invention ne se limite pas aux détails des formes de réalisation décrits ici à titre d'exemple, mais s'étend au contraire aux modifications à la portée de l'homme de l'art, sans sortir du cadre de l'invention. En résumé, I'invention décrite ici concerne un procédé et un dispositif de génération de code exécutable d'un programme d'ordinateur. Selon le mode de réalisation préféré, les étapes du procédé sont déterminées par les instructions d'un programme de génération de code selon l'invention, le procédé étant mis en _uvre lorsque ce programme est chargé dans un système informatique dont ie fonctionnement est alors commandé par l'exécution du programme. L'invention concerne également un programme d'ordinateur, particulièrement un programme d'ordinateur sur ou dans un support d'informations, adapté à mettre en _uvre l'invention. Ce programme peut étre sous la forme de code source, de code objet, ou de code intermédiaire entre code source et code objet tel que dans une forme partiellement compilée, ou dans n'importe quelle autre forme souhaitable pour implémenter le procédé de génération de code selon l'invention. Le support d'informations peut étre n'importe quelle entité ou dispositif capable de stocker le programme. Par exemple, le support peut 22 2823871 comporter un moyen de stockage, tel quiune ROM, par exemple un CD-ROM ou une ROM semi-conducteur, ou un moyen d'enregistrement magnétique, par exemple une disquette (floppy disc) ou un disque dur. D'autre part, le support peut-être transmissible tel qu'un signal électrique ou optique, et acheminé via un câble électrique ou optique, ou encore par radio ou tout autre moyen. Alternativement le support peut être un circuit intégré dans lequel le programme est incorporé, le circuit étant adapté pour exécuter le. ou pour être utilisé dans l'exécution du, procédé en question. 23 2823871 REVENDICATIONS 1. Procédé de génération du code exécutable d'un programme comportant au moins un sous-programme librairie (Lib1) et au moins un sous programme (App1) client de ladite librairie, ledit au moins un clent utilisant au moins une ressource informatique gérée par ladite librairie, caractérisé en ce qu'il comporte les étapes suivantes: -obtention (E230) d'un contexte d'utilisation (App1.out) de ladite ressource par ledit au moins un client (App1); -vérification (E250) de la conformité du contexte d'utilisation (App1.out) de ladite ressource par ledit au moins un client (App1) vis-à-vis de règles de conformité (R1) prédéfinies d'utilisation de la ressource; -déclenchement (E290) d'une première action correctrice en cas de non conformité dudit contexte d'utilisation (App1.out). 2. Procédé de génération de code exécutable selon la revendication 1, dans lequel le programme comporte au moins deux sous programmes (App1, App2) clients de ladite librairie (Lib1), lesUits au moins deux clients partageant au moins une ressource informatique gérée par ladite librairie, caractérisé en ce qu'il comporte en outre les étapes suivantes: vérification (E250) de la compatibilité des contextes d'utilisation (App1. out, App2.out) de ladite ressource, associés respectivement aux dits clients (App1, App2), vis-à-vis de règles de compatibilité (R1, R2, R3) prédéfinies d'utilisation de la ressource; -déclenchement (E290) d'une deuxième action correctrice en cas d'incompatibilité desdits contextes d'utilisation (App1.out, App2.out). 3. Procédé de génération de code exécutable selon la revendication 1 ou 2, caractérisé en ce qu'il comporte une étape d'optimisation (E270) du code exécutable de ladite librairie (Lib1) en fonction du contexte d'utilisation (App1.out) dudit au moins un client (App1). 4. Procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 3, caractérisé en ce qu'il comporte une 24 2823871 étape (E240) d'optimisation du code exécutable dudit au moins un client (App1), en fonction d'au moins une librairie (Lib1) dont il est client. 5. Procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 4, caractérisé en ce qu'il comporte une étape (E200) de recherche des dépendances entre lesdits sous-programmes (App1, App2, Lib1). 6. Procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 5, caractérisé en ce que ladite étape d'obtention (E230) dudit contexte d'utilisation (App1.out) comporte une sous étape d'analyse du code source (App1.c) dudit au moins un client (App1). 7. Procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 6, caractérisé en ce que ladite étape d'obtention (E230) dudit contexte d'utilisation (App1.out) comporte une sous étape d'interprétation d'annotations du code source (App1.c) dudit au moins un client (App1). 8. Procédé de génération de code exécutable selon la revendication 7, caractérisé en ce que lesUites annotations sont contenues dans un fichier associé audit au moins un client (App1). 9. Procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 8, caractérisé en ce que la première action correctrice comporte une sous-étape d'alerte d'un utilisateur dudit procédé. 10. Procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 9, caractérisé en ce que la première action correctrice comporte une sous-étape de modification dudit contexte d'utilisation (App1.out) de ladite ressource par ledit au moins un client (App1). 11. Procédé de génération de code exécutable selon l'une quelconque des revendications 2 à 10, caractérisé en ce que la deuxième action correctrice comporte une sous-étape d'alerte d'un utilisateur dudit procédé. 12. Procédé de génération de code exécutable selon l'une quelconque des revendications 2 à 11, caractérisé en ce que la deuxième action correctrice comporte une sous-étape de modification d'au moins un 2823871 contexte d'utilisation (App1.out, App2.out) de ladite ressource par au moins un desdits clients (App1, App2). 13. Procédé de génération de code exécutable selon l'une quelconque des revendications 2 à 12, caractérisé en ce que la deuxième action correctrice comporte une sous-étape d'ajout d'une stratagie de partage dynamique de ladite ressource, ladite stratégie étant mise en ceuvre au cours d'une exécution dudit code exécutable. 14. Procédé de génération de code exécutable selon l'une quelconque des revendications 2 à 13, caractérisé en ce que la deuxième action correctrice comporte une sous-étape de duplication de ladite au moins une librairie (Lib1), et une sous-étape de modification d'au moins une copie (Lib1, Lib1v2) de ladite au moins une librairie (Lib1) en fonction d'au moins un contexte d'utilisation (App1.out, App2.out) de ladite ressource par au moins un desdits clients (App1, App2). 15. Dispositif (70) de génération du code exécutable d'un programme comportant au moins une librairie (Lib1) et au moins un sous programme (App1) client de ladite librairie, ladit au moins un client utiiisant au moins une ressource informatique gérée par ladite librairie, caractérisé en ce qu'il comporte: - des moyens (76a) d'obtention d'un contexte d'utilisation (App1.out) de ladite ressource par ledit au moins un client; -des moyens (77a) de vérification de la conformité du contexte d'utilisation (App1.out) de ladite ressource par ledit au moins un client (App1) vis-à-vis de règles de conformité (R1) prédéfinies d'utilisation de la ressource; - des moyens (77b) de déclen chement d' u ne p rem ière action correctrice en cas de non conformité dudit contexte d'utilisation (App1. out). 16. Dispositif (70) de génération de code exécutable selon la revendication 15, dans lequel le programme comporte au moins deux sous programmes clients (App1, App2) de ladite librairie (Lib1), lesdits au moins deux clients partageant au moins une ressource informatique gérée par ladite librairie (Lib1), caractérisé en ce qu'il comporte: 26 2823871 -des moyens (77a) de vérification de la compatibilité des contextes d'utilisation (App1.out, App2.out) de ladite ressource, associés respectivement aux dits clients, vis-à-vis de règles prédéfinies (R1, R2, R3) de compatibilité d'utilisation de la ressource; - des moyens de déclenchement (77b) d'une deuxième action correctrice en cas d'incompatibilité desdits contextes d'utilisation (App1.out, App2.out). 17. Dispositif (70) de génération de code exécutable selon la revendication 15 ou 16, caractérisé en ce qu'il comporte des moyens d'optimisation (77b) du code exécutable de ladite librairie (Lib1) en fonction du contexte d'utilisation (App1.out) dudit au moins un client (App1). 18. Dispositif (70) de génération de code exécutable selon l'une quelconque des revendications 15 à 17, caractérisé en ce qu'il comporte des moyens d'optimisation (76b) du code exécutable dudit au moins un client (App1), en fonction d'au moins une librairie (Lib1) dont il est client. 19. Dispositif (70) de génération de code exécutable selon l'une quelconque des revendications 15 à 18, caractérisé en ce qu'il comporte des moyens (71) de recherche des dépendances entre lesdits sous-programmes (App1, App2, Lib1). 20. Dispositif (70) de génération de code exécutable selon l'une quelconque des revendications 15 à 19, caractérisé en ce qu'il comporte des moyens adaptés à la mise en _uvre d'un procédé de génération de code exécutable selon l'une quelconque des revendications 6 à 14. 21. Support d'informations, éventuellement totalement ou partiellement amovible, lisible par un système informatique, caractérisé en ce qu'il contient des instructions d'un programme d'ordinateur, permettant la mise en _uvre d'un procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 14, lorsque ce programme est chargé et exécuté par un système informatique. 22. Support d'informations selon la revendication 21, caractérisé en ce qu'il est un CD-ROM, ou un support magnétique, tel un disque dur ou une disquette. 27 2823871 23. Support d'informations selon la revendication 21, caractérisé en ce qu'il est un support transmissible, tel un signal électrique ou optique. 24. Programme d'ordinateur stocké sur un support d'informations, led it programme comportant des instructions permettant de mettre en _uvre le procédé de génération de code exécutable selon l'une quelconque des revendications 1 à 14 lorsqu'il est chargé et exécuté par un système informatique. 25. Système informatique, caractérisé en ce qu'il comporte un dispositif (70) de génération de code exécutable selon l'une quelconque des