Reputation: 6597
I have a visual studio solution that contains two projects. They are both saved in a separate folder. The main project (in my case EquitCalculatorMontecarlo) contains a main function that can work by itself. The second project contains boost Tests that are supposed to test the main project.
My issue is that when I try to run the tests with the test explorer I get an error message from the linker:
Error LNK2019 unresolved external symbol "bool __cdecl eval_best_hand(class std::vector<class std::set<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,class std::allocator<class std::set<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > > > const &)" (?eval_best_hand@@YA_NAEBV?$vector@V?$set@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@V?$allocator@V?$set@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@@2@@std@@@Z) referenced in function "public: void __cdecl card_evaluation1::test_method(void)" (?test_method@card_evaluation1@@QEAAXXZ) Tests C:\Users\dickr\git\EquityCalculatorMontecarlo\Tests\Test.obj 1
I followed the instructions here: https://learn.microsoft.com/en-us/visualstudio/test/how-to-use-boost-test-for-cpp?view=vs-2019
The full code is visible here: https://github.com/dickreuter/PokerEquityCalculator
but here a quick summary:
/Tests/Test.cpp
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE HandEvaluationTests
#include <boost/test/included/unit_test.hpp>
#include "../EquityCalculatorMontecarlo/Deck.h"
#include "../EquityCalculatorMontecarlo/Scoring.h"
BOOST_AUTO_TEST_CASE(card_evaluation1)
.....
/EquityCalculatorMontecarlo/Scoring.cpp
various function definitions
/EquityCalculatorMontecarlo/Scoring.h
using CardsWithTableCombined = std::set<std::string>;
using Score = std::vector<std::tuple<int, int>>;
bool eval_best_hand(const std::vector<CardsWithTableCombined>&);
std::tuple< std::vector<int>, std::vector<int>, std::string> calc_score(const CardsWithTableCombined&);
template<typename T>
std::vector<T> slice(std::vector<T> const& v, int m, int n)
{
if (m > v.size())
.....
/EquityCalculatorMontecarlo/Deck.h
various function declarations
/EquityCalculatorMontecarlo/Deck.cpp
various function definitions
What could be the problem that the test project cannot access my main EquityCalculatorMontecarlo project? I have also tried to select it as a dependency but nothing seems to help. I cannot run the tests.
Any suggestions are highly appreciated.
Upvotes: 3
Views: 280
Reputation: 1408
Definitions of eval_best_hand and its dependencies are present only in EquityCalculatorMontecarlo project that is an executable, you are just referring the function declaration of eval_best_hand from header files in your Tests project but not linking them. Either you make the definitions of whatever functions designated to be used in other projects (Executables) into a common static lib (Say Utils.lib), and link your projects against that static library or include all the .cpp files that contains definitions of necessary functions to Tests.vcxproj.
I think, simply adding Scoring.cpp and Deck.cpp to Tests.vcxproj will solve the linker errors.
You may also create a separate project namely "Utils.lib" with only Scoring.cpp and Deck.cpp source files and link that lib to whatever executable project that needs to consume those utility methods. This is basically to meet the purpose of reusing and easy maintenance. In this case your main project (EquityCalculatorMontecarlo) may only contain a main function and code to consume functions in Scoring.h and Deck.h(Definitions present in Utils.lib).
Upvotes: 3