Search code examples
c++makefilemultiple-definition-error

(Makefile Error) Multiple definitions errors


Basically I'm trying to create a makefile for the project I'm currently working on. The error suggests that I've defined the same function twice in two different files.

The error repeats throughout with many function but to simple things down I'll only put one of them and try to fix the others on my own, as I'll understand what is going on.

This is the MakeFile code:

BIN=bin
INC=includes
OBJ=obj
LIB=lib
SRC=src

all : bin/main

$(OBJ)/utilidades.o: $(SRC)/utilidades.cpp $(INC)/utilidades.h
    g++ -c -o $(OBJ)/utilidades.o -I$(INC) $(SRC)/utilidades.cpp

$(OBJ)/main.o: $(SRC)/main.cpp $(INC)/utilidades.h 
    g++ -c -o $(OBJ)/main.o -I$(INC) $(SRC)/main.cpp

$(BIN)/main: $(OBJ)/main.o $(OBJ)/utilidades.o
    g++ -o $(BIN)/main $(OBJ)/main.o $(OBJ)/utilidades.o

cLean:
    echo "Cleaning Objects..."
    rm $(OBJ)/*.o

mrproper: clean
    rm 
    $(BIN)/main

This is the MakeFile output

g++ -o bin/main obj/main.o obj/utilidades.o
obj/utilidades.o: In function `mostrar(double*, int)':
utilidades.cpp:(.text+0x0): multiple definition of `mostrar(double*, int)'
obj/main.o:main.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
Makefile:16: recipe for target 'bin/main' failed
make: *** [bin/main] Error 1```

So I've been looking for those functions being declared in main.cpp:

#include <iostream>
#include "utilidades.cpp"

using namespace std;





int main(){

    bool salir = false;
    char hold;
    int util1, util2, util3;
    double vtr_num1[100], vtr_num2[100], vtr_num3[200];
    double *ptr_vtr_num1, *ptr_vtr_num2, *ptr_vtr_num3;
    ptr_vtr_num1 = vtr_num1;
    ptr_vtr_num2 = vtr_num2;
    ptr_vtr_num3 = vtr_num3;

    cout << "       _               _      _       _____" << endl;
    cout << "  ___ (_) ___ _ __ ___(_) ___(_) ___ |___ /" << endl;
    cout << " / _  | |/ _ | '__/ __| |/ __| |/ _    |_  " << endl;
    cout << "|  __/| |  __| | | (__| | (__| | (_)  ___) |" << endl;
    cout << "|_____/ |____|_| |____|_| ___|_| ___/|____/" << endl;
    cout << "    |__/" << endl;


    while(!salir){

        cout << "\n\n\nCuantos numeros va a introducir en el primer vector: ";
        cin >> util1;
        cout << "\n Introduzcalos: ";

        for(int i=0; i<util1; i++){
            cin >> *(ptr_vtr_num1 + i);
        }
        cout << "\n El vector 1 es: ";
        mostrar(ptr_vtr_num1, util1);

        cout << "\n Cuantos numeros va a introducir en el segundo vector: ";
        cin >> util2;

        cout << "\n Introduzcalos: ";
        for(int i=0; i<util2; i++){
            cin >> *(ptr_vtr_num2 + i);
        }

        cout << "\n El vector 2 es: ";
        mostrar(ptr_vtr_num2, util2);
        cout << endl;

        mezclarUnico(util1, util2, util3, ptr_vtr_num1, ptr_vtr_num2, ptr_vtr_num3);


        cout << "Quiere salir? (s/n)";
        cin >> hold;
        if(hold == 's' || hold == 'S'){
            salir = true;
        }
    }


    return 0;

}

But as you can see they are never declared in main.cpp, only called.ç

The only places I declare them at are in my utilities.h (translated from utilidades.h for understanding purposes):

#include <iostream>
#ifndef UTILIDADES_H
#define UTILIDADES_H

void mostrar(double *ptr_vtr, int util);

int concatenar(int util1, int util2, double *ptr_vtr_num1, double *ptr_vtr_num2, int &util3, double *ptr_vtr_num3);

void eliminardobles(double *ptr_vtr_num, int &util);

void ordenador(double *ptr_vtr_num, int util);

void mezclarUnico(int util1, int util2, int util3, double * ptr_vtr_num1, double* ptr_vtr_num2, double* ptr_vtr_num3);

#endif

And my utilities.cpp (translated as before from utilidades.cpp):

#include <iostream>
#include "utilidades.h"

using namespace std;

/**
 * Muestra los valores de un vector
 * @param ptr_vtr el puntero al vector
 * @param util el tamanio del vector
 */
void mostrar(double *ptr_vtr, int util){
    for(int i=0; i < util; i++){        
        cout << *(ptr_vtr+i) << ", ";
    }
}


/**
 * Concatena dos vectores en uno 3o.
 * @param util tamanio de los vectores.
 * \param ptr_vtr_num punteros a los vectores.
 */
int concatenar(int util1, int util2, double *ptr_vtr_num1, double *ptr_vtr_num2, int &util3, double *ptr_vtr_num3){

    for(int i=0; i<util1; i++){
        *(ptr_vtr_num3 + i) = *(ptr_vtr_num1 + i); 
    }

    for(int i=0; i<util2; i++){
        *(ptr_vtr_num3 + util1 + i) = *(ptr_vtr_num2 + i);
    }

    util3 = util1+util2;

}

/**
 * Elimina los dobles de un vector, suponiendo que estan ordenado
 * @param ptr_vtr_num El puntero que apunta al primer valor del vector a eliminar los dobles.
 * @param util El tamanyo del vector a ordenar, se pasa por referencia para guardar el tamanio despues de haber eliminado los dobles.
 */
void eliminardobles(double *ptr_vtr_num, int &util){
    for(int i=0; i<util-1; i++){
        if(*(ptr_vtr_num + i) == *(ptr_vtr_num + i + 1)){
            for(int j=i; j<util-1; j++){
                *(ptr_vtr_num + j) = *(ptr_vtr_num + j + 1);
            }
            util--;
            i--;                //Esta es la clave para que siga comparando por si acaso hay mas para que aunque se repita mas de dos veces las reconozca.
        }
    }
}

/**
 * Ordena los valores de un vector de doubles.
 * @param ptr_vtr_num El puntero al vector a ordenar
 * @param util Tamanio del vector
 */
void ordenador(double *ptr_vtr_num, int util){
    double aux;
    for(int j=0; j<util-1; j++){
        for(int i=0; i<util-1-j; i++){
            if(*(ptr_vtr_num + i) > *(ptr_vtr_num + i + 1)){
                aux = *(ptr_vtr_num + i);
                *(ptr_vtr_num + i) = *(ptr_vtr_num + i + 1);
                *(ptr_vtr_num + i + 1) = aux;
            }
        }
    }
}

/**
 * Aprovecha las funciones anteriores para mezclar dos vectores en uno tercero de forma qeu no se repitan valores
 * @param util Tamanios de los vectores
 * @param ptr_vtr_num Los punteros a los vectores
 */
void mezclarUnico(int util1, int util2, int util3, double * ptr_vtr_num1, double* ptr_vtr_num2, double* ptr_vtr_num3){

    cout << "\nConcatenando..." << endl;
        concatenar(util1, util2, ptr_vtr_num1, ptr_vtr_num2, util3, ptr_vtr_num3);



        cout << "\nOrdenando..." << endl;
        ordenador(ptr_vtr_num3, util3);

        cout << "\nEliminando dobles...\n\n------------------------------\n" << endl;
        eliminardobles(ptr_vtr_num3, util3);

        cout << "\nTam. resultante de mezclar ambos arrays: " << util3;
        cout << "\nEl vector final es: ";
        mostrar(ptr_vtr_num3, util3);
        cout << "\n\n";


}

So why is this error being caused then and how may I fix it?


Solution

  • They are declared in main.cpp. #include does a textual inclusion, so all the contents of utilities.cpp are effectively copied in main.cpp. Use #include "utilities.h" instead.