2

I have a C++ project where I use Google Test to write my unit tests. The project has been around for a while and is quite messy, so I just added a line at the beginning of the main function that starts the unit tests and then exits the program. I would then comment and uncomment this line for switching between the unit tests and the real application.

This worked okey when only I used my code, but now I'm trying to solve this in a proper way, with two projects and .exe files, one for the real application and one for the tests, like toussa's answer here: Visual Studio C++: Unit test exe project with google test?

And his explanation for doing so here: Linking to multiple .obj for unit testing a console application

The problem is that all the .obj-files are put into this library, including the main function. This makes it impossible for me to link with my testmain, as _main is already defined. I tried adding the "/REMOVE" option to the command, so it looks like this:

lib /NOLOGO /OUT:"$(TargetPath).lib" /REMOVE:"$(ProjectDir)$(Configuration)\mainfile.obj" "$(ProjectDir)$(Configuration)\*.obj"

where mainfile.cpp is compiled to mainfile.obj, I hope. The output from lnk is:

LINK : warning LNK4014: cannot find member object C:\dev\solutions\currentSolution\currentProject\Debug\mainfile.obj

The only thing I found about how to write the name of the object file is from here: http://msdn.microsoft.com/en-us/library/5ff8sk86(v=vs.100).aspx

where they write:

The /REMOVE and /EXTRACT options require the full name of the member object that is to be deleted or copied to a file. The full name includes the path of the original object file. To see the full names of member objects in a library, use DUMPBIN /ARCHIVEMEMBERS or LIB /LIST.

If I type any of those two I get a list where "C:\dev\solutions\currentSolution\currentProject\Debug\mainfile.obj" is one of the entries.

What am I doing wrong? Is there some place that I type something wrong, or is there an easier solution to this problem?

Community
  • 1
  • 1
MrBerta
  • 2,457
  • 12
  • 24
  • 2
    Three projects. library of testable code, main application that links to library, test application that links to library. – Captain Obvlious Nov 30 '14 at 13:44
  • Yes, I tried that solution too, but because of the previous people that wrote this project, all the code is quite built together. Everything just includes stdafx.h that in turn includes everything else. The "classes" don't inherit, but just checks a type variable, calls a static method of the "subclass", which checks a number parameter, finds the correct object in the global array for that subclass, and finally calls the right method. Instead of untangling this mess I'd like to find a shortcut for having my tests in another project. – MrBerta Nov 30 '14 at 15:03
  • So. Change application to a library and rename `main` to `ApplicationEntry` or whatever then have the `main` in your new application project call it. Mimimum refactoring and less headache than introducing yet another element that is difficult for the next developer to maintain. – Captain Obvlious Nov 30 '14 at 15:07
  • Yes, that was a way simpler solution. Thanks :) – MrBerta Nov 30 '14 at 15:50

1 Answers1

3

I had exactly the same problem while using Google Test to build unit tests for a console application. I solved it by splitting the post-build action int two separate lib calls. First one builds the lib from all *.obj files. Second call removes the *.obj file with the main function from the *.lib file. In your case the calls would be:

lib /NOLOGO /OUT:"$(TargetPath).lib" "$(ProjectDir)$(Configuration)\*.obj"
lib /NOLOGO "$(TargetPath).lib" /REMOVE:"$(ProjectDir)$(Configuration)\mainfile.obj"
Radek
  • 123
  • 10
  • I followed Captain Obvlious advice and split the project into three: A library project with the real code, the test project, and then a small project that just creates an exe file from the library. This has been working fine now for almost three years, and I've repeated it in other projects. It is also very easy to explain to new people! – MrBerta Aug 14 '17 at 12:50
  • On a [@kulaGGin idea](https://stackoverflow.com/a/19709712/3641635), may i suggest you to use `$(ProjectDir)$(IntDir)` instead of `$(ProjectDir)$(Configuration)\ ` ? This way, it will work fine also for platform specific configurations. – Zilog80 Nov 28 '21 at 20:13