ibex-team / ibex-lib

IBEX is a C++ library for constraint processing over real numbers.
http://ibex-team.github.io/ibex-lib/
GNU Lesser General Public License v3.0
67 stars 51 forks source link

Using CMake for compilation #368

Open cyrilbouvier opened 5 years ago

cyrilbouvier commented 5 years ago

Ce ticket sert à discuter du changement de waf à CMake comme système de compilation d'Ibex, comme cela a été discuté aux IbexDays 2019.

Prérequis

Les questions auxquelles ils faut répondre avant de faire le changement:

Méthode

Je vois deux façon de procéder au changement:

  1. Faire une branche où l'on implémente tous et qu'on merge une fois que c'est terminé
  2. Faire des changements progressifs dans la branche develop en faisant coexister CMake et waf tant que les scripts CMake ne sont pas terminés.

Je pencherai plutôt pour la deuxième façon, car s'il les changements prennent du temps, le moment où il faudra merger risque d'être compliqué. La deuxième façon permettrai aussi d'ajouter progressivement des tests pour CMake dans Travis afin d'éviter les regressions par rapport au reste du code qui continuera à évoluer.

Features

Voic une liste des features que doit posséder le système de compilation (obtenue en regardant ce que propose la compilation via waf actuellement (./waf --help) et des discussions des IbexDays 2019). N'hésiter pas à compléter ou à en enlever si nécessaire. J'ai mis des :question: sur les features pour lesquels je ne sais pas si il faut les garder ou pas.

Les checkbox validées correspondent à ce qui est déjà fait dans la branche with_cmake_v2.6.5 du fork de @benEnsta (à vérifier, j'ai peut-être raté des features déjà implémentés)

benEnsta commented 5 years ago

Salut Cyril,

Merci pour la TODO list !!!

Juste quelques précisions: La branche la plus à jour et plutôt celle-ci with_cmake. Il me semblait avoir corriger le problème avec fmemopen (à vérifier). Sinon par rapport à la liste, les tests passaient sur toutes les architectures mais sans solveur linéaire et cppunit est installé automatiquement sous appveyor. Je vais aussi vérifier ça.

Pour flex et bison j'avais aussi ajouté la possibilité utiliser des fichiers déjà générés comme generatedparser.cpp par exemple. Cela évite sous windows de dépendre de flex et bison. A voir si cette façon de faire peut convenir pour la suite.

SInon, Je suis aussi pour la méthode d'intégration numéro 2. Si j'ai le temps ce we, je vais essayer de faire une pull request avec le script cmake sur la branch develop pour servir de base.

gchabert commented 5 years ago

Salut les gars, Super la TODO list Cyril et merci Benoit pour le boulot déjà fait !

Ce ne sont que mes suggestions :) A discuter si vous n'êtes pas convaincu.

gchabert commented 5 years ago

PS: Pour flex et bison, je suis d'accord avec Benoît, c'est une bonne idée pour l'utilisateur lambda d'utiliser les fichiers déjà générés plutôt que de lui faire installer flex/bison. Mais il faut aussi me laisser un moyen simple de continuer à développer le parseur ;-)

SimonRohou commented 5 years ago

Salut Gilles et les Ibexeurs,

Concernant les plugins (il faudrait utiliser un autre mot, disons package pour le moment), il y a deux usages à considérer :

La première fournit les briques métiers du package et leurs headers. Par exemple, pour ibex-solve : la classe Solver ; pour Tubex, un contracteur sur un tube, etc. La seconde (optionnelle) fournit une utilisation de ce package sous forme d'exécutable. Par exemple pour ibex-solve, il s'agit de l'exécutable lié à main/ibexsolve.cpp avec interface minibex.

C'est un découpage classique. En terme de paquets, un développeur roboticien installera : sudo apt install ibex-lib-dev ibex-solve-dev tubex-lib-dev s'il souhaite développer un nouveau programme faisant intervenir des fonctions du solveur et des contracteurs sur les tubes. D'un autre côté, un physicien souhaitant uniquement résoudre un problème en utilisant le solveur via minibex lancera : sudo apt install ibex-solve

Dans le premier cas toutes les bibliothèques nécessaires au développement du roboticien sont installées, avec les headers ; dans l'autre uniquement l'exécutable est demandé.

Je pense qu'il est plus simple d'associer un repo Git par projet (incluant la partie dev et éventuellement la partie utilisation si elle existe). Cela permet de faire clairement apparaître l'état de développement du projet, ses dépendances, les responsables du développement, les issues associées au dev, etc. La page ibex-team ferait donc apparaître tous ces packages.

Exemple d'organisation de dépôts dans la IBEX-team en imaginant les paquet .deb associés :

Enfin je pense que les wrappers tels que pyIbex sont à placer dans chaque package à wrapper. Ainsi les développeurs d'un package sont responsables de la mise à jour de l'interface python de ce package.

NB1 : certains projets tels que le noyau d'IBEX (ou Tubex actuellement) sont de pures bibliothèques qui n'intéresseront que des développeurs. Les paquets permettant à un développeur d'utiliser ces librairies (avec accès aux headers) seraient ibex-lib-dev et tubex-lib-dev. Malgré tout, des paquets ibex-lib et tubex-lib (non dev) inclueront des shared libraries qui seront utilisées par des utilisateurs non développeurs. Par exemple, l'installation du paquet ibex-solve engendra l'installation du paquet ibex-lib afin que le solveur exécutable ait accès aux fonctions d'IBEX par la shared library présente dans ibex-lib.

NB2 : les éventuels exemples fournis avec des bibliothèques de dev (tels que ceux d'IBEX) n'ont pas forcément besoin de faire l'objet d'un "paquet utilisateur" si le but de ces exemples et d'illustrer l'utilisation des fonctions de la bibliothèque, plutôt que ses performances.

NB3 : il faudrait que le site web d'IBEX soit présent dans un dépôt Git de la IBEX-team, afin que chacun puisse contribuer à la documentation du site (mise à jour des références vers les publis, ajout de docs comme par exemple "comment compiler IBEX sur un système embarqué", etc.).

NB4 : il faudrait faire un dépôt Git vide d'exemple de package IBEX, et contenant les éléments de base à remplir en terme de CMake, structure soft, documentation, wrapper python, etc.

Qu'en pensez-vous ?

amarendet commented 5 years ago

Salut,

Je me permets juste de dire que je souscris totalement à ce que dit Simon pour l'organisation des plugins/extensions/packages.

Les seuls désavantages que je vois sont :

gchabert commented 5 years ago

Salut Simon et Antoine,

Je souscris également à tout ce que vous dites.

Juste: Pour la doc, elle est déjà sous Github au format reStructuredText sous le répertoire doc/. Pour info, je remplace dans le tar.gz de chaque release le contenu de ce répertoire par le HTML généré (sauf pour la release 2.8 où j'ai oublié de le faire ...). Par contre, il n'y a pas tout le site web en effet et ce serait peut-être une bonne idée de le mettre quelque part sous Github. Mais cela suppose avant tout de le refaire au propre. Actuellement, c'est un dump très sale de pages HTML générées par Drupal (que j'ai du désinstaller suite à un piratage). Gilles

cyrilbouvier commented 5 years ago

Avec les ponts de Mai, ça avance lentement mais je commence à avoir une idée plus précise du travail à faire.


D'après ce que je comprends des discussions précédentes, il faut viser l'architecture suivante:

Est-ce bien cela ?

Ce choix implique qu'une nouvelle bibliothèques d'intervalles ou de prog lineaire ou un nouvel opérateur ne peut pas se faire via l'utilisation d'une "extension" mais uniquement en ajoutant du code au répo du noyau. De mon point de vue, ce n'est pas forcément génant mais c'est bien de la noter avant de tout chambouler.

De plus, actuellement le solver ibexsolve est compilé et installé par défaut, est-ce qu'on le considère comme faisant parti du noyau ou est-ce une extension ?


Dans les sources d'Ibex (et de certains plugins), il y a des fichiers qui se terminent par un "cpp_". De ce que j'ai compris, ces fichiers ne doivent pas être compilés directement mais plutôt inclus dans d'autres fichiers ou transformés en remplaçant certains variables (@VARIABLES@). Cela me gène un peu car la convention n'est pas clair, et cela demander parfois d'écrire pas mal d'exceptions pour les gérer lors de la configuration/compilation.

Pour chacun des fichiers suivants

src/function/ibex_FunctionBuild.cpp_
src/parser/parser.cpp_
src/set/ibex_SetConnectedComponents.cpp_
src/system/ibex_FritzJohnFactory.cpp_
src/system/ibex_SystemCopy.cpp_
src/system/ibex_SystemMerge.cpp_

j'aurai besoin des infos suivantes:

benEnsta commented 5 years ago

Juste une autre remarque à ajouter à celles de @cyrilbouvier Faut-il conserver les sources des bibliothèque d'intervalles (gaol, filib, ....) et les sources des solveurs linéaires dans le noyau d'ibex ?

Pour ma part je pense que non. Cela éviterait de devoir patcher a chaque fois de veilles versions des lib (en particulier pour filib) et vérifier automatique leur bon fonctionnement sur toutes les plateformes (linux, mac, windows). Cela permettrait également de mieux suivre les évolutions et corrections de bug et gérer les dépendances.

L'idée à terme serait d'utiliser directement soit les versions officielles, soit celles hébergées les dépôts de la ibex-team via des fork, copies des sources, ...

Dans un premier temps, on pourrait (avec l'accord des auteurs respectifs) créer un dépôt filib et un dépôt avec gaol qui contiendraient les fichiers pour la CI (continous integration) et les fichiers Cmake. Pour l’installation dans ibex, cela revient à cloner les dépôts au lieu de les dé-zipper mais avec une meilleurs gestion des versions.

Normalement, pas de grands changements en perspective mais on gagnerait en lisibilité.

Si cela vous va, on pourrait le faire un premier test avec filib.

gchabert commented 5 years ago

Cyril

  • un repo ibex contenant le noyau et les "plugins obligatoires" (bibliothèques d'intervalles, de prog linéaire et opérateurs) et qui installerai libibex.a (ou .so ou .dll), les headers nécessaires (dont ibex.h), le fichier pkg-config ibex.pc (et tous les fichiers nécessaires aux librairies tierces comme gaol, filib, ...).

  • des "extensions" (optim, tubex, java, ....) dans des repos supplémentaires qui doivent pouvoir s'interfacer facilement avec la bibliothèques Ibex.

Est-ce bien cela ?

Pour moi, oui.

Ce choix implique qu'une nouvelle bibliothèques d'intervalles ou de prog lineaire ou un nouvel opérateur ne peut pas se faire via l'utilisation d'une "extension" mais uniquement en ajoutant du code au répo du noyau. De mon point de vue, ce n'est pas forcément génant mais c'est bien de la noter avant de tout chambouler.

De plus, actuellement le solver ibexsolve est compilé et installé par défaut, est-ce qu'on le considère comme faisant parti du noyau ou est-ce une extension ?

Oui. Au minimum, il doit être dans le même repo que le noyau. On peut même envisager de rapatrier le code dans les sources du noyau... on verra plus tard.

Dans les sources d'Ibex (et de certains plugins), il y a des fichiers qui se terminent par un "cpp_". De ce que j'ai compris, ces fichiers ne doivent pas être compilés directement mais plutôt inclus dans d'autres fichiers ou transformés en remplaçant certains variables (@variables@). Cela me gène un peu car la convention n'est pas clair, et cela demander parfois d'écrire pas mal d'exceptions pour les gérer lors de la configuration/compilation.

Oui, tu as raison, ce n'est pas une façon de faire très standard. Je vais déjà nettoyer une partie de ces ".cpp_" ce matin et je te réponds pour le reste dans la foulée.

gchabert commented 5 years ago

@benEnsta

Faut-il conserver les sources des bibliothèque d'intervalles (gaol, filib, ....) et les sources des solveurs linéaires dans le noyau d'ibex ?

Pour ma part je pense que non.

Juste pour être clair: ces librairies ne sont justement pas actuellement dans le noyau mais bien dans des plugins séparés (c'est ce qu'à fait Cyril il y a déjà un certain temps).

Je suppose donc que tu parles de séparation en terme de repo.

Car en effet, actuellement, les releases Github d'ibex englobent des distributions+patchs de toutes ces librairies (sauf cplex). Tu voudrais que cela ne soit plus le cas, n'est-ce pas? Je comprends tes arguments mais je crois qu'il est très important de garder au moins une installation automatique pour chaque catégorie de plugin "obligatoire" lié au noyau (c.a.d. librairie intervalle et solveur linéaire), pour assurer une certaine stabilité et pour que les utilisateurs qui installent ibex n'aient pas à s'en soucier (je ne pense pas qu'on pourra les installer facilement via des paquets de type .deb...).

On pourrait donc ne garder que Gaol et Soplex. On pourrait alors déplacer les autres plugins (filib, CLP, bias, etc.) dans un autre repo, dont on n'assurerait plus le même niveau de test et de maintenance. Effectivement.

Est-ce que cela conviendrait à tous?

gchabert commented 5 years ago

Oui, tu as raison, ce n'est pas une façon de faire très standard. Je vais déjà nettoyer une partie de ces ".cpp_" ce matin et je te réponds pour le reste dans la foulée.

OK. J'ai finalement retiré tous les .cpp_ (sur la branche develop).

SimonRohou commented 5 years ago

@gchabert

De plus, actuellement le solver ibexsolve est compilé et installé par défaut, est-ce qu'on le considère comme faisant parti du noyau ou est-ce une extension ?

Oui. Au minimum, il doit être dans le même repo que le noyau. On peut même envisager de rapatrier le code dans les sources du noyau... on verra plus tard.

Si le solver est actuellement considéré comme un plugin, qu'est-ce qui motive la décision de le laisser dans le répo du noyau, plutôt que de l'identifier dans un dépôt séparé (avec ses commits, issues, etc. propres ?).

C'est une simple question :) En termes de visibilité et de compréhension de l'architecture d'IBEX et de ses extensions, il est peut-être plus simple d'appliquer les mêmes règles pour toutes les fonctionnalités. Et donc laisser dans le noyau les aspects contracteurs et interfaces vers des bibliothèques bas niveau (Gaol, etc.) et externaliser tous les autres développements tels que le solveur, l'optim, etc.

Mais ce n'est qu'un point de vue d'un non-utilisateur du plugin solver :)

gchabert commented 5 years ago

Salut Simon

Si le solver est actuellement considéré comme un plugin, qu'est-ce qui motive la décision de le laisser dans le répo du noyau ?

Le fait que je ne suis pas sûr qu'il doive justement être considéré comme un plugin.... Ibexsolve et ibexopt sont le coeur historique d'ibex et la plupart des gens utilisent ibex pour ces exécutables. Du coup, j'hésite à les réintégrer dans le noyau à un moment donné. Je me tâte car tu as raison malgré tout, pour les releases ou les bug reports par exemple, c'est sans doute mieux de séparer les choses. Pas évident de savoir ce qui est le mieux...

benEnsta commented 5 years ago

Salut @gchabert,

Effectivement je n'avais pas le même définition des plugins en tête. Pour moi plugins = dépôt séparé :)

Pour moi, gaol et soplex sont aussi à mettre dans des depots séparés et non dans les sources d'ibex. Cela n'a pas trop de sens de télécharger les sources d'un projet qui lui même contient des sources d'autres projets. Surtout quand on a des outils moderne comme git et cmake.

En se qui concerne l'installation automatique quelque soit la structure des dépôts et des dépendances la procédure restera simple avec git. Avec le mécanisme des sous-module, la commande :

git clone --recursive <ibex-lib repo>

clonera les sources avec tous les submodules avec les sources de gaol, soplex,... La suite de l'installation restera inchangée et transparente pour l'utilisateur.

Par contre si demain des modifications dans ces librairies doivent être faites, ce sera beaucoup plus simple que de modifier les zip ou ajouter des patchs. En particulier, si on passe le coeur avec Cmake, il serait plus simple de compiler les dépendances avec cmake aussi. Cela permet d’être plus homogène vis à vis des options de compilation et de faciliter l’installation / packaging. J’ai déjà fait les scripts pour filib, et j’ai fait quelques essais avec gaol. Mais pour l’instant, avec la structure actuelle, c’est compliqué à intégrer.

Je m'accroche peut-être à un detail, mais pour avoir passer beaucoup de temps à déployer les binaires compilés de pyibex sur toutes les plateformes, je pense que c'est important de bien maitriser chaque dependance.

Sujet à discuter ....

ThomasLeMezo commented 5 years ago

@gchabert @SimonRohou

Je comprends tes arguments mais je crois qu'il est très important de garder au moins une installation automatique pour chaque catégorie de plugin "obligatoire" lié au noyau (c.a.d. librairie intervalle et solveur linéaire), pour assurer une certaine stabilité et pour que les utilisateurs qui installent ibex n'aient pas à s'en soucier (je ne pense pas qu'on pourra les installer facilement via des paquets de type .deb...).

Pour vous donner une idée de ce qui est fait dans d'autres projets comme par exemple pour ROS l'utilisateur se voit proposer plusieurs choix d'install en fonction de son besoin :

Dans chacun de ces trois packages, il y a des dépendances à des centaines d'autres (y compris pour l'installation de base, voir ici). Ainsi pour l'installation d'un seul packet, cela déclenche automatiquement l'installation de toute une suite de packages. Une démarche à suivre serait de définir éventuellement des "type d’utilisations/d'utilisateurs" d'ibex avec la liste des packages/plugins à fournir (cas général, orientation optim, orientation robotique, dev, etc.).

Concernant le nombre de répo github, dans le cas de ROS ils en ont beaucoup rien que pour le "core" cf ici. Cela donne des idées d'architecture possible...

gchabert commented 5 years ago

@domensta @ThomasLeMezo

Si c'est effectivement plus simple pour les scripts d'install de tout éclater sur différents repos et que ça reste transparent pour l'utilisateur, alors OK. Je crains une certaine lourdeur notamment du fait que chaque morceau de code aura ses propres versions, dépendances.... mais, OK pour essayer.

Je ne sais pas si vous êtes parvenus à vous synchroniser Benoît et Cyril?

A+ Gilles

cyrilbouvier commented 5 years ago

Je viens de pusher sur la branche develop (commit 4177f50) un premier jet pour l'utilisation de CMake.

Pour tester:

mkdir build
cd build
cmake ..
make
make test
make install

la commande cmake reconnaît pour l'instant les arguments suivant:

Concernant les bibliothèques d'intervalles, il n'y a que gaol qui est utilisable pour l'instant. Et il n'y a pas d'installation automatique pour l'instant. Avant que je continue le boulot sur ces bibliothèques, il faut décider les questions suivantes:

Pour moi la troisième question est indépendante des deux questions précédentes et on peut très bien imaginer que les répos soit séparés mais qu'Ibex propose quand même une installation automatique (en imginant par exemple que l'archive ibex contiennent une copie du répo gaol).

Aucun plugin n'est activable pour le moment.

make test se contente de faire deux tests.

Je me suis basé sur CMake 2.8.12 (cmake_minimum_required (VERSION 2.8.12)) ce qui permet que cela fonctionne out-of-the-box sur Debian 8 (et supérieur), Ubuntu 14.04 (et supérieur) et Centos 6 (et supérieur).

gchabert commented 5 years ago

Salut Cyril, Super!

J'ai testé mais je ne parviens pas à compiler car cmake me réclame gdtoa (qui est pourtant bien installé dans le sous-répetoire gdtoa de gaol).

  • quelles versions de gaol/filib/bias sont compatibles avec Ibex (toutes, une seule, celle après la v42.3.4, ...) ?

On se limite à une seule.

  • doit-il y avoir un script d'installation automatique ? pour gaol ? filib ? bias ?

Uniquement pour gaol désormais.

  • les répertoires plugins/intervallib* doivent-ils être dans des répos séparés ?

Suite aux échanges précédents, voilà finalement mon point de vue: Je préfère que les plugin gaol et soplex soient dans le même repo que le noyau, pour deux raisons:

gchabert commented 5 years ago

Addendum: je constate en fait que Filib est toujours la librairie intervalle installée par défaut sous Windows (MinGW). Peut-être est-ce parce qu'il y a toujours des soucis à compiler Gaol 4 sous MinGW? Est-ce qu'alors, en passant désormais par cmake, ces soucis disparaîtront? Sinon, il faudra envisager de garder aussi filib installable automatiquement...

cyrilbouvier commented 5 years ago

J'ai testé mais je ne parviens pas à compiler car cmake me réclame gdtoa (qui est pourtant bien installé dans le sous-répetoire gdtoa de gaol).

Est-ce que cela fonctionne avec le commit 9c0b242 ?

Je préfère que les plugin gaol et soplex soient dans le même repo que le noyau.

Ok. Est ce que je les mets dans un répertoire autre que plugin ? Par exemple, je crée un répertoire interval_lib_wrapper à la racine du répo (ou dans src) qui contient gaol (avec install automatique si besoin) en prenant en compte la possibilité d'avoir d'autre wrappers (filib, bias, direct) ? Et la même chose avec un répertoire lp_lib_wrapper.

gchabert commented 5 years ago

Est-ce que cela fonctionne avec le commit 9c0b242 ?

Non :-/ il me dit toujours "Looking for gdtoa -- not found"

Ok. Est ce que je les mets dans un répertoire autre que plugin ? Par exemple, je crée un répertoire interval_lib_wrapper à la racine du répo (ou dans src) qui contient gaol (avec install automatique si besoin) en prenant en compte la possibilité d'avoir d'autre wrappers (filib, bias, direct) ? Et la même chose avec un répertoire lp_lib_wrapper

Ca me paraît une bonne idée. Ça clarifiera la situation!

cyrilbouvier commented 5 years ago

Est-ce que cela fonctionne avec le commit 9c0b242 ?

Non :-/ il me dit toujours "Looking for gdtoa -- not found"

Est-ce que tu utilises -DGAOL_DIR=/path/to/gaol/install/dir quand tu invoques CMake ?

gchabert commented 5 years ago

Est-ce que tu utilises -DGAOL_DIR=/path/to/gaol/install/dir quand tu invoques CMake ?

Oui. Mais c'est bon désormais, c'était de ma faute, je n'avais pas fait de "make install" de gaol.

Nouveau problème désormais: il ne trouve pas de fichier CMakeLists.txt dans ibex/tests.

cyrilbouvier commented 5 years ago

C'est normal, j'ai oublié de le comitter... C'est fait dans 243eb8d

cyrilbouvier commented 5 years ago

Je me suis basé sur CMake 2.8.12 (cmake_minimum_required (VERSION 2.8.12)) ce qui permet que cela fonctionne out-of-the-box sur Debian 8 (et supérieur), Ubuntu 14.04 (et supérieur) et Centos 6 (et supérieur).

Je suis très tenté de me baser sur CMake 3.0 au lieu de 2.8.12 pour simplifier un peu le développement des fichiers CMake. La conséquence est que sur sur Ubuntu 14.04 (qui n'est plus maintenu par Ubuntu depuis avril) et Centos 6 (qui ne sera plus maintenu en 2020), il faut faire une petite manip avant d'installer ibex (désinstaller le paquet cmake et installer cmake3). Pour toutes les distributions plus récentes, la version de cmake disponible par défaut dans les paquets est au moins la 3.0. [ Pour windows et OS x, c'est moins génant, les gens téléchargent des versions précompilés et prennent donc souvent la dernière version (3.14 actuellement) ].

Est-ce que quelqu'un a une objection à ce changement ?

gchabert commented 5 years ago

Salut Cyril, OK pour "cmake". Mais pour "make", il échoue au milieu de la compilation:

[ 38%] Building CXX object src/CMakeFiles/ibex.dir/numeric/ibex_LPSolver.cpp.o
/home/gilles/workspace/ibex/build/src/numeric/ibex_LPSolver.cpp:290:10: fatal error: ibex_LPWrapper.cpp_: No such file or directory
 #include "ibex_LPWrapper.cpp_"
          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.

Aucune objection pour ma part à utiliser cmake 3, quitte à reprendre tout le build d'ibex, autant être "cutting edge" ;-)

benEnsta commented 5 years ago

Pour moi, cmake 3.0 c'est nickel. Par contre il faudrait garder auusi filib car elle compile avec mvsc. il me semble que ce n'est pas le cas de gaol pour le moment.

cyrilbouvier commented 5 years ago

Dans 1a9a3e7, j'ai fait quelque chose de plus propre pour les bibliothèques d'intervalles et de programmation linéaire, je vais commencer à écrire le code pour l'utilisation de filib, soplex, .. (sans installation automatique pour l'instant).

De plus, en activant les tests dans un commit d'hier ou avant hier, je suis tombé sur le problème que certains tests ne compilent pas sans le "plugin" solver (aucun plugin n'est pour l'instant intégré avec CMake). Ca me semble donc être le bon moment pour décider de ce qu'on fait du "plugin" solver. Je vois 4 possibilités:

  1. on le met dans un répo séparé
  2. on le laisse dans le même répo comme un plugin obligatoire (comme actuellement)
  3. on le laisse dans le même répo comme un plugin facultatif
  4. on le laisse dans le même répo et on l'intègre au noyau

La solution 2 me paraît un peu bancale (il faut au minimum bouger les tests qui dépendent de solver dans le plugin). Les meilleurs solutions me semblent être 1 et 4, le seul argument que je vois pour les départager est la "facilité d'accès" pour un utilisateur lambda: si la majorité des utilisateurs installe Ibex pour le solver autant l'intégrer au noyau, ca leur facilitera la vie; s'il est peu utilisé autant le séparer pour ne pas "alourdir" le noyau d'Ibex inutilement.

cyrilbouvier commented 5 years ago

J'ai ajouté la possibilité d'utiliser soplex et filib avec CMake. Pour cela il faut utiliser les options:

Pour aider CMake à les trouver, il y a deux nouvelles options:

La semaine prochaine j'aurai moins de temps pour bosser sur Ibex mais n'hésiter pas à tester, je corrigerai tous les problèmes du code CMake dès que j'aurai le temps. Par contre j'essayerai d'être réactif sur les bugs que j'ai pu introduire dans waf par effets de bord.

Les prochains chantiers:

gchabert commented 5 years ago

@cyrilbouvier

J'ai testé sous linux gaol seul, gaol+soplex, et filib+soplex. Tout se compile nickel ! Seule remarque pour l'instant: make clean n'efface pas le contenu du répertoire build, ni les répertoires générés (lib, include).

Ca me semble donc être le bon moment pour décider de ce qu'on fait du "plugin" solver. Je vois 4 possibilités: 1- on le met dans un répo séparé 2- on le laisse dans le même répo comme un plugin obligatoire (comme actuellement) 3- on le laisse dans le même répo comme un plugin facultatif 4- on le laisse dans le même répo et on l'intègre au noyau

Juste une remarque: actuellement, le plugin "solver" est bien facultatif (mais installé par défaut). Mais bon, peu importe; vu les avis, je propose la solution 4 du coup. On peut délacer le répertoire "src" ainsi: plugins/solver/src ----> src/solver Par contre, je ne sais pas où déplacer proporement les répertoires "main" et "benchs". Si cela ne pose pas de difficulté en terme de script cmake, on peut mettre les fichiers de "main" (args.hxx et ibexsolve.cpp) dans src/solver.... mais pour le coup, je ne trouve pas ça très clean (mettre un exécutable au milieu de fichiers objet d'une librairie, bof non?). Pour "benchs", on peut le mettre à la racine de ibex mais avec peut-être un nom comme solver_benchs. Je suis preneur de suggestion...

Gilles

cyrilbouvier commented 5 years ago

Seule remarque pour l'instant: make clean n'efface pas le contenu du répertoire build, ni les répertoires générés (lib, include).

C'est la "philosophie" CMake, make clean ne supprime que les fichiers générés par make (donc pas grand chose). Si tu veux repartir de zéro, il faut supprimer à la main le fichier dans lequel tu as fait le build. Par exemple, si tu as compilé en faisant:

mkdir build
cd build
cmake ..
make

l'équivalent d'un make clean serait

cd ..
rm -r build

Juste une remarque: actuellement, le plugin "solver" est bien facultatif (mais installé par défaut).

Pas vraiment facultatif: il y a 5 tests (du répertoire tests principal) qui ne compilent pas sans ce plugin et plusieurs exemples ne compilent pas non plus.

Mais bon, peu importe; vu les avis, je propose la solution 4 du coup

Une chose auquelle je n'avais pas pensé: les fichiers du plugin solver requièrent une bibliothèque de programmation linéaire (du style soplex), non ? Cela rajoute donc une dépendence au noyau Ibex, sauf s'il le wrapper "none" peut être utilisé comme défaut sans problème.

Edit: en regardant le code, je me rends compte que je me suis trompé, c'est le plugin optim qui à en a besoin pas le plugin solver. C'est bien cela ? Dans ce cas, cette remarque peut etre oubliée.

Si cela ne pose pas de difficulté en terme de script cmake, on peut mettre les fichiers de "main" (args.hxx et ibexsolve.cpp) dans src/solver.... mais pour le coup, je ne trouve pas ça très clean (mettre un exécutable au milieu de fichiers objet d'une librairie, bof non?)

Ca me choque pas. Mais si tu veux séparer, on peut mettre les fichiers ibexsolve.cpp et argx.hxx dans src/bin pour les séparer du reste.

gchabert commented 5 years ago

Une chose auquelle je n'avais pas pensé: les fichiers du plugin solver requièrent une bibliothèque de programmation linéaire (du style soplex), non ? Cela rajoute donc une dépendence au noyau Ibex, sauf s'il le wrapper "none" peut être utilisé comme défaut sans problème.

En effet. On peut utiliser le wrapper "none" sans problème (même si ce n'est pas top pour les performances).

Ca me choque pas. Mais si tu veux séparer, on peut mettre les fichiers ibexsolve.cpp et argx.hxx dans src/bin pour les séparer du reste.

OK, très bien.

Jordan08 commented 5 years ago

Bonjour,

Je prends la discusion en chemin. J'ai des questions sur les chemins d'accès des librairies 3rd (interval et LPsolver).

-Est-ce que CMake regarde si une librairie (interval et/ou LPsolver) est déjà disponible et installé dans les chemins d'accès standard du système? Si c'est le cas, il faudrait la prévilégier, je pense.

gchabert commented 5 years ago

Salut Jordan

Est-ce que CMake regarde si une librairie (interval et/ou LPsolver) est déjà disponible et installé dans les chemins d'accès standard du système? Si c'est le cas, il faudrait la prévilégier, je pense.

Comme dit plus haut, on ne fait d'installation automatique que pour les librairires désormais officiellement supportées, c.a.d. Gaol côté intervalle (+ filib si gaol ne s'avère pas compilable sous windows) et Soplex côté LPSolver. Cyril je te laisse corriger si je me trompe.

J'ai remarqué que le chemin de "clp" avait été changé

OK. Je ne sais pas à quand remonte cette modif!... Bon, Cyril ne peut pas tout faire. Lorsque les plugins auront été redispatchés sur des repos distincts, il faudra poster une issue sur le repo ibex-CLP et on traitera ça à ce moment-là. Ok pour toi?

Jordan08 commented 5 years ago

ok je comprends, mais ce que je voulais dire c'est:

gchabert commented 5 years ago

Pourquoi installer Gaol ou Filib ou Soplex, si c'est déjà installé sur la machine?

Je te confirme donc qu'on n'installera pas ces librairies si elles sont présentes sur la machine. J'ai déjà pu tester que c'était le cas, mais en spécifiant à cmake le chemin où elles se trouvent. Je n'ai pas testé la recherche automatique.

De même, Si CLP ou CPLEX est installé, pourquoi installer Soplex?

Pour des questions de maintenance. Si cmake compile ibex avec CLP automatiquement lorsque cette librairie est présente, cela veut dire qu'on "prend la responsabilité" de faire fonctionner ibex avec CLP. Car un utilisateur peut ne même pas avoir conscience que CLP est installé!... et si cmake plante, c'est qu'on n'a pas fait notre boulot. Pire, si on supporte CLP et CPLEX en plus de Soplex, il faut maintenir toutes les combinaisons avec les autres librairies: gaol, filib, etc. Bref, c'est l'enfer. Donc si un utilisateur veut compiler avec CLP c'est qu'il sait qu'il fait, il prend donc la responsabilité que ça échoue en ajoutant l'option --with-clp explicitement. Tu vois l'idée?

Est-ce c'est pas mieux de minimiser le nombre d'installation que l'on fait nous-même?

Je ne crois pas. Ca ne coûte rien à l'utilisateur qu'une librairie soit installée automatiquement avec ibex...

Jordan08 commented 5 years ago

ok.. je vois l'idée. Pourquoi pas, ça me va.

Du coup, il faut juste vérifier que les chemins par defaut soient explorés.

cyrilbouvier commented 5 years ago

@Jordan08 @gchabert Concernant les bibliothèques (pour l'arith d'intervalles ou la programmation linéaire), la logique implémentée avec waf et que je compte reproduire avec CMake est la suivante:

  1. l'utilisateur choisit sa bibliothèque (avec une bibliothèque par défaut si pas de choix)
  2. le script cherche la bibliothèque dans le chemin suggéré par l'utilisateur (si l'option --*-path est utilisée) et dans les chemins standards (les chemins hardcodé dans waf ou CMake genre /usr/lib, /usr/local/lib, ... sur Linux)
  3. si rien n'est trouvé, on fait une install si c'est possible

Sachant que comme le dit Gilles, le repo principale d'Ibex ne proposera que Gaol (et peut être Filib si nécessaire) et Soplex. Mais tout sera prévu pour qu'un utilisateur puisse ajouter le support pour d'autres bibliothèques s'il le souhaite. Dans ce cas l'utilisateur sera libre d'implémenter sa propre logique (les étapes 2 et 3)

J'ai remarqué que le chemin de "clp" avait été changé "coin/ClpSimplex.hpp" -> "ClpSimplex.hpp". Ça pose des problèmes, car de façon standard CLP est installé dans le dossier /usr/include/coin/ClpSimplex.hpp . Et c'est la même chose pour CPLEX /usr/include/ilcplex/cplex.h On fait de même pour ibex, on le met dans /usr/include/ibex/ibex_*.h Il faudrait laisser le "coin/..."

Ca ne pose pas tant de problème, le 'coin/' est prefixé à tous les chemins de recherches. C'est fait actuellement dans waf et c'est très facile à faire dans CMake aussi. Le contraire est plus compliqué à faire. Si pour une raison ou pour une autre, ClpSimplex.hpp n'est pas installé dans le répertoire coin/ alors il sera impossible de le trouver s'il on cherche coin/ClpSimplex.hpp. Quant à Ibex, effectivement il installe ces headers dans le sous répertoire ibex/ mais ibex.h est installé à la racine du répertoire d'installation des headers, ce qui fait qu'un utilisateur voulant utiliser la bibliothèque Ibex a juste à faire #include <ibex.h>.

Edit Après je me rends compte que c'est pas très uniforme. Dans Gaol par exemple on continue d'inclure gaol/gaol.h et du coup les scripts (waf et CMake) cherchent gaol/gaol.het nongaol.h`.

cyrilbouvier commented 5 years ago

Bonjour,

Cette semaine je me suis remis à Ibex. Je vais m'attaquer à intégrer les opérateurs, à finir le packaging et à la gestion des plugins. Pour finir correctement la gestion des opérateurs, j'aurais besoin de savoir quel est leur statut: est-ce qu'ils font vraiment parti du noyau (et dans ce cas on pourrrait les mettre dans src/operators et mettre les tests dans tests/) ou est-ce qu'ils doivent rester séparer (dans ce cas que faire des tests? ) ?

Pour info, l'installtion automatique de soplex, gaol et filib est implémentée. Et CMake peut maintenant générer et installer le fichier ibex.pc (ce qui devrait être utile pour les plugins).

gchabert commented 5 years ago

Super! J'allais justement venir aux nouvelles :)

Pour les opérateurs, voilà mon point de vue. A l'origine, un nouvel opérateur était vu comme une extension du noyau et il était donc plus logique de le placer dans plugins/ plutôt que dans src/. Mais avec le recul, ça rend par ailleurs les choses tordues car l'opérateur est bel et bien intégré au noyau (il y a une dépendance au niveau du code) ... Du coup, si ça te paraît plus clair Cyril, je pense qu'on peut rapatrier les opérateurs dans src/. Et à bien y réfléchir, je crois que ça ne change rien pour l'utilisateur qu'il dépose le code de son propre opérateur dans le répertoire plugins/operators ou dans le répertoire src/operators. Dis-moi ce que tu en penses. Gilles

cyrilbouvier commented 5 years ago

Pour les opérateurs, voilà mon point de vue. A l'origine, un nouvel opérateur était vu comme une extension du noyau et il était donc plus logique de le placer dans plugins/ plutôt que dans src/. Mais avec le recul, ça rend par ailleurs les choses tordues car l'opérateur est bel et bien intégré au noyau (il y a une dépendance au niveau du code) ... Du coup, si ça te paraît plus clair Cyril, je pense qu'on peut rapatrier les opérateurs dans src/. Et à bien y réfléchir, je crois que ça ne change rien pour l'utilisateur qu'il dépose le code de son propre opérateur dans le répertoire plugins/operators ou dans le répertoire src/operators.

Ok j'essaye de commiter ça demain pour que vous puissiez tester.

cyrilbouvier commented 4 years ago

Dans le commit 11d823d, j'ai réécrit pas mal de code CMake pour faciliter l'export d'Ibex et raccourcir le code qu'il est nécessaire d'écrire dans les plugins (je vais mettre à jour le dépot https://github.com/ibex-team/template-ibex-plugin-cmake rapidement).

Cmake peut aussi maintenant générer des paquets debian (il suffit de faire 'make package')

Le code est maintenant quasi terminé (il reste quand même encore quelques TODO par-ci par-là). Il faudrait qu'un maximum de personne le teste, ceci me permettrait de prendre en compte des cas d'utilisations que je n'ai pas implémenté et/ou prévu.

Il pourrait être aussi intéressant de commencer à sortir les plugins du répo principale et de les mettre dans des répos séparés (en s'appuyant sur https://github.com/ibex-team/template-ibex-plugin-cmake) pour tester toutes les fonctionnalités que j'ai developpé avec CMake.

amarendet commented 4 years ago

Bonjour Cyril,

Super, merci, ça a l'air de bien fonctionner de mon côté ! J'ai juste un soucis avec cette ligne :

https://github.com/ibex-team/ibex-lib/blob/c010a59e6226170f62baf11b7b57ed7271efafcf/cmake.utils/ibex-config-utils.cmake#L130

Je suppose que tu voulais écrire ${ARGS} à la place $(ARGS) (j'ai une erreur en utilisant Ninja comme backend), mais vu que je ne suis pas sûr je préfère ne pas toucher :). D'ailleurs je ne suis pas non plus très sûr de ce qu'est censé référencer ${ARGS}.

Antoine

amarendet commented 4 years ago

Je n'arrive pas à compiler lorsque MATHLIB_DIR et GAOL_DIR ne sont pas définis avant. Il n'a pas l'air de builder la target "ultim":

CMake Warning at CMakeLists.txt:4 (message):
  CMake support is still experimental, use waf to build Ibex

-- Configuring Ibex 2.8.6
-- Running on system Darwin-19.2.0 with processor x86_64
-- Using CMake 3.16.4
-- C++ compiler: AppleClang 11.0.0.11000033
-- Will build static libraries
-- Library for interval arithmetic: gaol
-- Looking for MathLib.h
-- Looking for MathLib.h -- not found
-- Looking for ultim
-- Looking for ultim -- not found
-- Will install and use mathlib from 3rd/ subdirectory
/Users/antoinemarendet/logiciels/ibex-lib-build/interval_lib_wrapper/gaol/mathlib-2.1.0/lib/libultim.a
-- Looking for gaol/gaol.h
-- Looking for gaol/gaol.h -- found at /Users/antoinemarendet/logiciels/gaol/include
-- Looking for gdtoa
-- Looking for gdtoa -- found at /Users/antoinemarendet/logiciels/gaol/lib/libgdtoa.a
-- Looking for gaol
-- Looking for gaol -- found at /Users/antoinemarendet/logiciels/gaol/lib/libgaol.a
-- Library for linear programming: soplex
-- Looking for soplex.h
-- Looking for soplex.h -- found at /Users/antoinemarendet/logiciels/soplex-4.0.2/include
-- Looking for soplex
-- Looking for soplex -- found at /Users/antoinemarendet/logiciels/soplex-4.0.2/lib/libsoplex.a
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/antoinemarendet/logiciels/ibex-lib-build
ninja: error: 'interval_lib_wrapper/gaol/mathlib-2.1.0/lib/libultim.a', needed by 'src/bin/ibexsolve', missing and no known rule to make it

Impossible aussi de builder les targets "ibexsolve" et "ibexopt", j'ai ce genre de message:

FAILED: src/bin/ibexsolve 
: && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++  -O3 -DNDEBUG -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  src/bin/CMakeFiles/ibexsolve.dir/ibexsolve.cpp.o  -o src/bin/ibexsolve  src/libibex.a  /Users/antoinemarendet/logiciels/gaol/lib/libgaol.a  /Users/antoinemarendet/logiciels/gaol/lib/libgdtoa.a  /Users/antoinemarendet/logiciels/gaol-mathlib-ibex/lib/libultim.a  /Users/antoinemarendet/logiciels/soplex-4.0.2/lib/libsoplex.a && :
Undefined symbols for architecture x86_64:
  "gaol::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, gaol::interval const&)", referenced from:
      ibex::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, ibex::Interval const&) in libibex.a(ibex_IntervalLibWrapper.cpp.o)
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_not_of(char const*, unsigned long) const", referenced from:
      gaol::operator<<(std::ostream&, gaol::interval const&) in libgaol.a(gaol_interval.o)
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::c_str() const", referenced from:
      gaol::interval::interval(char const*) in libgaol.a(gaol_interval.o)
      gaol::interval::interval(char const*) in libgaol.a(gaol_interval.o)
      gaol::interval::interval(char const*, char const*) in libgaol.a(gaol_interval.o)
      gaol::interval::interval(char const*, char const*) in libgaol.a(gaol_interval.o)
      gaol::operator>>(std::istream&, gaol::interval&) in libgaol.a(gaol_interval.o)
...
cyrilbouvier commented 4 years ago

J'ai juste un soucis avec cette ligne :

https://github.com/ibex-team/ibex-lib/blob/c010a59e6226170f62baf11b7b57ed7271efafcf/cmake.utils/ibex-config-utils.cmake#L130

Je suppose que tu voulais écrire ${ARGS} à la place $(ARGS) (j'ai une erreur en utilisant Ninja comme backend), mais vu que je ne suis pas sûr je préfère ne pas toucher :). D'ailleurs je ne suis pas non plus très sûr de ce qu'est censé référencer ${ARGS}.

Non, c'est bien $(ARGS). Cela fait référence aux arguments que tu peux passer à make check sur la ligne de commande. Par example, si tu veux lancer que certains tests tu peux faire:

make check ARGS="-R TestCtc*"

Le "ARGS" sur la ligne de commande sera passé à ctest via $(ARGS).

Faudra que je mette ces infos dans une doc (pas forcémenent celle pour les utilisateurs mais plus pour les développeurs).

cyrilbouvier commented 4 years ago

Je n'arrive pas à compiler lorsque MATHLIB_DIR et GAOL_DIR ne sont pas définis avant. Il n'a pas l'air de builder la target "ultim":

Effectivement, il y a un problème lorsque que CMake trouve Gaol mais pas Mathlib/libultim. Je vais regarder de plus près ce qu'il se passe dans ce cas. Est-ce que c'est génant si dans le cas là, je réinstalle tous (Mathlib/libultim et Gaol) ?

cyrilbouvier commented 4 years ago

@amarendet Est-ce que tu peux réessayer avec le dernier commit ? Si cela ne marche pas, est-ce que tu peux envoyer la commande exacte que tu utilises, et les logs de Cmake et de compilation ?

amarendet commented 4 years ago

Mea culpa : en fait je n'avais pas vu que j'avais une vieille installation de Gaol dans mon path, mais pas la libm associée. En l'enlevant de mon path, CMake installe bien ultim et Gaol depuis Ibex. Je pense qu'on devrait peut-être avoir une erreur si on indique GAOL_DIR mais pas MATHLIB_DIR et inversement (ou s'ils l'un est trouvé automatiquement mais pas l'autre).

En tout cas maintenant tout marche bien chez moi en utilisant le backend make.

Pour l'histoire du $(ARGS), est-ce qu'il n'y aurais pas un autre moyen ? C'est embêtant d'avoir une commande qui fait planter certains backends, ça risque peut-être de poser problème sous Windows également.

cyrilbouvier commented 4 years ago

Pour l'histoire du $(ARGS), est-ce qu'il n'y aurais pas un autre moyen ? C'est embêtant d'avoir une commande qui fait planter certains backends, ça risque peut-être de poser problème sous Windows également.

J'ai reglé le problème dans le commit 3e50c89137, je ne mets le $(ARGS) que pour les générateurs basés sur Makefile. Cela règle donc le problème pour Ninja en particulier.

gchabert commented 4 years ago

Salut Cyril, Je voudrais commencer à tester ce que tu as fait sauf que j'ignore tout de cmake... mais c'est en fait une très bonne chose car ça permettra de constituer au fil de l'eau une doc d'installation adéquate, y compris pour les utilisateurs inexpérimentés.

J'ai juste pu faire un premier test en faisant cmake . suivi de make et ça a marché :) J'ai néanmoins une remarque: l'exécutable ibexsolve est placé dans src/bin au lieu de bin. C'est dommage, je préférerais garder l'ancien emplacement.

Ensuite, j'aurais besoin de savoir comment installer les différents plugins et choix de librairies intervalles/solveur linéaire. Peux-tu me dire comment? Si tu veux, je peux me charger ensuite de mettre ça en forme et l'intégrer dans la doc en ligne; on peut aussi le faire tous les deux (la doc est sous github dans doc/install.rst).