lairworks / nas2d-core

NAS2D is an open source, object oriented 2D game development framework written in portable C++.
http://nas2d.lairworks.com
zlib License
10 stars 5 forks source link

Fix debug builds of unit test project #1101

Closed DanRStevens closed 1 year ago

DanRStevens commented 1 year ago

There is an error finding the debug version of the Google Test library when compiling the debug builds of the unit test project.

DanRStevens commented 1 year ago

So after checking the vcpkg folders, I noticed there are separate folders for the release builds and the debug builds. In both folders, the libraries are found without the "d" suffix. That means it should just be "gtest.lib" and "gtest_main.lib".

Of course, vcpkg has automatic linking of the core library, though it's manual linking for the "main" version that includes the main function. That means we only need to explicitly specify the gtest_main.lib library, which we do use.

Now although the above fix does get the code to link, it unfortunately aborts with an error when run. During some reading, I thought I saw mention of a bug report where vcpkg uses the release version of the library for debug builds, which might explain the crash. I'm uncertain if fixing that error would mean the "d" suffix would be restored.

I'll have to do some more investigation later, and maybe link to all the relevant pieces.

DanRStevens commented 1 year ago

So I discovered something curious. If I remove the gtest.lib library from the explicit list of libraries to link, then Google Test will still run, but it won't find any tests to execute. It just prints the summary, with no tests run.

No idea why no tests are run without explicit manual linking. Maybe something related to library include order.

It seems we can remove explicit manual linking for opengl32.lib without any issue. Though I am a bit hesitant to remove that one without first understanding the issue for gtest.lib.

DanRStevens commented 1 year ago

I enabled a little more debug output for the linking step using: Project -> Properties -> Configuration Properties -> Linker -> Show Progress = Display all progress messages (/VERBOSE)

Project file change under <Link> section:

<ShowProgress>LinkVerbose</ShowProgress>

It seems vcpkg was linking the release versions for gtest.lib into the Debug builds. It seems the default behaviour of vcpkg is to always link Release versions of libraries, unless specifically requested otherwise. This sort of makes sense, since you don't typically bother to debug your dependencies. It maybe makes a little less sense with Google Test, since I believe it needs to be compiled with the same settings as the project under test.

To change the setting: Project -> Properties -> Configuration Properties -> vcpkg -> Vcpkg Configuration = Debug

Project file change under PropertyGroup Label="Vcpkg":

<VcpkgConfiguration>Debug</VcpkgConfiguration>

Changing the VcpkgConfiguration from Release to Debug changes the referenced library from the first to the second (adds the debug folder in the path):


Doing a full rebuild of the Solution, using VcpkgConfiguration set to Debug allows the unit test project to run. Oddly, that only seems to be true after a full Solution rebuild. Only rebuilding just the test project will still result in crashes.

Curiously, the property pages for other projects also show the Debug setting change under the vcpkg section, even though only the test project file was updated. I'm not sure why that would be.

DanRStevens commented 1 year ago

I looked a little further into removing gtest.lib from the explicit list of AdditionalDependencies. It seems that tests are not found only in Release mode. The Debug builds still find and run tests after removing gtest.lib from AdditionalDependencies.

I suspect maybe a Link Optimization that discards the tests, perhaps thinking they're unreferenced. I'm not too sure how Google Test keeps track of test functions, so it knows how to run them. If it traverses some kind of symbol table in the executable file, there might not be any references, and so the Linker might drop what it thinks are unreferenced symbols. Mind you, I tried adjusting the Link Optimization to drop unreferenced data, with no success at finding tests. I also adjusted options for COMDAT folding, and Link Time Code Generation, also with no success. Those seemed to be the only Link Optimizations that differed from a Debug build.