(Makefile 错误)多个定义错误
Posted
技术标签:
【中文标题】(Makefile 错误)多个定义错误【英文标题】:(Makefile Error) Multiple definitions errors 【发布时间】:2020-04-18 22:12:29 【问题描述】:基本上,我正在尝试为我目前正在处理的项目创建一个 makefile。 该错误表明我在两个不同的文件中定义了两次相同的函数。
错误在许多功能中反复出现,但为了简单起见,我只会放其中一个并尝试自己修复其他的,因为我会理解发生了什么。
这是 MakeFile 代码:
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
这是 MakeFile 输出
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```
所以我一直在寻找那些在 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;
但正如你所见,它们从未在 main.cpp 中声明,只在.ç 中声明
我声明它们的唯一位置是在我的实用程序.h 中(出于理解目的从 utilidades.h 翻译):
#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
还有我的实用程序.cpp(从 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";
那么为什么会出现这个错误,我该如何解决呢?
【问题讨论】:
#include "utilidades.cpp"
几乎总是错误的。您永远不应该直接包含 .cpp 文件
在指责你的makefile之前,试着手动构建你的项目(只有两个文件,不会花很长时间)。从问题中消除你的makefile将是迈向minimal reproducible example的一大步。
这能回答你的问题吗? Error with multiple definitions of function
【参考方案1】:
它们在main.cpp
中声明。 #include
包含文本,因此utilities.cpp
的所有内容都有效地复制到main.cpp
中。请改用#include "utilities.h"
。
【讨论】:
对!所以我包括它是因为我输入了实用程序.cpp 而不是实用程序.h 有效地声明了两次!非常感谢!这对我来说是一个巨大的错误,我只是找不到它几个小时,并且有点急于完成它!非常感谢!顺便说一句,它告诉我我在 main.cpp 中 (.text+0x0) 声明它的原因可能是因为它是一个#include 文件而不是实际的代码行,所以它不能告诉我确切的行它是在 main.cpp 中声明的?再次感谢您! 部分。该错误将两个文件(main.o,从 main.cpp 编译,和实用程序.o,从 utilites.cpp 编译)链接在一起,这两个文件都包含mostrar
的定义。链接器不知道这些定义来自哪里,目标文件不存储这些数据(除了作为调试信息的一部分,如果有的话)。以上是关于(Makefile 错误)多个定义错误的主要内容,如果未能解决你的问题,请参考以下文章
如何创建用于从子目录中的其他 Makefile 编译多个驱动程序的 Makeflow