IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Compiler sur un OS différent


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Compiler sur un OS différent
    Bonjour à toutes et à tous!

    J'ai codé/bricolé une petite lib pendant ma thèse, que j'ai utilisé sur Ubuntu, et aujourd'hui on a collaboré avec une chercheuse du domaine qui code sur mac. Outre le sentiment fort agréable que le travail des trois ans de thèse va peut être pas partir de suite aux oubliettes ( ) , y'a quand même quelques spécificités du travail à plusieurs à prendre en compte. Notamment le changement d'OS... Bon je m'attendais à ce qu'on rencontre quelques bricoles évidemment, et heureusement dans l'ensemble ça a été vite réglé.

    Par contre j'avoue avoir été un peu surpris de voir la nature des problèmes, je m'attendais pas à des problèmes de cet ordre.

    Par exemple je déclarais ce constructeur par déplacement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class MyClass {
      MyClass(MyClass&& other) noexcept = default;
    };
    Ca passait sur mon système mais pas sur mac. J'ai pas dit que ça aurait du passer incognito jusque là: à vrai dire vous allez peut être brûler ce constructeur pour hérésie. Je dis juste que c'est étonnant de voir que le code qui passe sans souci chez A plante superbement chez B. Par contre ceci met tout le monde d'accord (je vais sans doute surprendre personne à part moi )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class MyClass {
      MyClass(MyClass&& other) = default;
    }
    Idem, j'avais oublié un #include<functional> quelque part: ça passait crème chez moi, et ça plantait chez l'autre. Comment ça se fait que ce soit passé inaperçu alors qu'on a compilé exactement le même code de tests unitaires ?

    Bref, au final c'est assez ironique, j'ai perdu beaucoup de temps à débugger ça parce que justement je pensais pas qu'un code qui compile quelque part puisse être en fait blindé de problèmes. Ca m'a rappeler le temps perdu il y a un an à chercher une erreur au mauvais endroit parce que je partais du principe que mes tests étaient exhaustifs: ce matin je partais du principe que le compilateur de mon système avait déjà trouvé tous les défauts de mon code.

    C'est ce genre de trucs auquel il faut s'attendre à l'avenir quand on va essayer de coder des truc Linux-mac compatibles ? Ou bien ça c'était juste le côté pâte-à-choux et y'a des truc horribles qui vont nous tomber sur les dents ?

    PS: on le dit jamais assez mais vivent les batteries de tests unitaires
    PPS: il faut vraiment que j'assainisse cette batterie de tests unitaires
    PPS: encore merci à vous tous d'avoir insister pour que je fasse des tests unitaires

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Salut,

    Ça fait 2 ans que je travaille sur des projets pour micro-contrôleur (MCU) pour lesquelles une grosse partie du code est compilé sur PC pour faire des tests unitaires. Et franchement tu trouves souvent des choses qui clochent entre les deux. En ce moment, c'est du GCC sur MCU et sur PC, les deux cibles sont des processeurs 32 bits, et pourtant on a des différences. Notamment le fait que std::(u)int32_t soit un alias pour (unsigned) int d'un côté et (unsigned) long de l'autre. Ce qu'il faut retenir c'est que quand tu changes de cible (processeur + OS + compilateur), il faut s'attendre à des différences. Ce sont des options qui ne sont pas toujours exactement les mêmes (ou qui des fois n'ont pas d'équivalents directs), des bibliothèques standards qui ne sont pas implémentées de la même manière (c'est là que ton histoire de header non inclus peut arriver ; des fois ça donne des trucs assez relou), ton code qui utilisent des undefined behaviors ou implementation-defined behaviors, ton code qui contient des bugs qui ne s'étaient pas encore exprimés jusque là, des compilateurs avec des bugs(oui ça existe) ou des comportements assez étranges ou des comportements pas toujours exactement collés à la norme. La norme des fois laisse aussi des latitudes qui peuvent amener des choses funs (comme par exemple le fait que dans <cstdio>, tu puisses avoir ou pas printf() dans le namespace global ou pas).

    Bref, les problèmes t'attendent au tournant.

    Les tests unitaires te permettent effectivement d'avoir une référence pour exécuter ton code sur une nouvelle plateforme. Il faut pas oublier pour autant que ce n'est pas une méthode complète de validation de code. En vrac, faire lire son code à des gens, relire soi-même son code, se reposer sur son compilateur réglé en mode paranoïaque et des outils comme valgrind ;)

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    - la compilation n'est pas propre a l'OS mais a la chaine de compilation (qui varie d'un OS a l'autre, mais au sein d'un meme OS egalement)
    - toutes les implementations ne sont pas strictement identiques

    Apres, ca c'est le niveau 0 de la portabilite. D'autres problemes peuvent survenir
    - implementation manquante
    - comportements differents avec les memes appels
    - devoir rearchitecturer certains pans parce qu'une plateforme propose qu'une API asynchrone
    - bug de compilateur sur une plateforme donnee
    la liste continue et s'etoffe au fur et mesure des experiences
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Invité
    Invité(e)
    Par défaut
    Complètement d'accord avec Bousk. Sur Ubuntu, tu as une toolchain GCC par défaut alors que sur Mac c'est du Clang. Les options de compilation et les includes par défaut ne sont pas les mêmes, et j'imagine que c'est encore différent sur windows/msvc.
    Pour résoudre ce genre de problème, il faut essayer de respecter les normes au maximum et surtout tester la compilation sur les différentes toolchains. Tester toutes les toolchains à la main sur sa machine est plutôt difficile. Une meilleure solution est de mettre en place de l'intégration continue avec TravisCI, Appveyor, Gitlab-CI ou autres.

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Et aussi étudier les réglages de la chaine de compilation.
    Il y a souvent une option pour choisir la norme à utiliser, mais elle n'est pas la même pour tous les compilateurs.

    Il peut aussi y avoir des différences entre les versions d'un même compilateur.

  6. #6
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Merci de vos réponses

    Citation Envoyé par Bousk Voir le message
    - la compilation n'est pas propre a l'OS mais a la chaine de compilation (qui varie d'un OS a l'autre, mais au sein d'un meme OS egalement)
    la liste continue et s'etoffe au fur et mesure des experiences
    Hum oui c'est bien là le souci: l'expérience ... seabirds apt-get update experience
    Citation Envoyé par SimonDecoline
    Tester toutes les toolchains à la main sur sa machine est plutôt difficile. Une meilleure solution est de mettre en place de l'intégration continue avec TravisCI, Appveyor, Gitlab-CI ou autres.
    Mhh ok depuis quelques mois déjà je sentais venir le moment où mes scripts bash lancés à la main pour les tests allait atteindre une limite. J'ai jeté un coup d'oeil à TravisCI, et j'avoue que je n'arrive pas à savoir si c'est overkill, ou si je peux facilement le mettre en place. Je vais regarder d'un peu plus près merci. Pour l'instant, j'ai une solution faite à la main un peu dégueu ou des scripts bash s'appellent en cascade à travers les différents modules de la lib pour compiler/exécuter des fichiers de tests. Franchement à une époque j'étais assez fier du service rendu à ma communauté de 1 personne, mais là ça me saoule assez clairement, notamment parce que:
    • le nombre de scripts bash explose ces derniers temps, puis c'est relou à écrire.
    • que ces tests mélangent un peu deux buts à la fois: i) fournir un code simple et fonctionnel d'exemple d'utilisation pour la classe, et ii) tester le code avec des asserts un peu dégueu. Du coup je fais un compromis et au final c'est pas super rigoureux.
    • que ma collabratrice a tout un pan des tests qui marchent pas à cause d'une option -I écrite en dur dans la commande de compilation des scripts bash.

    Moui en écrivant ces lignes ça devient assez évident qu'il faut changer ça

    Citation Envoyé par Bktero
    son compilateur réglé en mode paranoïaque
    g++ -o UTest -Wall -std=c++17 test.cpp c'est assez paranoïaque ?

    Ternel: Les réglages de la chaîne de compilation... Je vais chercher ça merci

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Seabirds Voir le message
    g++ -o UTest -Wall -std=c++17 test.cpp c'est assez paranoïaque ?
    Euh non ça c'est le minimum vital

    En ce moment je compile avec ça :
    -pedantic
    -Wall
    -Wextra

    -Wsuggest-override

    -Wold-style-cast
    -Wuseless-cast

    -Wdouble-promotion

    -Wmissing-declarations
    -Wshadow=compatible-local

    -Wswitch-default
    -Wswitch-enum
    Si tu veux vraiment te faire mal, regarde ce dépôt Github qui te donne des listes d'options pour différents compilateurs https://github.com/jonathanpoelen/cpp-compiler-options Au hasard (presque), utilise cette gcc-8.0-warnings_strict:
    -pedantic
    -pedantic-errors
    -Wall
    -Wextra
    -Wcast-align
    -Wcast-qual
    -Wdisabled-optimization
    -Wfloat-equal
    -Wformat-security
    -Wformat-signedness
    -Wformat=2
    -Wmissing-declarations
    -Wmissing-include-dirs
    -Wnon-virtual-dtor
    -Wold-style-cast
    -Woverloaded-virtual
    -Wpacked
    -Wredundant-decls
    -Wundef
    -Wuninitialized
    -Wunused-macros
    -Wvla
    -Wconversion
    -Wswitch-default
    -Wswitch-enum
    -Wsuggest-attribute=noreturn
    -Wzero-as-null-pointer-constant
    -Wlogical-op
    -Wvector-operation-performance
    -Wdouble-promotion
    -Wtrampolines
    -Wuseless-cast
    -Wconditionally-supported
    -Wfloat-conversion
    -Wopenmp-simd
    -fsized-deallocation
    -Warray-bounds=2
    -Wconditionally-supported
    -Wnoexcept
    -Wsized-deallocation
    -Wstrict-null-sentinel
    -Wsuggest-override
    -Wduplicated-cond
    -Wnull-dereference
    -Waligned-new
    -Walloc-zero
    -Walloca
    -Wformat-overflow
    -Wshadow=compatible-local
    -Wclass-memaccess
    -Wsign-conversion
    -Wcast-align=strict

  8. #8
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour,

    Je rejoins Bktero : il faut plus d'avertissements que -Wall.

    En fait, le nom -Wall est trompeur, car il n'active pas tous les avertissements.
    D'ailleurs, avec GCC, il n'est pas souhaitable d'activer tous les avertissements qui existent car, par exemple, il existe même -Wtemplates qui râle quand on déclare un template et -Wnamespaces qui râle quand on écrit du code dans un espace de nom !

    Avec GCC, je conseille d'utiliser au moins -Wall -Wextra -pedantic-errors ainsi que -Winvalid-pch si tu as des entêtes précompilés.

    Personnellement, j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    -Wall -Wextra -pedantic-errors -Winvalid-pch -Wshadow -Weffc++
    -Wold-style-cast -Wconversion -Woverloaded-virtual -Wpointer-arith
    -Wzero-as-null-pointer-constant -Winit-self -Wredundant-decls -Wcast-align
    -Wfloat-equal -Wunreachable-code -Wmissing-include-dirs
    Cela dit, l'inconvénient des listes d'avertissements à rallonge comme la mienne, c'est que, quand on inclut des entêtes codés par d'autres personnes, on se ramasse plein d'avertissements dans la tronche. Par exemple, voici un extrait d'un de mes codes, simplement pour inclure un entête de Boost :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Weffc++"
    #pragma GCC diagnostic ignored "-Wold-style-cast"
    #pragma GCC diagnostic ignored "-Woverloaded-virtual"
    #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
    # include <boost/test/unit_test.hpp>
    #pragma GCC diagnostic pop

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Seabirds Voir le message
    Mhh ok depuis quelques mois déjà je sentais venir le moment où mes scripts bash lancés à la main pour les tests allait atteindre une limite.
    J'aime beaucoup le bash mais pour compiler/tester un projet, ça ne me semble plus trop adapté aujourd'hui. Tu ne peux pas faire tes tests via le système de build + tests unitaires (genre cmake + google-test) ?

  10. #10
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Citation Envoyé par SimonDecoline Voir le message
    Tu ne peux pas faire tes tests via le système de build + tests unitaires (genre cmake + google-test) ?
    Bonne question. Je ne fais jamais de cmake parce que ma lib c'est juste un petit paquet de headers a inclure dans le main.cpp , que je compile a la main.

    Comme tout est template, j'ai des petits fichiers de tests du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    // Compiles with g++ -o test merger_test.cpp -std=c++14 -Wall
     
    #include "../../merger.h" // le code a "tester"
     
    //! [Example]
     
    #include <vector>
    #include <list>
    #include <string>
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <random>
    #include <cassert>
     
    int main () {
     
      using node_type = std::string;
      using quetzal::coalescence::occupancy_spectrum::on_the_fly;
      using SMM = quetzal::coalescence::SimultaneousMultipleMerger<on_the_fly> ;
     
      std::vector<node_type> nodes = {"a", "b", "c", "d"};
     
      unsigned int N = 3;
     
      std::mt19937 gen;
     
      std::cout << "\nNodes at sampling time :\n";
      std::copy(nodes.begin(), nodes.end(), std::ostream_iterator<node_type>(std::cout, "\n"));
      std::cout << "\n";
     
      auto last = SMM::merge(nodes.begin(), nodes.end(), N, gen);
     
      std::cout << "\nAfter one simultaneous multiple merge generation:\n";
      for(auto it = nodes.begin(); it != last; ++it){
        std::cout << *it << std::endl;
      }
     
      return 0;
    }
     
    //! [Example]
    Un ficher bash compile, l’exécute, enregistre l'output. L'output et le code source sont récupérés par Doxygen.

    On est bien d'accord que c'est assez éloigné du test unitaire idéal et c'est sans doute crado, mais bon, ça m'a jusque la permis a moindre coût de tester des modules indépendamment les uns des autres tout en pouvant retourner dans la doc voir comment utiliser telle ou telle classe, tout en me permettant de tester tous les modules avec un petit ./run_all_tests avant de merger mes betises sur la branche master du depot git.

    Ma nature paranoïaque (pas encore assez pour le compilo semble-t-il) m’encourage a mettre des asserts partout et a vérifier chaque fonction, et les attendus statistiques des simulations, ce que j'ai fait dans certains cas qui fleurait bon le casse-gueule, mais pas partout non plus parce que [ironie]des tests unitaires complets c'est un luxe que je ne peux pas me permettre et puis ça ruinerait la doc [/ironie].

    Voila pour ce que j'ai fait, mais je ne sais pas comment j'aurais du procéder au mieux. Ce qui est certain c'est que aujourd'hui ce bricolage ne tient plus bien la route. La petite ligne de compilation me semblait tellement minimaliste qu'utiliser Cmake pour ça me paraissait un peu accablant en comparaison.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Delphi 7 update 1 - Erreur de compil sur SQLExpr
    Par RamDevTeam dans le forum Bases de données
    Réponses: 14
    Dernier message: 02/11/2005, 17h44
  2. Même liste sur 26 pages différentes
    Par krfa1 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 8
    Dernier message: 18/03/2005, 11h32
  3. [CR7] état sur un disque différent du crystal web serv
    Par shadowR dans le forum SAP Crystal Reports
    Réponses: 10
    Dernier message: 23/12/2004, 15h44
  4. Somme de 3 COUNT() sur 3 tables différentes
    Par PyRoFlo dans le forum Langage SQL
    Réponses: 9
    Dernier message: 13/08/2004, 18h36
  5. [Eclipse][Java]Problème de compilation sur CTRL+S
    Par ZeKiD dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 27/05/2004, 11h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo