Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: digimikeh en 28 Abril 2019, 00:19 am



Título: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: digimikeh en 28 Abril 2019, 00:19 am

Hola!

Tengo 4 archivos:

udbmanagement.hpp
uloginwindow.h
main.cpp
uloginwindow.cpp


main.cpp está incluyendo a "udbmanagement.hpp"
loginwindow.cpp también incluye esta misma cabecera "udbmanagement.hpp"

Sin embargo, al compilar, me envía ese error del linker, símbolos duplicados, los símbolos duplicados son 4 funciones que están dentro del archivo .hpp

El problema es que utilizo esas funciones tanto en main, como en uloginwindow.cpp

que debería hacer en este caso?..

(he probado con #pragma once pero sigo teniendo el mismo error.)

en el archivo .hpp tengo 2 structs cada una tiene algunas funciones, y esta todo definido dentro del mismo .hpp .. quizá sea mejor idea separarlos en .h y .cpp ...

Alguna idea?..
Saludos y gracias...


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: srWhiteSkull en 28 Abril 2019, 00:51 am
Qué IDE estás usando?


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: digimikeh en 28 Abril 2019, 01:28 am
Qt creator en mac


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: RayR en 28 Abril 2019, 04:01 am
Fíjate en el archivo .pro de tu proyecto, a ver si en la sección HEADERS no tienes repetido el archivo.


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: digimikeh en 28 Abril 2019, 05:56 am
Lo revisare, gracias.

Como dato extra, si yo retiro #include "udbmanagement.hpp" en uno de los dos archivos (solo en uno), el error desaparece... es como que no pueden estar usándose por ambos al mismo tiempo, evidentemente que debo tener símbolos duplicados si los esta invocando dos veces..

Probare lo que dices con el archivo de proyecto..
Lo otro que hare será separar el archivo .hpp en dos, .h y .cpp, me da la espina de que es mejor practica incluir las cabeceras y no las fuentes..

Comentare como me fue..
gracias!


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: srWhiteSkull en 28 Abril 2019, 07:27 am
Nunca he tenido un mac  :-\

Podrías solucionarlo cambiando el orden de compilado si ese IDE te permitiera hacerlo, algo que desconozco y si no compilarlo por línea de comando en el orden inverso.

https://www.appletonaudio.com/blog/2013/linking-c-static-libraries-with-duplicate-symbols/

Luego otra alternativa usar la opcion --whole-archive en el parámetro de la parte del enlace a las librerías, que desconozco como se haría desde ese IDE pero que podrías poner como se muestra en el enlace de abajo desde la línea de comando.

https://stackoverflow.com/questions/9093891/gcc-detect-duplicate-symbols-functions-in-static-libraries

Y ésto otro que no puedo probar :
--no-define-common
This option inhibits the assignment of addresses to common symbols. The script command "INHIBIT_COMMON_ALLOCATION" has the same effect.
The --no-define-common option allows decoupling the decision to assign addresses to Common symbols from the choice of the output file type; otherwise a non-Relocatable output type forces assigning addresses to Common symbols. Using --no-define-common allows Common symbols that are referenced from a shared library to be assigned addresses only in the main program. This eliminates the unused duplicate space in the shared library, and also prevents any possible confusion over resolving to the wrong duplicate when there are many dynamic modules with specialized search paths for runtime symbol resolution.

O

--traditional-format
For some targets, the output of ld is different in some ways from the output of some existing linker. This switch requests ld to use the traditional format instead.
For example, on SunOS, ld combines duplicate entries in the symbol string table. This can reduce the size of an output file with full debugging information by over 30 percent. Unfortunately, the SunOS "dbx" program can not read the resulting program ("gdb" has no trouble). The --traditional-format switch tells ld to not combine duplicate entries.

https://linux.die.net/man/1/ld




Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: digimikeh en 28 Abril 2019, 15:00 pm
Que bien, no sabia que había más opciones, afortunadamente no envíoñ tengo tantos archivos como para que la compilacion manual sea un dolor de cabeza, probare también con lo que has mencionado, muchas gracias


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: RayR en 28 Abril 2019, 20:58 pm
Se me pasó preguntarte si habías probado la forma más obvia: los clásicos include guards. Pones en tu .h:

Código:
#ifndef NOMBRE_H
#define NOMBRE_H

//Contenido de tu archivo...

#endif

Esta es la forma estándar. Todas las demás son dependientes del compilador (aunque #pragma once es soportada por prácticamente todos). Esto no debería fallarte. Si siguiera sin funcionar, significaría  que tu IDE está haciendo algo muy, muy mal.


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: digimikeh en 29 Abril 2019, 02:33 am
#pragma once me funciona en Visual Studio, pero no me anda en QT Creator Mac (en la versión de Windows no he probado), ..

agregare a la lista los include guards.. no los conocía..
probare mañana en mi oficina  :)


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: CalgaryCorpus en 29 Abril 2019, 14:42 pm
Apostaria mas por el flag hacia el compilador que el #ifndef o el #pragma.
Usualmente las directivas al preprocesador tendran efecto si al compilar 1 programa, este #incluye mas de 1 vez el mismo codigo en esa operacion.
Pero si estas compilando 2 archivos .cpp, como indicas, y ambos hacen #include, el compilador no tiene manera de saber lo que #incluiste antes y no va a tener efecto el #ifndef o #pragma.

Si el archivo #incluido tiene funciones, como parece ser el caso, a ninguna de las 2 compilaciones le molestara', pero el linker descubrira' esto y reclamara' de la duplicacion de codigo, como lo esta haciendo ahora.

Sugiero eliminar la presencia de funciones en los archivos #incluidos. quedandose solamente con la definicion de tipos y la especificacion de prototipos de funciones, haciendo su implementacion en un archivo .cpp aparte.


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: RayR en 29 Abril 2019, 17:28 pm
Cierto. Tienes definiciones de funciones en tu hpp. Sí va a ser lo que te dice CalgaryCorpus. Y de cualquier forma separar en .h y .cpp sí es en general mejor práctica, como suponías.


Título: Re: como evitar el error de linker : Duplicated symbol for Architecture x86?
Publicado por: digimikeh en 30 Abril 2019, 00:02 am
Gracias a todos por las respuestas, efectivamente se soluciono separando la definición de la declaración

 :laugh: