I have a project I am trying to add google-test unit testing to. It is structured like so:
VM (project)
some source files
BytecodePrograms.h
VMTest (project, made by add project -> google test -> link dynamically, test VM)
pch.h
test.cpp
I added my VM project as an include directory in VMTest properties -> c/c++ -> general -> additional include directories
contents of test.cpp are:
#include "pch.h"
#include "BytecodePrograms.h"
TEST(TestCaseName, TestName) {
EXPECT_EQ(8, VMFibonacciImp(6));
EXPECT_TRUE(true);
}
If I build, I get the following errors
Error LNK2019 unresolved external symbol "public: __thiscall WVM::WVM(void)" (??0WVM##QAE#XZ) referenced in function "int __cdecl VMFibonacciImp(int)" (?VMFibonacciImp##YAHH#Z) WVMTest C:\Users\WadeMcCall\source\repos\Virtual Machine Visual Scripting\WVMTest\test.obj 1
Error LNK2019 unresolved external symbol "public: __thiscall WVM::~WVM(void)" (??1WVM##QAE#XZ) referenced in function "int __cdecl VMFibonacciImp(int)" (?VMFibonacciImp##YAHH#Z) WVMTest C:\Users\WadeMcCall\source\repos\Virtual Machine Visual Scripting\WVMTest\test.obj 1
Error LNK2019 unresolved external symbol "public: int __thiscall WVM::interpret(class std::vector<int,class std::allocator<int> >)" (?interpret#WVM##QAEHV?$vector#HV?$allocator#H#std###std###Z) referenced in function "int __cdecl VMFibonacciImp(int)" (?VMFibonacciImp##YAHH#Z) WVMTest C:\Users\WadeMcCall\source\repos\Virtual Machine Visual Scripting\WVMTest\test.obj 1
However, my VM project defines my WVM class and uses it and can build and run and BytecodePrograms.h includes VM.h which has the declaration for this class.
I feel like this must just be a problem with the set up of my projects in Visual Studio somehow, but I have no idea. I have been googling for 2 days straight and have found other people with similar problems but their solution never seems to work for me.
Any ideas? Thanks.
I found a solution here: https://stackoverflow.com/a/19709712/8488701
Similar to what Steve suggested, except instead of creating a whole new project, I use a post-build event to build my project to a library and then link google test to that. The advantage of this over Steve's solution is that you don't have to modify your main project at all and you can still build a unit testing project on top of it.
This is a link error indicating that it found the .h file but couldn't find the actual implementation found in the .cpp. If you have a LIB project then visual studio may take the cpp code compiled into the LIB project and add it to your EXE project.
To incorporate the code into the test project, you have two options.
You can add the .cpp files in your VM Project to your Test project as well, but this is not usually done.
Instead, if your VM project is now an EXE I would recommend creating a new project called VMLib as a LIB project and then adding that project to both the test project and the VM EXE project.
I want to unit test my C++ project with Visual Studio. After adding the folders from my project as include path to my test project, I get linker errors when trying to compile the tests:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol "public: __thiscall Piece::Piece(enum Color)" (??0Piece##QAE#W4Color###Z) referenced in function "public: __thiscall Bishop::Bishop(enum Color)" (??0Bishop##QAE#W4Color###Z) ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1
Error LNK2019 unresolved external symbol "public: __thiscall Board::~Board(void)" (??1Board##QAE#XZ) referenced in function "public: void __thiscall ChessPlusPlusTests::BishopTests::ValidMovesTest(void)" (?ValidMovesTest#BishopTests#ChessPlusPlusTests##QAEXXZ) ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1
Error LNK2019 unresolved external symbol "public: void __thiscall Board::placePieceAt(class Piece * const,struct Position)" (?placePieceAt#Board##QAEXQAVPiece##UPosition###Z) referenced in function "public: void __thiscall ChessPlusPlusTests::BishopTests::ValidMovesTest(void)" (?ValidMovesTest#BishopTests#ChessPlusPlusTests##QAEXXZ) ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1
Error LNK2001 unresolved external symbol "public: virtual class std::vector<struct Position,class std::allocator<struct Position> > __thiscall Bishop::getMovesFor(struct Position,class Board &)" (?getMovesFor#Bishop##UAE?AV?$vector#UPosition##V?$allocator#UPosition###std###std##UPosition##AAVBoard###Z) ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1
Error LNK2001 unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Bishop::toString(void)" (?toString#Bishop##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1
Error LNK2001 unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Bishop::toShortString(void)" (?toShortString#Bishop##UAE?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##XZ) ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1
My test source code:
#include "stdafx.h"
#include "CppUnitTest.h"
#include "Bishop.h"
#include "Board.h"
#include "TestUtils.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace ChessPlusPlusTests
{
TEST_CLASS(BishopTests)
{
public:
TEST_METHOD(ValidMovesTest)
{
// Arrange
Board board{};
Bishop *piece = new Bishop{ Color::WHITE };
Position pos{ 3,3 };
board.placePieceAt(piece, pos);
// Act
auto validPositions = piece->getMovesFor(pos, board);
// Assert
TestUtils::AssertPositions(validPositions, {
0,0,0,0,0,0,0,1,
1,0,0,0,0,0,1,0,
0,1,0,0,0,1,0,0,
0,0,1,0,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,0,1,0,0,0,
0,1,0,0,0,1,0,0,
1,0,0,0,0,0,1,0,
});
}
};
}
Without adding the include path's the test project doesn't compile, since the header file includes in the main project rely on the include paths.
The main project compiles just fine.
Can someone help me to understand whats going wrong?
Thanks!
I believe the chosen answer is not correct. Tests typically should be run in their environment; therefore, they should not access the implementation (.cpp)
When you create a separate Test Project on Visual Studio (VS 2017) you need to create a reference to the project you want to test (right-click test project -> Add -> Reference -> tick projects):
Add a reference
If you see some linker errors, right-click from the Unit test project: Project->Linker->Input->Additional Dependencies->Edit
then add the path to your .obj files.
You could try something like "$(SolutionDir)ConsoleApplication1\$(IntDir)*.obj" where ConsoleApplication1 is the target project name.
Path to .obj
Initially, I only wanted to put a comment on Cornelis' post, but I couldn't.
https://www.codeproject.com/Tips/1085171/How-To-Do-Unit-Testing-with-Cplusplus-in-Visual-St
I found there that you have to add your .h and .cpp files as existing files also to the test project. That is left out on the official documentation or I missed it.
Now it works!
I just ran into the same problem and solved it differently, following this piece of Microsoft documentation: https://learn.microsoft.com/nl-nl/visualstudio/test/unit-testing-existing-cpp-applications-with-test-explorer?view=vs-2015&redirectedfrom=MSDN#objectRef
This solution is a bit cleaner, I think, as you don't end up with all the header files from your projects under test also showing up in your test project.
Lines from the documentation in italics, bold lines are my additions:
If the code under test does not export the functions that you want to test, you can add the output .obj or .lib file to the dependencies of the test project.
Create a C++ test project.
On the File menu, choose New, Project, Visual C++, Test, C++ Unit Test Project.
Make sure to add the projects that you want to test as References. If you forgot, you can also add these references later, in the Solution Explorer window.
In Solution Explorer, on the shortcut menu of the test project, choose Properties. The project properties window opens.
Choose Configuration Properties, Linker, Input, Additional Dependencies.
Choose Edit, and add the names of the .obj or .lib files. Do not use the full path names.
For me, there were only .obj files. I found them in the Intermediates folder, of which there are multiple versions, one for each combination of Solution Platform (x86 or x64) and Solution Configuration (Debug or Release). If you have a lot of .obj (or .lib) files, I found it convenient to open a terminal and run ls (or dir) to get the filenames, edit out the .log, .txt and .pdb filenames that I didn't need, and copy paste the list of .obj filenames into Visual Studio. For convenient editing, note that you can click on the dropdown arrow on the right hand side of the Additional Dependencies entry field and click on edit.
Choose Configuration Properties, Linker, General, Additional Library Directories.
Choose Edit, and add the directory path of the .obj or .lib files. The path is typically within the build folder of the project under test.
For me, I only had .obj files. I found them in the Intermediates folder, of which there are multiple versions, one for each combination of Solution Platform (x86 or x64) and Solution Configuration (Debug or Release). A convenient macro for setting this path for all 4 combinations is this: $(SolutionDir)bin\$(PlatformTarget)\$(IntermediateOutputPath)Intermediates. You might have to take out the bin\ part, as I have also seen the output folders set up directly in the Solution Directory, instead of in a separate binary folder.
Choose Configuration Properties, VC++ Directories, Include Directories.
Choose Edit, and then add the header directory of the project under test.
For this directory, it's okay to point directly to folders that are part of the project under test. There is no need to copy the header files over to the test project. It's also okay if this directory contains more than just the headers. For example, my source folder contains both the .h files and the .cpp files.
After following these steps, I was able to include the header files in my test code by simply writing:
#include "SomeHeaderName.h"
So, without any need to specify the folders that the header files are in.
Make sure to clean and rebuild your entire solution. Then, your tests should be able to access the functionality of the projects that you are testing.
Good morning,
I have just inherited an application from a collegue who has left, and I'm already in trouble: the last thing we have done is porting the solution from Visual Studio 2010 to 2013.
Now while building one of the projects in the solution, I get following error message:
1>usharedmemory.obj : error LNK2019: unresolved external symbol "public: __cdecl C_NamedSemaphore::C_NamedSemaphore(char const *,unsigned int)" (??0C_NamedSemaphore##QEAA#PEBDI#Z) referenced in function "public: __cdecl C_RecursiveNamedSemaphore::C_RecursiveNamedSemaphore(char const *,unsigned int)" (??0C_RecursiveNamedSemaphore##QEAA#PEBDI#Z)
This error seems to be caused within the file "Y:\Ucam5\ucm\x\rip_mlfdpf\usharedmemory.obj" (within the project's directory), but after having a quick look, it seems that this *.obj file does not even exist.
Hence the next question: what can I do in order to be sure that the *.obj file gets created? I have already verified that the "usharedmemory.cpp" file is present in the directory of the main project (the corresponding *.h files is located in the "External Dependencies" chapter, which makes me believe that the *.obj file will be created during the build of the main project.
You see my problem: my project refers to a file which the project needs to create, but as the project does not create the file, he obviously can't refer to it, you see the circle I'm running in :-)
(for your information, I have no idea on how to generate an "*.obj" file)
Can anybody help me?
Thanks
Object files (*.obj) are created directly from source files (*.cpp) by the compiler at compilation time, for each source file in your project.
The error you are receiving is not caused by usharedmemory.obj not existing; it should be created in the Debug or Release folders.
The error you are getting is because usharedmemory.cpp uses the C_NamedSemaphore(char const *,unsigned int)-constructor of C_NamedSemaphore and the definition of the constructor can not be found in any of the source files. This constructor is used in the C_RecursiveNamedSemaphore(char const *,unsigned int)-constructor defined in usharedmemory.cpp. This is what the error message reads.
To solve this, you need to find out where the constructor of C_NamedSemaphore is defined (which source file) and ensure that this source file is included in your project. Or, if it is in a library file (static or dynamic), verify that this library file is included as an Additional Dependency (under project Properties -> Linker -> Input -> Additional Dependencies; ensure you set this for all builds, not just the currently active one).
Good morning,
I have finally solved my issue. As a good citizen, I will describe how I have done it :-), but as a less good programmer, I need to admit that I don't understand how my actions solve the problem ;-(
I have done a file comparison of both *.vcxproj Visual Project files (the old one from VC2010 and the new VC2013 one). In that way I have seen that the "umultiproc.cpp" entry was missing in the VC2013 one:
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<ItemGroup>
...
<ClCompile Include="..\..\mp\umultiproc.cpp" /> <!-- missing -->
Summary: In the error message, there was an unresolved symbol (C_Semaphore constructor), which was defined in *.cpp/*.h source/header file. In order to solve the error, I have added a reference to the *.cpp source file into the VC2013 project file.
I am trying to get protocol buffer to work but linking problems occurs.
All the errors looks something along like this
error LNK2019: unresolved external symbol "public: bool __cdecl google::protobuf::MessageLite::ParseFromArray(void const *,int)" (?ParseFromArray#MessageLite#protobuf#google##QEAA_NPEBXH#Z) referenced in function "void __cdecl ReceiveRequest(bool *)" (?ReceiveRequest##YAXPEA_N#Z)
I am using visual studio pro 2013 and this is what I have done:
I compiled the protocol buffer and added the libprotobuf.lib to the project(Add->Existing Item->libprotobuf.lib)
I've added the header files in C/C++ -> General -> "Additional Include Directories"
I have tried to add the library all the different ways I know but I still get these linking errors...
Any idea what I might have done wrong?
// Eric
You need to include the generated protocol buffer .cc (and maybe the .h) file (ie the file with the specific getters and setters for your specific proto) in your VS project (ie there has to be a little icon for them in the solution explorer) or else visual studio won't generate the code for it and thus there's nothing to link to.
Make sure you have the correct libraries for your architecture (e.g. x86 / x64).
That has caught me out a few times.
I'm trying to add Beecrypt library to my project. First i have added header files but after attempting to create an object i'm receiving the following errors:
error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall beecrypt::security::SecureRandom::~SecureRandom(void)" (__imp_??1SecureRandom#security#beecrypt##UAE#XZ) referenced in function _wmain
As far as i understand it is due to the absence of cpp files. Ok. Then i'm trying to add cpp files but whatever folder i put them i still receive the same error. For example SecureRandom.h is situated:
beecrypt/c++/security/SecureRandom.h
Where should i put SecureRandom.cpp to get rid of that error? I've already tried all levels of folders. Or maybe that error is caused by something else? Thanks a lot in advance
Simplest way is to Just drag and drop them to your project in the solutions explorer.
Or
Follow the steps given in the link below on MSDN website:
Adding a Source File.