googletest testing framework c++: static method linker error

…衆ロ難τιáo~ 提交于 2019-12-13 07:06:30

问题


I'm trying to call static method from my TEST, but I'm getting unresolved external symbol. What I've done so far: Created 3 projects:

  1. GoogleTest project as a static library - compiled gtest-all.cc and gtest_main.cc
  2. MyProject - where I keep my .h and .cpp files
  3. UnitTest project - where I keep tests

I've set up UnitTest's additional directories, lib directories, and referenced GoogleTest and MyProject. Tests run fine until I call static method from one of my classes...

Linker options:

/OUT:"D:\SkyDrive\Projekti\Visual Studio 2010\Projects\File System\Debug\Unit Test.exe" /INCREMENTAL /NOLOGO "..\lib\part.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" "D:\SkyDrive\Projekti\Visual Studio 2010\Projects\File System\Debug\Google Test.lib" /MANIFEST /ManifestFile:"Debug\Unit Test.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"D:\SkyDrive\Projekti\Visual Studio 2010\Projects\File System\Debug\Unit Test.pdb" /SUBSYSTEM:CONSOLE /PGD:"D:\SkyDrive\Projekti\Visual Studio 2010\Projects\File System\Debug\Unit Test.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE

Error:

error LNK2019: unresolved external symbol "public: static char __cdecl FS::mount(class Partition *)" (?mount@FS@@SADPAVPartition@@@Z) referenced in function "private: virtual void __thiscall Cluster_KernelFS_mountPartition_Test::TestBody(void)" (?TestBody@Cluster_KernelFS_mountPartition_Test@@EAEXXZ)   D:\SkyDrive\Projekti\Vi‌​sual Studio 2010\Projects\File System\Unit Test\cluster.obj

回答1:


From our exchange of comments it looks clear that the linkage of your googletest unit-test project (Unit Test) does not include necessary object files generated by the project that it is supposed to test (MyProject). fs.obj and kernelfs.obj are at least two that are missing and from inspection of the failing linker commandline it appears that you are linking none of the object files that implement the classes or functions you want to test (if there are any more)

You seem to believe that adding a Visual Studio project reference to MyProject to Unit Test will automatically provide the missing object file dependencies to Unit Test, but it won't.

The quickest way to remove the linkage errors would simply be to add the missing object files generated by MyProject to the Unit Tests project's Configuration Properties -> Linker -> Input -> Additional Dependencies.

You could add each of the missing .obj files by a fully-qualified pathname that locates it in the Debug output directory of MyProject. Or more easily, you could add the path to that Debug directory to Configuration Properties -> Linker -> Input -> Additional Directories, and then simply add the unqualified name of the missing .obj file to Additional Dependencies.

But this would be a flawed solution because of course you want Unit Test always to build on the latest source version of MyProject and not just whatever MyProject object files happen to exist at the time. In that case you have two options:-

  • a) You can add the source files that generate the missing .obj files to the Unit Test project as well as MyProject. In Unit Test's Solution Explorer view, right-click Source Files and navigate Add -> Existing Item. In this case you must take care that whenever your add a new source file to MyProject you also add it to Unit Test.

  • b) This option assumes that both projects are in the same solution. If they're not you can make them so. Then you can, first, carry out the quick-but-flawed solution (and test it). Then to fix the flaw, you can make Unit Test dependent on MyProject, so that whenever you build Unit Test, MyProject will automatically be built first if it is out-of-date. To create this dependency, right-click Unit Test in the Solution Explorer pane, navigate Build Dependencies -> Project Dependencies -> Dependencies and tick the checkbox to make Unit Test depend on MyProject. In this case you must take care that whenever a new .obj file is to be generated by MyProject you add it to the additional linker dependencies of Unit Test.

(b) Is the better practice.

All of the above assumes that you have correctly configured Unit Test so that the compiler searches the include-directories of MyProject and correctly locates its header files. You don't seem to have any build errors on that score.

Follow up Q. 1

Could you explain to me why doesn't the linker link any object files from MyProject (and I have to add them manually).

As far as the Visual Studio is concerned, MyProject and Unit Test are just two projects contained in the same solution that build different executables. It doesn't "know" that the purpose of Unit Test is to unit-test MyProject and therefore will need to link all of the object files generated by MyProject that contain functionality that Unit Test is going to test. So why would it automatically add MyProject's object files to Unit Test's linkage?

Even if Visual Studio did somehow know that the purpose of Unit Test was to unit-test MyProject, how would it know which of MyProject's object files it should link in Unit Test? One of them might contain a main() function - which will in fact be the case if MyProject builds a console application - but Unit Test also generates a main() function in one of its object files; so linking all the MyProject object files in Unit Test would be impossible: it would cause a multiply defined symbol error.

I pointed out that giving Unit Test a project reference to My Project does not have the effect of adding all My Project's object files to Unit Test's linkage. You now see one reason why it couldn't have that effect.

And that reason exemplifies a more general one: When you link object files to build an executable, it's a linkage error for the same symbol to be visible in multiple object files. Which one is supposed to get linked? But of course it's not any kind of error for the same symbol to be visible in the linkages of different executables. That means you can't simply scoop up a bunch of object files from the linkage of one executable and add them to the linkage of another executable and expect it to work. If you want to add object files from one executable to the linkage of another, you have to know that some such mixture can be linked and what mixture you want. You have to know which symbols are meant to be linked from which object files to make the second executable and select the object files accordingly. As you say, it's a "manual" exercise.

Visual Studio's Project Reference feature would help you if MyProject generated a library rather than an executable. In that case creating a reference from Unit Test to MyProject would (among other things) tell Visual Studio that by default the MyProject library will be added to the linkage of Unit Test. Libraries, unlike plain object files, are created for the purpose of being being linked with different executables, so it's natural for the MS Project Reference feature to support automation of library dependencies. It's also natural to assume that if a project generates an executable, not a library, then its object files are just a by-product and not intended to be linked with other executables.

The text-book way of organizing your work would be in three projects:-

  • MyLib, generating library that contains all the functionality you want to unit-test.
  • MyProject, generating the same executable as at present, but linking MyLib
  • Unit Test, generating an executable that unit-tests MyLib, also linking MyLib

Follow up Q. 2

Explain to me how to configure the linker to link .objs from MyProject's debug folder?

I already have. Paragraph 4, "Or more easily..." etc. There is no way you can avoid having to specify the individual .obj files to be linked. You can't instruct the linker "Just link whatever object files you find in /path/to/MyProject/Debug", because for the reasons I've explained, the linker doesn't do things as sloppy as that.



来源:https://stackoverflow.com/questions/23042424/googletest-testing-framework-c-static-method-linker-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!