Linux et la portabilité. Un petit retour d'expérience de développeur.

Depuis 10 ans

Chip bug versus chip bug / Creative Commons By Oskay (Flickr.com) J'ai commencé, tranquillement, il y a 10 ans, le développement d'un logiciel sous linux. Il s'agit d'un interpréteur d'un langage que j'ai inventé et qui sert à faciliter les tests de protocoles. Lorsque vous avez, dans un système complexe, des équipements, ils sont généralement connectés entre eux. Ils se parlent, échangent des données, des programmes, dans des contraintes de temps et de volume et au travers de supports divers. Dans ces systèmes, certains équipements ne disposent que d'un port de communication, d'autres, plus centraux, reçoivent et gèrent des centaines de machines.

Or, pour de multiples raisons, il manquait un outil pour tester les échanges, pour s'assurer qu'ils sont corrects, qu'ils arrivent au bon moment, ... Soit parce que les machines qui sont connectées ne sont pas disponibles au moment où l'on en teste une, soit parce que les cas de tests sont difficiles à réaliser avec les vraies machines. Donc, il faut simuler.

Globalement, on écrit dans ce langage des scripts qui permettent de faciliter, plus que dans un langage classique de programmation, l'écriture des échanges de données. On peut, grâce à quelques lignes de code, simuler un point précis d'une machine, du point de vue de son comportement vis à vis de l'extérieur.

De nombreux clients me l'ont demandé sous Windows. Il fallait donc le porter. Et, par coïncidence, j'ai dû, depuis cinq ans, effectuer de nombreux portages de quelque chose vers Windows ou de Windows vers quelque chose.

Ceci est un bilan de ces différentes expériences. Il est intéressant puisque un logiciel ne fonctionnant que sur l'un des deux OS est, à terme, non viable.

Compatibilité du code source

Tout d'abord, tout est écrit en C. Le C de Microsoft (Visual Studio) est sans problème le même que GCC (de Linux ou de Windows). Par contre, les options de compilations par défaut, et notamment les « warnings », ne sont pas les mêmes. Attention aussi aux problèmes d'alignement et de « big endian » vs « little endian ». Surtout lorsque on échange des données entre deux systèmes hétérogènes. Tant que les logiciels qui se parlent sont dans le même monde, pas de souci.

Sur des milliers de lignes, seules 7 % nécessitent des adaptations. Le C, par la compilation conditionnelle, permet de garder des fichiers sources communs. Il faut noter que, tant que l'on reste dans la LIBC, Microsoft a fait un énorme effort pour fournir les mêmes API. Ils ont même poussé à fournir la couche « socket BSD » à la Linux. La gestion multi-thread reste « similaire » et la partie mulit-processus est galère. Attention aux gestion des signaux et IPC SV.

Il faut noter que nous avons porté par une chaîne de développement MinGW, qui est un portage de GCC et des libs sous windows. Cela a simplifié grandement.

Nous avions fait un essai avec Visual Studio 2008 : impossible au bout de 3 jours d'arriver à compiler. De même avec Visual 2005. Visual C 6, plus ancien, semblait plus apte à comprendre nos sources. Mais, dégoutés, nous nous étions rabattus sur MinGW. Il y a même un débogeur GDB avec dev-cpp. C'est presque comme sous Linux.

Le binaire, un peu moins

En 10 ans, j'ai eu des soucis de pérennité. Le premier avait été de Linux à Linux, le passage du 2.0 au 2.2 fut galère pour mon logiciel. Mais les points les plus importants sont liés au comportement de Windows sur la gestion des processus. Le slicing est plus « délicat » et nécessite une attention particulière. Le traitement du temps aussi nécessite une attention encore plus grande. Porter un logiciel qui gère la micro-seconde est impossible sous Windows de base, il faut mettre en oeuvre des librairies (notamment les timers multi-média).

Il reste que, de temps en temps, le système, même peu chargé, part en apnée et met le logiciel en difficulté sur des timeouts. Notamment sur des select() ou read(). Il semble ne pas vouloir réagir de suite.

L'environnement graphique et le pari GTK

La partie interface usager de ce logiciel est faite en GTK. Nous avions fait ce choix pour assurer la compatibilité lors du portage ultérieur. A part quelques menus soucis sur le multi-thread, la partie GTK est compatible, tant sur le plan des sources que du comportement. Le pari est gagné.

Les problèmes ne sont pas là où on les attend.

Et bien non. Une fois les sockets « adaptées », c'est à dire que les select(), read(), write(), ... sont conçus pour Windows, elles ont des comportements pas forcément équivalents que sous Linux. C'est surprenant.

Arrêter un processus par une de ces thread est particulièrement embêtant. Il faut presque penser le « main » comme une thread à part entière.

Bien sûr, nmake (le make de Microsoft) n'est pas compatible. Heureusement que MinGW fournit un make classique (qui sait gérer les ).

Sur une machine Linux, lorsque un processus tourne, il ne prend pas 100% du temps CPU. Sur une machine Windows, il faut le ralentir pour qu'il « rende » la main à Windows. Faites l'essai : un logiciel sur un boucle infinie qui déroule quelques instructions sans interaction avec l'OS. Il prendra 100% du temps CPU. Vous le ralentissez par une attente de quelques millisecondes, et il tombera à 5%. Surprenant.

Pour conclure, globalement, c'est faisable. Passer d'un monde à l'autre nécessite tout de même d'y avoir pensé au départ. Surtout si l'on fait le passage Windows vers Linux. Il nécessitera plus de travail que dans l'autre sens.

Michel

Vus : 494
Publié par G3L : 84