Never understood Visual studio linker- Error lnk2005.

Started by
1 comment, last by WoopsASword 7 years, 5 months ago

Hello,

I build a library which uses other libraries.

I've encountered a linking error which I could not solve it in a simple manner.

I've downloaded TinyObjLoader which is a only header obj loader.

I've put the header in an api source folder which the project configuration references. (Include section)

Then you have to specifcy #define Tinyobject_Implementation to include the implementation in the header only.

The library build and link goes well, the issue is referencing it from another project.

I have a test project which defines a program.cpp (Main here) and it reference a "ClassRenderer.h" which includes my render object, this file includes the "MeshLoader" which includes the TinyObjLoader header.

The output is "ClassRenderer.obj" and "program.obj". (After compilation)

The issue is in the linker, it tries to link program.obj but fails because functions from tinyobjloader are already defined in ClassRenderer.obj.

So I solved it by making a new project from the tinyobjloader and creating a static library and removing the #define tinyobject_Implementation preprocessor definition.

Now the test project also links against TinyObjectLoader.lib, which I find unnessecery in a header only library.

How can I solve this without using a .lib or .dll file?

I'm using Visual studio 2013 Community edition.

Thanks !

Advertisement

Then you have to specifcy #define Tinyobject_Implementation to include the implementation in the header only.


To understand the problem, you should read C++ FAQ lite’s “why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?”. While not the exact issue described, it provides insight as to what is at play here.

First, the issue is that you apparently didn’t read the readme very thoroughly, as it states you should only define TINYOBJLOADER_IMLEMENTATION for only one translation unit: :^)

USAGE
-----

#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
#include "tiny_obj_loader.h"



Second, the actual issue is that the TINYOBJLOADER_IMPLEMENTATION switches tiny_obj_loader from a symbol importer to symbol exporter. The correct set up should look something like:
// source1.cpp
#define TINYOBJLOADER_IMLEMENTATION
#include <tiny_obj_loader.h>

// source1.cpp will contain all of tiny_obj_loader’s symbols.


// source2.cpp
#include <tiny_obj_loader.h>

// from here, the symbols in tiny_obj_loader contains stubs, which will
// be resolved when the linker links source2.obj with source1.obj

If both source2.cpp and source1.cpp define TINYOBJLOADER_IMLEMENTATION, then the linker sees two different sets of identical symbols for tinyobjloader, and that’s an error.

Then you have to specifcy #define Tinyobject_Implementation to include the implementation in the header only.


To understand the problem, you should read C++ FAQ lite’s “why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?”. While not the exact issue described, it provides insight as to what is at play here.

First, the issue is that you apparently didn’t read the readme very thoroughly, as it states you should only define TINYOBJLOADER_IMLEMENTATION for only one translation unit: :^)

USAGE
-----


#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
#include "tiny_obj_loader.h"


Second, the actual issue is that the TINYOBJLOADER_IMPLEMENTATION switches tiny_obj_loader from a symbol importer to symbol exporter. The correct set up should look something like:

// source1.cpp
#define TINYOBJLOADER_IMLEMENTATION
#include <tiny_obj_loader.h>

// source1.cpp will contain all of tiny_obj_loader’s symbols.


// source2.cpp
#include <tiny_obj_loader.h>

// from here, the symbols in tiny_obj_loader contains stubs, which will
// be resolved when the linker links source2.obj with source1.obj

If both source2.cpp and source1.cpp define TINYOBJLOADER_IMLEMENTATION, then the linker sees two different sets of identical symbols for tinyobjloader, and that’s an error.

So if I got it right,

I do not need to specify TINYOBJLOADER_IMLEMENTATION in the library?
Because I use it in only in 1 file (MeshLoader.h) that gets included in couple of files. (And yeah I wrote it inside a single cpp file).

It seems weird because I want my library to do all the work so I don't have to specify additional libraries or preprocessor definitions.

I've also checked the linked, I was there already and it did not help my case. Neither explains it :|

This topic is closed to new replies.

Advertisement