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 :

Soucis de compilateurs


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur Etudes
    Inscrit en
    Juillet 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Etudes

    Informations forums :
    Inscription : Juillet 2010
    Messages : 54
    Par défaut Soucis de compilateurs
    Bonjour,

    J'ai développé un programme quelconque (pour l'instant...) qui fait appel à Qt, juste un simple affichage de courbes.
    Sous système Unix, avec Qt Creator, j'ai eu aucun souci pour le compiler, ni pour le lancer. Que ce soit directement par ligne de commande ou bien via Qt Creator.

    Sous Windows, c'est beaucoup plus compliqué.
    J'utilise MSVC 2019/64-bit et Qt-Creator (qui lui peut choisir son compilateur), à partir de CMakeFiles.
    Voilà les soucis que je rencontre :
    • Sous MSVC, j'ai une erreur d'édition de lien
    • Sous QtCreator avec MSVC comme compilateur, j'ai plusieurs erreur d'éditions de lien
    • Avec CMake-gui et mingw32-make, j'ai des erreurs de compilation au niveau des .h d'une bibliothèque (que je n'ai pas ailleurs)

    Il n'y qu'avec QtCreator avec son MinGW-64bit que ça marche, et encore...seulement quand je lance le programme dans l'environnement. En dehors il ne trouve pas les .dll (certes je peux les ajouter au %PATH).

    Dès lors je ne sais pas trop comment m'en tirer sans trop bricoler de choses. Je voudrais que malgré les quelques bibliothèques présentes et nécessaires, un utilisateur puisse facilement à partir de mon code source et mon CMakeList (ci-dessous) compiler et lancer le programme. D'autant que les erreurs que je liste, je ne sais pas comment les résoudre, chaque environnement ayant sa logique.
    Le CMakeList.txt
    Code CMakeLists : 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
    cmake_minimum_required(VERSION 3.10)
     
    project(testQCustomPlot LANGUAGES CXX)
     
    set(CMAKE_CXX_STANDARD 14)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
     
    # Find the QtWidgets library
    find_package(Qt5Widgets)
    find_package(Qt5PrintSupport)
     
    add_compile_definitions(QCUSTOMPLOT_USE_LIBRARY)
    if (CMAKE_BUILD_TYPE STREQUAL "Debug")
        message(${CMAKE_BUILD_TYPE})
        if (UNIX)
            set(LINK_LIB_PLOT "${CMAKE_CURRENT_SOURCE_DIR}/libqcustomplotd.so")
        elseif(WIN32)
            set(LINK_LIB_PLOT "${CMAKE_CURRENT_SOURCE_DIR}/libqcustomplotd2.a")
        endif()
    else()
        if (UNIX)
            set(LINK_LIB_PLOT "${CMAKE_CURRENT_SOURCE_DIR}/libqcustomplot.so")
        elseif(WIN32)
            set(LINK_LIB_PLOT "${CMAKE_CURRENT_SOURCE_DIR}/libqcustomplot2.a")
        endif()
    endif()
     
    add_executable(testQCustomPlot main.cpp qcustomplot.h)
     
    #find_package(Armadillo REQUIRED PATHS "C:/Project/armadillo-9.900.2")
    message(status "${PROJECT_SOURCE_DIR}")
    set (ARMADILLO_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include_arma")
    set (ARMADILLO_LIBRARIES "${PROJECT_SOURCE_DIR}/ext_lib/libarmadillo.a")
    include_directories(${ARMADILLO_INCLUDE_DIRS})
    target_link_libraries(testQCustomPlot Qt5::Widgets Qt5::PrintSupport ${LINK_LIB_PLOT} ${ARMADILLO_LIBRARIES})

    Et le code :
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    #include <iostream>
    #include <memory>
    #include <QApplication>
    #include <QDialog>
    #include "qcustomplot.h"
    #include <armadillo>
     
    using namespace std;
     
    void convertToVectorDouble(const arma::vec Avec, std::vector<double> &Aout);
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QDialog window;
        QCustomPlot customPlot;
        QVBoxLayout *mainLayout = new QVBoxLayout();
        QPushButton *buttonQuit = new QPushButton("Quit");
        mainLayout->addWidget(buttonQuit);
        mainLayout->addWidget(&customPlot);
        window.setLayout(mainLayout);
        // setup customPlot as central widget of window:
        arma::arma_rng::set_seed_random();
        // generate data
        arma::mat Tvalrand = arma::randn(1000,1);
        arma::vec Tsamples(Tvalrand.n_rows);
        Tsamples = Tvalrand.col(0);
        arma::uvec histVal(50);
        arma::vec histValD(50);
        std::vector<double> histValVec(50);
        std::vector<double> abcissesVec(50);
     
        double xmin = Tsamples.min();
        double xmax = Tsamples.max();
        double step = (xmax - xmin)/50;
        histVal = arma::hist(Tsamples, 50);
        histValD = arma::conv_to<arma::vec>::from(histVal);
        histValD /= step*1000;
     
        convertToVectorDouble(histValD, histValVec);
     
        int l = 0;
        double step_2 = (xmax - xmin)/(50-1);
        std::generate(abcissesVec.begin(), abcissesVec.end(), [&] () -> double {return xmin+(l++)*step_2;} );
        abcissesVec.back() = xmax;
     
        // create plot (from quadratic plot example):
        QVector<double> x(50), y(50);
        x = QVector<double>::fromStdVector(abcissesVec);
        y = QVector<double>::fromStdVector(histValVec);
     
        // layouts
        customPlot.plotLayout()->clear();
        QCPLayoutGrid *subLayout = new QCPLayoutGrid;
        QCPAxisRect *leftAxis = new QCPAxisRect(&customPlot);
        QCPAxisRect *rightAxis = new QCPAxisRect(&customPlot);
        customPlot.plotLayout()->addElement(0,0,subLayout);
        subLayout->addElement(0, 0, leftAxis);
        subLayout->addElement(0, 1, rightAxis);
     
        QCPGraph *leftGraph = customPlot.addGraph(leftAxis->axis(QCPAxis::atBottom),leftAxis->axis(QCPAxis::atLeft));
     
        leftGraph->setData(x, y);
        leftGraph->keyAxis()->setLabel("x");
        leftGraph->valueAxis()->setLabel("y");
        leftGraph->rescaleAxes();
     
        QCPGraph *rightGraph = customPlot.addGraph(rightAxis->axis(QCPAxis::atBottom),rightAxis->axis(QCPAxis::atLeft));
     
        rightGraph->setData(x, y);
        rightGraph->keyAxis()->setLabel("x");
        rightGraph->valueAxis()->setLabel("y");
        rightGraph->rescaleAxes();
     
        /*arma::mat valRandImage = arma::randn<arma::mat>(10*10,1);
        arma::vec meanA(10*10);
        std::vector<double> im2show(10*10);
        meanA = valRandImage.col(0);
        /*convertToVectorDouble(meanA, im2show);*/
        /*QCPColorMap *colorMap = new QCPColorMap(customPlot.xAxis, customPlot.yAxis);
        colorMap->data()->setSize(10, 10);
        colorMap->data()->setRange(QCPRange(0, 10), QCPRange(0, 10));
        for (int i =0; i < 10; ++i)
        {
            for (int j = 0; j < 10; ++j)
            {
                cout << 255*meanA(j+i*10) << endl;
                colorMap->data()->setCell(i,j,255*meanA(j+i*10));//(unsigned char) 255*meanA(j+i*10));
            }
        }
        colorMap->setGradient(QCPColorGradient::gpGrayscale);
        colorMap->setInterpolate(false);
        colorMap->setTightBoundary(false);
        colorMap->rescaleDataRange(true);
        customPlot.rescaleAxes();
        customPlot.replot();*/
     
        window.setGeometry(100, 100, 500, 400);
        window.show();
     
        return a.exec();
    }
     
    void convertToVectorDouble(const arma::vec Avec, std::vector<double> &Aout)
    {
        unsigned int nElem = Avec.n_elem;
        for (unsigned int i = 0; i < nElem; ++i)
        {
            Aout.at(i) = Avec(i);
        }
    }

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Il faut faire très attention, sous windows, quand on utilise des bibliothèques dynamiques sous windows (dont les bibliothèques Qt), car l'ABI (Application Binary Interface ou, si tu préfères, la manière dont une application va "dialoguer" avec les bibliothèques dont elle dépend) n'est ni standardisée ni même "un tant soit peu" stabilisée.

    Je vais te passer les détails, mais, disons juste que, pour bien faire ch...er tout le monde, utiliser une dll générée par un compilateur X (mettons: MinGW) avec une application générée par le compilateur Y (mettons: celui de Visual Studio) a toutes les chances de ne pas passer :P

    Pire encore: il y a "toutes les chances" pour que la dll compilée avec la version V1 d'un compilateur ne fonctionne pas avec une application compilée avec la version V2 (V1+1) de ce même compilateur 8O:(:?

    Il faut donc être vraiment attentif à utiliser la version de Qt qui correspond exactement au compilateur que tu utilises.

    En ce qui concerne les symptomes que tu décris:
    • Sous MSVC, j'ai une erreur d'édition de lien
    Cela signifie qu'il a trouvé le dossier contenant les fichiers d'en-tête, mais pas la bibliothèque d'importation correcte.

    Ce qui entre dans la logique de ce que je t'expliquais, étant donné que QtCreator est compilé avec MinGW et utilise les versions des dlls compilées ... par MinGW pour fonctionner

    Tu peux assez facilement ajouter la "bonne version" de Qt en choisissant la version "MSVC 2019 xx-bit" à l'aide du "MaintenanceTool.exe" qui se trouve dans le dossier racine de ton installation de Qt ;)
    • Sous QtCreator avec MSVC comme compilateur, j'ai plusieurs erreur d'éditions de lien
    Même causes, mêmes effets, mêmes solutions
    • Avec CMake-gui
    L'utilisation de CMake en version graphique ne va rien changer à l'histoire ;)
    et mingw32-make, j'ai des erreurs de compilation au niveau des .h d'une bibliothèque (que je n'ai pas ailleurs)
    Sans doute parce que tu auras fini par "foutre le bordel" à force de "chipoter" dans la configuration ... j'espère pour toi que tu as pris l'habitude de configurer ta compilation dans un dossier séparé, car, autrement, faire le ménage ne va pas se faire forcément sans peine :P ;)

    Il n'y qu'avec QtCreator avec son MinGW-64bit que ça marche, et encore...seulement quand je lance le programme dans l'environnement. En dehors il ne trouve pas les .dll.
    C'est logique:

    Lors de l'installation, Qt a le très bon gout de ne pas modifier la variable PATH, ce qui fait -- entre autres -- que, si tu lance une ligne de commande, tu ne pourras pas lancer QtCreator à partir d'elle sans, au choix:
    • avoir modifié (temporairement) la variable PATH
    • être entré dans le dossier où se trouve l'exécutable (typiqument Qt/tools/QtCreator/bin) ou
    • avoir fournis chemin complet permettant d'atteindre l'exécutable qtcreator.exe. (typiqument Qt/tools/QtCreator/bin)

    Or, si tu y regarde d'un peu plus près, tu remarquera que le dossier dans lequel se trouve QtCreator (typiqument Qt/tools/QtCreator/bin) contient exactement les mêmes dlls que celle que tu retrouve dans le dossier bin de la version de Qt que tu as installée (typiquement Qt/<version de Qt>/<compilateur>/bin), où <Version de Qt> et <compilateur> indiquent le kit utilisé dans Qt Creator.

    Cela permet à QtCreator d'utiliser son propre jeu de dll pour son propre usage (car il en a besoin pour fournir l'interface graphique ;) )

    D'un autre coté, je vais te passer les détails, mais, disons que le fait d'avoir défini un kit utilisé pour la compilation va permettre à QtCreator de modifier temporairement (en gros, le temps que ton application s'exécute ;) ) la variable PATH, afin d'en faciliter l'essai.

    Par contre, la variable PATH n'étant pas modifiée de manière "globale", toute tentative de lancer l'application générée sans passer par QtCreator (ou sans modifier la variable PATH) ne pourra qu'échouer misérablement, car les dlls requises ne seront pas trouvées :P
    (certes je peux les ajouter au %PATH)
    Oui, mais non...

    Oui, parce que:
    • à condition de choisir le dossier bin qui correspond au kit utilisé pour générer ton programme, c'est une solution simple, et rapide à mettre en oeuvre
    • je n'ai aucun ordre à te donner, au mieux quelques conseils
    • tu es une grand personne, tu fais ce que tu veux au final :D

    Mais non, parce que:
    • une modification temporaire de la variable PATH est facile en mode console, et te permettra de lancer ton application depuis l'invite de commande,
    • pour pouvoir la lancer en double cliquant dessus, il faudra modifier la varaible PATH de manière globale (dans paramètres->système->informations système->informations système->informations système avancées -> variables d'environnement), et que cela posera problème si tu te retrouve à utiliser plusieurs kits différents
    • Et surtout: ca fonctionnera chez toi, mais, quand tu voudra filer le programme à ton voisin, tu va perdre un temps bête à te demander pourquoi l'application lui sort une floppée de dll introuvables :P


    Pour t'éviter bien des problèmes, l'idéal est d'utiliser l'utilitaire windeployqt.exe qui se trouve dans le dossier bin du kit utilisé afin de lui demander de copier l'ensemble des dll nécessaires directement dans le dossier de ton application

    De cette manière, quand tu voudra filer ton programme à ton voisin, tu pourra tout mettre dans une archive et il pourra lancer ton programme sans même devoir installer Qt ;)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur Etudes
    Inscrit en
    Juillet 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Etudes

    Informations forums :
    Inscription : Juillet 2010
    Messages : 54
    Par défaut
    Merci pour cette réponse très complète !

    Il faut donc que pour ma future appli, je réfléchisse à ce que je veux distribuer avec le code source, puisque c'est l'idée.

    Comme je l'ai dit, mon appli compile bien sous Linux, et là je veux savoir ce qui se passe sous Windows. Et comme tu l'as expliqué, ce n'est pas aussi simple. Il faut que je puisse distribuer le code et aussi les .dll/.so (les .so pour le linuxien) pour que le futur utilisateur s'embête le moins possible avec les compilations et installe le moins de choses possibles également.

    Donc il faudrait que j'avertisse l'utilisateur qui utilise windows que j'ai compilé les dll avec tel compilateur, sous qtcreator...

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par fanzilan Voir le message
    Merci pour cette réponse très complète !

    Il faut donc que pour ma future appli, je réfléchisse à ce que je veux distribuer avec le code source, puisque c'est l'idée.
    Non, pas avec le code source: avec le programme exécutable!

    Si tu fournis le code source, les gens devront compiler ton code, et il devront donc installer le kit de Qt qui correspond à leur compilateur.

    A ce moment là, il s'en foute complètement du kit que tu as utilisé pour développer ton programme: Il pourraient tout aussi bien utiliser une plus ancienne version de Qt (à condition que toutes les fonctionnalités que tu utilises soient présentes) qu'une version beaucoup plus récente (qui fournira a priori toutes les fonctionnalités que tu utilises), et tout le monde sera content

    Par contre, si tu distribue ton projet en tant que "programme tout fait", les choses sont plus problématiques, parce que ton programme aura été généré par un compilateur bien particulier, et qu'il ne pourra donc fonctionner qu'avec des dlls de Qt qui ont été spécifiquement générées par ce compilateur particulier.
    Comme je l'ai dit, mon appli compile bien sous Linux,
    C'est parce que, sous linux, les choses sont beaucoup plus simples:
    on a un seul compilateur : Gcc (bon, on a aussi clang, mais ce n'est qu'un front end pour Gcc ) qui sera tout de suite correctement installé grâce au gestionnaire de paquetages

    et là je veux savoir ce qui se passe sous Windows. Et comme tu l'as expliqué, ce n'est pas aussi simple. Il faut que je puisse distribuer le code et aussi les .dll/.so (les .so pour le linuxien) pour que le futur utilisateur s'embête le moins possible avec les compilations et installe le moins de choses possibles également.
    Oh, pour cela, tu peux choisir de ne fournir que le code: il y a des gens qui préfèrent compiler leur programmes

    Cependant, cela n'a un réel intérêt que lorsque l'on souhaite participer d'une manière ou d'une autre au projet., et, du coup, si tu veux distribuer ton code, tu devra le faire avec les bibliothèques partagées / dll
    Donc il faudrait que j'avertisse l'utilisateur qui utilise windows que j'ai compilé les dll avec tel compilateur, sous qtcreator...
    Non, tu les mets toutes dans un joli paquet, avec un joli ruban, et tu les offres en cadeau avec le programme compilé, comme cela il n'aura même pas à s'en inquiéter

    Autrement dit, tu crées une archive qui contient, en plus de ton programme, les dll qu'il utilise
    (sous linux, tu fournis un paquet qui déclare sa dépendance avec telle version de Qt, et tout devrait aller bien )

    Je le répète: le problème des dll ne survient que sur le programme compilé. Si les gens prennent le code source, ils vont devoir installer le kit Qt qui correspond à leur compilateur
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. [langage]Compilateur PERL
    Par major2 dans le forum Langage
    Réponses: 4
    Dernier message: 07/02/2007, 21h52
  2. petit souci de compilateur
    Par fox_a_poil_mou dans le forum C
    Réponses: 22
    Dernier message: 19/09/2006, 20h55
  3. Compilateur - editeur C++ pour Linux
    Par Torpedox dans le forum Choisir un environnement de développement
    Réponses: 5
    Dernier message: 15/09/2002, 02h16
  4. Newbie......compilateur et table de caractères
    Par Cyberf dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 21/08/2002, 14h29
  5. Compilateur natif ??? Kesako ???
    Par Riko dans le forum Langages de programmation
    Réponses: 4
    Dernier message: 06/08/2002, 08h54

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