Partage
  • Partager sur Facebook
  • Partager sur Twitter

Utilisation de plusiques fichiers

C++ découpez votre programme en fonctions

    9 octobre 2021 à 17:33:09

    Bonjour,

    Je suis sou Visual Studio Code Sous Linux. 

    A cette partie, quand je coupe mon programme en plusieurs fichiers, j'obtiens cette erreur lors de l'execution de la commande: g++ -o test main.cpp

    /usr/bin/ld : /tmp/ccERPRzY.o : dans la fonction « main » :

    main.cpp:(.text+0x51) : référence indéfinie vers « plusDeux(int) »

    collect2: erreur: ld a retourné le statut de sortie 1

    Que faire? Merci.

    -
    Edité par Athsid 9 octobre 2021 à 17:34:34

    • Partager sur Facebook
    • Partager sur Twitter

    AthSid

      9 octobre 2021 à 18:09:10

      Salut !

      Tu as tout simplement oublié de compiler les autres fichiers cpp de ton projet.

      • Partager sur Facebook
      • Partager sur Twitter

      Si vous ne trouvez plus rien, cherchez autre chose.

        9 octobre 2021 à 18:47:01

        Salut,

        Lorsque tu veux compiler plusieurs fichiers, il faut commencer à respecter l'ordre "logique" des choses, à savoir:

        1- produire un "fichier objet" (comprend: un fichier qui contient les instructions compréhensibles par le processeur) pour chaque fichier source du projet.  C'est ce que l'on appelle la compilation proprement dite

        2- "relier" tous ces fichiers objets ensembles en y ajoutant -- en cas de besoin -- le code objet des fonctionnalités issues de bibliothèques externes (la bibliothèque standard étant considérée pour la cause comme une bibliothèque externe) afin de générer l'exécutable.  C'est ce que l'on appelle "l'édition de liens".

        La première étape devra clairement indiquer au travers de la ligne de commande au compilateur que l'on veut uniquement qu'il génère le fichier objet et que l'on ne veut surtout pas qu'il essaye de générer l'exécutable (qui ne serait pas complet sans les autres fichiers), et, pour ce faire, il "suffit" d'ajouter l'option -c (ex $ g++ -c nom_du_fichier.cpp ).

        Cela aura pour effet de provoquer la génération d'un fichier objet nommé nom_du_fichier.o (ou nom_du_fichier.obj, ou d'autres variations) à partir du code que l'on trouve dans le fichier nom_du_fichier.cpp.  Mais Gcc s'arrêtera là ;)

        Et, bien sur, il faudra faire cela avec l'ensemble des fichiers d'implémentations (tous les fichiers *.cpp de ton projet).

        Ce n'est qu'une fois que tu auras généré un fichier objet pour chacun des fichiers d'implémentation de ton projet que tu pourras envisager de rassembler tous ces fichiers dans l'exécutable final.

        Et, pour ce faire, il faudra relancer une Gcc en lui indiquant l'ensemble des noms des fichiers objets qu'il doit utiliser (ex: gcc -c fichier_1.o fichier2.o -o nom_executable ).

        Mais tout cela va rapidement devenir particulièrement lourd à gérer à la main, et ce, d'autant plus qu'il y aura très vite une quantité impressionnante d'autres options à rajouter à la ligne de commande (comme des symboles à définir, des dossiers à prendre en compte lors de la recherche  de fichiers d'en-tête ou lors de la recherche de bibliothèques externes, j'en passe et sans doute de meilleures...)

        L'idéal est donc de très rapidement passer à un système de "gestion de projet" qui te permettra plus facilement de refaire sans cesse les mêmes choses (compiler les fichiers d'implémentation, mais uniquement si leur contenu final a été modifié, générer l'exécutable ou les bibliothèques à partir des fichiers objets, et recommencer :D ) tout en pouvant "assez facilement" apporter des modifications au projet (ajouter un nouveau fichier, ajouter une bibliothèque externe comme dépendance, envisager la création d'un paquet d'installation, j'en passe et de meilleures)

        Le gestionnaire de projets qui est normalement utilisé par VisualStudio code est -- me semble-t-il -- CMake, ce qui est très bien, parce que c'est celui que l'on conseille avec le plus d'entrain pour l'instant.

        L'idée de cet outil (il faudra l'installer, si tu est sous debian like, à l'aide de la commande $ sudo apt install cmake cmake-qt-gui ) nécessite un fichier nommé CMakeLists.txt dans chaque dossier faisant partie du projet et qui contient les informations dont cmake a besoin pour fonctionner.

        Pour un projet "basique", dont tous les fichiers sont mis "en vrac" dans le même dossier, ce fichier pourrait ressembler à quelque chose comme

        #forcer une version minimale de CMake
        cmake_minimum_required(VERSION 3.11)
        # les informations de base du projet:
        # son nom, sa versions (majeure.mineure.patch.tweak) et
        # les langages utilisés (CXX == C++ )
        project(nom_du_project VERSION 1.0.0.0 LANGUAGES CXX)
        # pour forcer l'utilisation d'une norme particulière de C++
        # ici, c'est C++17, sans les extensions du compilateur, et 
        # c'est obligatoire
        set(DEFAULT_CXX_STANDARD 17)
        set(CMAKE_CXX_EXTENSIONS OFF)
        set(CMAKE_CXX_STANDARD_REQUIRED ON)
        # par facilité, on crée une liste des fichiers d'en-tête
        # spécifiques au projet
        set(HEADERS en-tete_1.hpp
                    en-tete_2.hpp
                    # ...
                    en-tête_n.hpp)
        # par facilité, on crée une liste des fichiers 
        # d'implémentation du projet
        set(SRCS fichier_1.cpp
                fichier_2.cpp
                # ... 
                fichier_n.cpp)
        
        #si on veut directement avoir l'exécutable
        add_executabl(nom_programme ${SRC} ${HEADERS})
        # si on a des dossier include à rajouter
        target_include_directories(nom_programme PUBLIC chemin_vers_dossier_include)
        # si on a des bibliothèques externes à rajouter
        target_link_libraries(nom_programme PUBLIC nom_bibliotheque)
        
        

        Après, il y a tout plein d'astuces sympa à connaitre... mais, si tu pars déjà de ce canevas de base, tu devrais pouvoir arriver déjà assez loin (en attendant d'avoir le temps de t'intéresser un peu d'avantage à CMake :D) ;)

        • Partager sur Facebook
        • Partager sur Twitter
        Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
          9 octobre 2021 à 19:16:55

          Koala01 et dragonjoker,

          Merci pour vos réponses.

          Cependant, Koala01, je débute aussi bien en c++ qu'en linux. Ce que tu me dit pourra, je le pense, etre d'une grande aide, si tu me simplifie tes explications, car je ne comprend pas ces mots techniques.

          Pourrais-tu te reformuler stp?

          Merci.

          • Partager sur Facebook
          • Partager sur Twitter

          AthSid

            10 octobre 2021 à 1:21:41

            C'est quels mots qui coincent dans l'explication de @koala01 ?
            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              10 octobre 2021 à 2:40:59

              La réponse courte est:

              g++ -o test main.cpp autre_fichier.cpp

              Mais je recommande fortement d'utiliser CMake avec VSCode, donc reviens lire ce qu'a expliqué koala01 quand tu en auras marre d'écrire à la main des lignes de commande gcc et tout recompiler à chaque fois (ça arrivera vite).

              • Partager sur Facebook
              • Partager sur Twitter
                10 octobre 2021 à 2:51:06

                Je pense que l'utilisation d'un makefile risque d'être compliquée pour un débutant tant sur Linux que sur C++
                Je vais essayer de résumer, pour chaque fichier de ton projet, tu fais:
                g++ -c fichier1.cpp
                g++ -c fichier2.cpp
                ... jusqu'au dernier
                Ça va te produire des fichiers: fichier1.o, fichier2.o ...
                Tu génère l'éxécutable avec:
                g++ -o nom_du_programme fichier1.o fichier2.o ... autres options si requis comme -Wall -Wextra
                Tu devrais obtenir un exécutable correct.
                Ça fait longtemps que je ne suis pas allé sur Linux (ou Unix). Il pourrait y avoir des paramètres -l*  ou '*' est le suffixe.
                Par exemple, pour la bibliothèque math, on a besoin de libm et on écrit -lm
                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  10 octobre 2021 à 10:17:16

                  Athsid a écrit:

                  car je ne comprend pas ces mots techniques.


                  As tu lu ce qu'il y a entre parenthèses?car la plupart des termes "techniques" sont expliqués en quelques morts de cette manière

                  Athsid a écrit:

                  Pourrais-tu te reformuler stp?

                  D'accord, mais il faudra être plus précis sur les termes que tu ne comprends pas, pour que je puisse cibler mes explications ;)

                  Retiens deux choses de primordiales en programmation (de manière générale):

                  1- il n'y a qu'en étant le plus précis possible sur ce que l'on souhaite obtenir que l'on arrive à obtenir exactement le résultat souhaité.

                  Toute demande "plutôt vague" comme "peux tu reformuler" devra donc venir avec des précision sur ce que l'on veut exactement :p

                  2- Lorsque tu viens sur un forum pour demander de l'aide, les gens à qui tu t'adresse ne savent absolument pas sur quoi tu travaille, ce que tu as pu tenter avant de venir poser ta question et, encore moins, ce que tu as exactement en tête

                  Certains recours à de boules de crystal pour deviner avec un taux d'erreur "raisonnable" ce que tu ne nous dis pas forcément.  Malheureusement, elles ne sont plus produites depuis longtemps, et les derniers exemplaires existants commencent à déconner de plus en plus et sont impossibles à remplacer :p

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                    14 octobre 2021 à 8:34:03

                    Pour simplifier la compilation et ne pas avoir à compiler chaque fichier cpp un par un le plus simple est de procéder comme suit:

                    - Dans ton dossier principal tu créés le fichier main.cpp 

                    - tu crées un src dans lequel tu mets tous les autres fichiers .cpp

                    - tu créés un dossier include dans lequel tu mets les fichiers .h

                    et tu compiles de cette façon

                    g++ main.cpp src/*.cpp -I include -o main -Wall -Wextra

                    Pour aller plus sur avec vscode ;

                     https://code.visualstudio.com/docs/cpp/config-linux

                    https://code.visualstudio.com/docs/editor/variables-reference

                    https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference

                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 octobre 2021 à 14:16:21

                      PierrotLeFou a écrit:

                      Je pense que l'utilisation d'un makefile risque d'être compliquée pour un débutant tant sur Linux que sur C++
                      Je vais essayer de résumer, pour chaque fichier de ton projet, tu fais:
                      g++ -c fichier1.cpp
                      g++ -c fichier2.cpp
                      ... jusqu'au dernier
                      Ça va te produire des fichiers: fichier1.o, fichier2.o ...
                      Tu génère l'éxécutable avec:
                      g++ -o nom_du_programme fichier1.o fichier2.o ... autres options si requis comme -Wall -Wextra


                      Les options -Wall et -Wextra, c'est plutôt pour les compilations séparées des fichiers sources

                      g++ -c fichier1.cpp -Wextra -Wall
                      g++ -c fichier2.cpp -Wextra -Wall
                      ...

                      Mais bon, la compilation séparée + édition des liens + gestion des dépendances, c'est peut-être une notion à repousser à un peu plus tard, si on veut éviter la surcharge cognitive, ennemie de l'apprentissage.

                      Le plus simple :

                      • on utilise un répertoire pour chaque projet
                      • dans ce répertoire, on compile tout par
                      g++ -o nom-de-l-executable -Wall -Wextra *.cpp

                      -
                      Edité par michelbillaud 14 octobre 2021 à 14:19:51

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Utilisation de plusiques fichiers

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      • Editeur
                      • Markdown