8

Here is my folder structure:

/
|
 -- program.cpp
 -- utility.h
 -- utility.cpp
|
 -- module/
    |
     -- utility.h
     -- utility.cpp

// Note that I have two files named utility.h and two named utility.cpp

On building the project, I get a link error (LNK2028: unresolved token and so on...) saying that some symbols aren't defined. I have confirmed that all symbols are defined and that all declared functions have a corresponding definition.

I have a feeling that on compiling my project, the utility.cpp files from both folders are compiled into the same utility.obj in the output folder. As a result, one overwrites the other.

  1. Is this expected behaviour?
  2. How do I build a C++ binary which has two files with the same name (though in different folders)?
David Schmitt
  • 58,259
  • 26
  • 121
  • 165
Agnel Kurian
  • 57,975
  • 43
  • 146
  • 217
  • what you are looking for is namespaces –  Feb 17 '10 at 15:29
  • 4
    @fuzzy: This has nothing to do with namespaces. Only one of the 2 .obj files are being pulled into the link step. – Michael Burr Feb 17 '10 at 15:34
  • 1
    @fuzzy: Say the first `utility.cpp` to be compiled defines everything under namespace `foo_ns` and the second `utilty.cpp` to be compiled compiles everything under namespace `bar_ns`, the compiler overwrites `utility.obj` when compiling the second `utility.cpp`... by the time the linker kicks in, only `bar_ns` is available in the .obj file. – Agnel Kurian Feb 17 '10 at 15:42
  • Possible duplicate of [Visual Studio 2010 & 2008 can't handle source files with identical names in different folders?](http://stackoverflow.com/questions/3729515/visual-studio-2010-2008-cant-handle-source-files-with-identical-names-in-diff) – Afriza N. Arief Dec 08 '15 at 06:49

6 Answers6

13

Right click both/either .cpp files > properties > C/C++ > Output Files > Object File Name > set a custom name. e.g. if both files are named MyFile.cpp in folder A and another in folder B, you can set the output to be AMyFile and BMyFile.

Alternatively, you can also use a macro to prefix the object names with the immediate parent folder name (i.e. using $(IntDir)\$(SafeParentName)$(SafeInputName)). If this is not enough (e.g. you have A/B/MyFile.cpp and C/B/MyFile.cpp) and you don't mind having some object files cluttering your source tree, you can also use $(InputDir)\ which will put the object files in the same folder as the source file.

the cpp files will then be compiled into two different object files..

enjoy!

Update for VS2010: There is a better solution in VS2010, check it out here. Thanks to n1ck's comment

btw, if the contents have the same name, do you separate them using different namespaces?

namespace A { // in folder A
    class CMyFile {};
};

namespace B{ // in folder B
    class CMyFile {};
};

// client.cpp
#include "A/MyFile.h"
#include "B/MyFile.h"
int main() {
    A::CMyFile aMyFile;
    B::CMyFile bMyFile;
    return 0;
}

I don't know if it matters but it's definitely clearer to human : D

Community
  • 1
  • 1
Afriza N. Arief
  • 7,696
  • 5
  • 47
  • 74
  • This is the solution - but be warned, for some reason have different names for the .cpp file and the .obj file dramatically slows the compile/link cycle down. I've no idea why. – JoeG Feb 17 '10 at 15:29
  • This *should* work and *should* be the solution, but it didn't work for me. VS would create both .obj files but would try to link in only one of them. – Michael Burr Feb 17 '10 at 15:32
  • I take it back - reloading the solution seemed to make this technique work (like it should). +1. VS is being touchy for me this morning for some reason. – Michael Burr Feb 17 '10 at 15:37
  • 1
    @afriza, AMyFile and BMyFile... looks like hardcoding. Is there a macro which I can use to insert the relative path of the `.cpp` as part of the path of the '.obj`? – Agnel Kurian Feb 17 '10 at 15:49
  • @agnel-kurian what about $(SafeParentName)$(SafeInputName) ? Thus, the complete path will be $(IntDir)\$(SafeParentName)$(SafeInputName). But this will not work if the files have same ParentName (immediate parent folder name). Thus, if you don't mind to clutter your source code folders, you can use $(InputDir)\$(SafeInputName) instead, which will put the object file in the same folder as the source files. – Afriza N. Arief Feb 17 '10 at 16:09
  • @afriza: The $(SafeParentName) fix do not seems to work when building the whole project. It seems to work fine when I compile only one file at a time (ctrl+f7) but when building the whole project it replace it only 1 time for the whole compilation instead of per-file (because it send the command line only one time, when building the .rsp file, and it already has replaced the $identifier). I did not find a way around this yet but manual management (i.e. $(IntDir)/A, $(IntDir)/B instead of something automatic). – n1ckp May 11 '11 at 19:45
  • @n1ck: what about `$(InputDir)\`? I don't have my PC now but I think the file names are optional. This will clutter your source tree with some more generated files though. – Afriza N. Arief May 21 '11 at 10:49
  • 2
    @afriza: yeah I guess $(InputDir) would work in a life or death situation but this is worse than doing it "by hand" in my case since it would pollute the src/ dir with lots of object files. Anyway, it is fixed in msvc2010 (http://stackoverflow.com/questions/3695174/visual-studio-2010s-strange-warning-lnk4042/3731643#3731643) so it is not too much a problem for me. – n1ckp May 21 '11 at 16:32
2

You could try adding another project to your solution, which will build a static mudule.lib file from your module's .cpp .h, then link your main project with that lib. It should make VS to output .obj files in a separate directory, and you should be able to link without problems.

Dmitry
  • 6,590
  • 2
  • 26
  • 19
1

The easiest thing that works well is put the conflicting .objs into different subfolders (I've used this technique with 2003 and 2008) based on the source dirs.

For example:

For src\gui\utils.cpp set "Object File Name" to ".\Debug\gui/" and for src\database\utils.cpp set it to ".\Debug\database/".

While I do it manually whenever I spot a conflict, I can imagine that writing a script that updates the project for every .cpp file (or just for conflicting ones) would be a pretty trivial task.

0

Maybe libraries (static or dynamic) would help with your case. But you will still have problem if there are any public symbols with the same name like in executable or other library.

Dominic.wig
  • 314
  • 3
  • 5
0

I don't know the VS compiling chain.

However, each .cpp is first compiled into a .obj file. The linking steps merges them together.

It's very common, to put all the .obj files in a same directory. So, as you guessed, when compiling the second one, erases the first one. Therefor some symbols are missing during compilation.

There probably is an option (again, I don't work with VS) to leave the .obj in the same directory as the .cpp file. The drawback is some garbage on your source code tree.

My personnal opinion would be to refactor.

Tristram Gräbener
  • 9,601
  • 3
  • 34
  • 50
0

Do you really WANT two different but same-named files in the same project?