Home > other >  Mac Link .h file to .cpp files
Mac Link .h file to .cpp files

Time:11-19

I'm a student and have just been introduced to modularity in cpp. I don't understand my mistake though.

I have 3 files.

One test.cpp

/**\
  * @file   testFile.cpp
  * @author TomPlanche
  * @brief  test file links
\**/

// . Importation Des Bibliothèques Nécessaires.
#include <iostream>
#include "fraction.h"


int main(void) {
    /**\
      * @goal                           :  test file links
      * @author :                       :  T.Planche
      * @remarks                        :  non
    \**/

    // ! Déclaration Variables
    Fraction frac1 = {1, 2};

    cout << frac1.denominateur << endl;


    return 0;
}

One fraction.cpp

/**\
  * @file   fraction.cpp
  * @author TomPlanche
  * @brief  Exercice TD2 R1.01/PT2
\**/

// ! Importation Des Bibliothèques Nécessaires.
#include "fraction.h"


// ! Définition Sous-Programmes
int pgcd(int nb1, int nb2) {
    int min = (nb1 < nb2) ? nb1 : nb2;

    for (int i = min; i <= min; i--) {
        if ((nb1 % i == 0) && (nb2 % i == 0)) {
            return i;
        }
    }
    return 1;
}


Fraction simplifier(const Fraction fraction) {
    /**\
      * @goal                           :  simplifier une fraction
      * @author :                       :  T.Planche
      * @remarks                        :  aucune
    \**/
    
    Fraction fractionFinale;
    int pgdcFraction;

    pgdcFraction = pgcd(fraction.numerateur, fraction.denominateur);
    
    fractionFinale.numerateur = fraction.numerateur / pgdcFraction;
    fractionFinale.denominateur = fraction.denominateur / pgdcFraction;

    return fractionFinale;
}


Fraction addition(Fraction frac1, Fraction frac2) {
    Fraction fractionResultat;

    if (frac1.denominateur == frac2.denominateur) {
        fractionResultat.denominateur = frac1.denominateur;
        fractionResultat.numerateur = frac1.numerateur   frac2.numerateur;
    } else {
        fractionResultat.denominateur = frac1.denominateur*frac2.denominateur;
        fractionResultat.numerateur = frac1.numerateur*frac2.denominateur   frac2.numerateur*frac1.denominateur;
    }

    return fractionResultat;
}

void afficherFraction(const Fraction fraction) {
    Fraction fractionSimplifiee = simplifier(fraction);

    cout << fractionSimplifiee.numerateur << "/" << fractionSimplifiee.denominateur << endl;
}

and one fraction.h

#ifndef FRACTION_H
#define FRACTION_H

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

struct Fraction {
    int numerateur; // Le signe est porté sur ce nombre
    unsigned int denominateur; // > 0
};

int pgcd(int nb1, int nb2);
//! @goal : Retourne Le Pdcg De Deux Entiers

Fraction simplifier(Fraction fraction);
//! @goal : Simplifier Une Fraction

Fraction addition(Fraction frac1, Fraction frac2);
//! @goal : Additionner Deux Fractions

Fraction soustraction(Fraction frac1, Fraction frac2);
//! @goal : Soustraire Deux Fractions

Fraction multiplication(Fraction frac1, Fraction frac2);
//! @goal : Multiplier Deux Fractions

Fraction division(Fraction frac1, Fraction frac2);
//! @goal : Diviser Deux Fractions

void afficherFraction(const Fraction fraction);
//! @goal : Afficher Une Fraction


#endif

When I try to add just a Fraction frac1 = {1, 2}; it compiles. But when I try to afficherFraction I have

cd "/Users/tom_planche_mbpm1/Desktop/BUT/R1.01-IntroDev/PT2/TD2/" && g   testFile.cpp -o testFile && "/Users/tom_planche_mbpm1/Desktop/BUT/R1.01-IntroDev/PT2/TD2/"testFile
Undefined symbols for architecture arm64:
  "simplifier(Fraction)", referenced from:
      _main in testFile-8df18c.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I'm on a MacBook Pro M1 on macOS Monterey (21C5031d)

Thanks !

CodePudding user response:

You build your executable with:

g   testFile.cpp -o testFile

but you're forgetting the second source file. You can either do everything in one line:

g   testFile.cpp fraction.cpp -o testFile

but with an eye on the future, when your program may become much larger, it's a better idea to use separate compilation:

g   -c testFile.cpp 
g   -c fraction.cpp
g   testFile.o fraction.o -o testFile

When you start using a build system (Make, Cmake) this is the way it will be done: compile only whatever file needs recompiling, and then link them together.

Btw, it's a good idea to add a couple of compiler flags, such as -g -O2. The first one makes debugging possible in gdb and such, the second one says "make optimized code".

  • Related