CMake not linking .obj files properly LNK2019 __thiscall - c++

Firstly, I've been working on this for days now and I've tried all possible fixes (went to 10th Google search page searching for a fix) but I can't get it to work.
I'm porting Unix app (G++/Bison/Flex) to Windows (MSVC/WinBison/WinFlex). I'm using CMake as a build system and the idea is to build the project from VS CMD and get VS project ready for modification. The project is meant to work on both platforms so all the modifications should be done in CMakeLists.txt so that I don't have to write special instructions done in VS.
Problematic line in preprocessor.cc is
State current(task->CPFs);
while the method State(std::vector<ConditionalProbabilityFunction*> const& cpfs) is declared in states.h with following code:
struct State {
State(std::vector<ConditionalProbabilityFunction*> const& cpfs);
State(State const& other) : state(other.state) {}
State(int stateSize) : state(stateSize, 0.0) {}
and implemented in states.cc:
State::State(vector<ConditionalProbabilityFunction*> const& cpfs) {
for (unsigned int i = 0; i < cpfs.size(); ++i) {
state.push_back(cpfs[i]->getInitialValue());
}
}
states.h is included in states.cc and rddl.h (which is included in preprocessor.cc) and class States is forward declared in preprocessor.h (which is included in preprocessor.cc).
The errors I'm getting are
[ 36%] Linking CXX executable rddl-parser.exe
preprocessor.cc.obj : error LNK2019: unresolved external symbol "public: __thiscall State::State(class std::vector<struct ConditionalProbabilityFunction *,class std::allocator<struct ConditionalProbabilityFunction *> > const &)" (??0State##QAE#ABV?$vector#PAUConditionalProbabilityFunction##V?$allocator#PAUConditionalProbabilityFunction###std###std###Z) referenced in function "private: void __thiscall Preprocessor::prepareActions(void)" (?prepareActions#Preprocessor##AAEXXZ)
rddl.cc.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall LogicalExpression::evaluate(double &,struct State const &,class ActionState const &)const " (?evaluate#LogicalExpression##UBEXAANABUState##ABVActionState###Z)
Linking, when build on Unix, works perfectly. But when I run it on Windows, I get this error.
This is the part of CMake code that does the linking:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG")
add_executable(rddl-parser ${RDDL_PARSER_SOURCES} ${FLEX_scanner_OUTPUTS} ${BISON_parser_OUTPUTS})
target_link_libraries(rddl-parser ${FLEX_LIBRARIES} ${BISON_LIBRARIES})
The option to copy the definition of the function to the source file is a no go.

OK, there was some almost duplicate code in this project where I noted that State was defined as struct and not as a class. When I switched it to being defined as class with all public methods, the compilation passed. It's interesting that this wasn't an issue on Unix and is on Windows.

Check whether the declaration of the function/class match exactly their definitions.
It could happen that when you compile logical_expressions.cc you define something that is not identical to the forward declaration for preprocessor.cc and rddl.cc files.

Related

How to define macro which correctly sets the __declspec

Using Visual Studio 2017, I am trying to build my latest project which imports libraries, which in turn import methods and functions from .dll files.
When building my project, I get a list of errors like this:
error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl UserTracking(void *)" (__imp_?UserTracking##YAXPEAX#Z)
error LNK2001: unresolved external symbol "public: bool __cdecl EACServer::Destroy(void)const " (?Destroy#EACServer##QEBA_NXZ)
error LNK2001: unresolved external symbol "public: bool __cdecl EACServer::Initialize(void)const " (?Initialize#EACServer##QEBA_NXZ)
...
All of the functions listed are from imported libraries.
As an example, the EACServer::Initialize method is defined as so in EACServer.h:
bool Initialize() const;
In the code I am compiling, this function is used as so (the appropriate header files are imported in the .h file ofc):
this->eacServer = EACServer();
this->eacServer.Initialize();
The class definition of EACServer is basic:
class EACServer : IRoot {
...
}
I have been told that these errors are thrown because I am missing the macro which correctly sets the __declspec.
How can I find/implement this macro?
Turns out that although I added the paths to my libraries in the linker additional library directories, I had neglected to add the .lib files in the linker additional dependencies.

lnk2001 error in VS trying to use the Bullet physics library

I'm new to C++, Visual Studio (2019) and Bullet (2.89).
I've been tying to build the Hello_World.cpp from Bullet for the past few days but I'm stuck on these 5 linking errors:
1>Hello_World.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall btCollisionShape::getBoundingSphere(class btVector3 &,float &)const " (?getBoundingSphere#btCollisionShape##UBEXAAVbtVector3##AAM#Z)
1>Hello_World.obj : error LNK2001: unresolved external symbol "public: virtual float __thiscall btCollisionShape::getAngularMotionDisc(void)const " (?getAngularMotionDisc#btCollisionShape##UBEMXZ)
1>Hello_World.obj : error LNK2001: unresolved external symbol "public: virtual float __thiscall btCollisionShape::getContactBreakingThreshold(float)const " (?getContactBreakingThreshold#btCollisionShape##UBEMM#Z)
1>Hello_World.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall btConvexShape::project(class btTransform const &,class btVector3 const &,float &,float &,class btVector3 &,class btVector3 &)const " (?project#btConvexShape##UBEXABVbtTransform##ABVbtVector3##AAM2AAV3#3#Z)
1>Hello_World.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall btSphereShape::calculateLocalInertia(float,class btVector3 &)const " (?calculateLocalInertia#btSphereShape##UBEXMAAVbtVector3###Z)
There are other people who had this or a similar problem but got no answer or it didn't work for me.
setup:
I used premake to set up the VS solution, Bullet is organized in static Libraries (as projects with source code that gets compiled to lib files) and I am now trying to link them with an application-project.
all projects are using static linking (for debug).
I've referenced all bullet projects to my project.
I've even staticly linked to the lib files from bullet (and the linker can apparently see these files, I even tried giving the absolute path)
As far as I can tell the functions exist and have the same signature in the .cpp and .h files
If you need more details let me know.
(One lead I possibly got is something about different bt_double_precision? But that might not be it and the only think I could find was floating point model using different precision. But making that the same didn't do anything)
Thanks in advance!
EDIT:
I don't think this answer applies to me
What is an undefined reference/unresolved external symbol error and how do I fix it?
EDIT:
Maybe worth mentioning: The file structure of the project is really weird (dictated by premake):
solution and project files are in: bullet3-2.89\build3\vs2010
high level header files(these are the ones used by Hello_World that include other headers): bullet3-2.89\src
source and header files are subdirectories of bullet3-2.89\src
libraries: bullet3-2.89\bin
but all headers use the correct relative paths in their include and I have set the project's include and library directories to those locations
I found a workaround. Just gonna hijack one of the example projects from Bullet and use that instead. They seem to be better at VS settings than me :D
Anyway, thanks for your suggestions.
Had the same issue where just a few of the functions didn't link.
This is most likely due to the Bullet library being built with BT_USE_DOUBLE_PRECISION, meaning all btScaler will be of type double.
But the library is included without BT_USE_DOUBLE_PRECISION, meaning the program will try to link with the float versions of the functions.
But they don't exists since the built version uses doubles.

Unresolved externals when compiling unit tests for Visual C++ 2012

I want to create unit tests for a Visual C++ project. I tried following these MSDN instructions. I've found pages where they differentiate between unmanaged/mixed/pure code, but I don't fully understand those concepts. My code doesn't use .NET and would likely compile under MinGW with a few code adjustments.
My main project builds an executable, so I followed the steps under To reference exported functions from the test project. For starters I got different project options:
I went with Native Unit Test Project. I added a reference to my main project and I set Include Directories to $(SolutionDir)\Cubes;$(IncludePath). I wrote my code and got this when compiling:
1>Creating library C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.lib and object C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.exp
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Room::Room(void)" (??0Room##QAE#XZ) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: __thiscall Layout::Layout(class Room *,int)" (??0Layout##QAE#PAVRoom##H#Z) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layout::add(int,int,class Room *)" (?add#Layout##QAEXHHPAVRoom###Z) referenced in function "public: void __thiscall CubesTest::LayoutTest::NumOfRoomsConsistency(void)" (?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ)
1>LayoutTest.obj : error LNK2019: unresolved external symbol "public: void __thiscall Layout::clear(int,int,bool)" (?clear#Layout##QAEXHH_N#Z) referenced in function __catch$?NumOfRoomsConsistency#LayoutTest#CubesTest##QAEXXZ$0
1>C:\Users\Pieter\Dropbox\Unief\TTUI\TTUIproject\Cubes\Debug\CubesTest.dll : fatal error LNK1120: 4 unresolved externals
If I'm not mistaken, this means that the compiler finds the header files, but not the source files. What am I missing?
Here is a step-by-step description on how to add an EXE as an unit-test target.
The key point is to "export" the functions/classes you want to test... You can download the complete sample here: http://blog.kalmbachnet.de/files/CPP_UnitTestApp.zip (I did not change any project settings, so all changes you can see in the source-code; of course, some parts can be made in the project settings).
Create a Win32 Application (Console or MFC or Windows, does not matter); I created a console project called CPP_UnitTestApp:
Add a function you want to test (you can also add classes). For example:
int Plus1(int i)
{
return i+1;
}
Add a header file for the functions you want to test: CPP_UnitTestApp.h
Put the declaration of the methods into the header file, and also export these functions!
#pragma once
#ifdef EXPORT_TEST_FUNCTIONS
#define MY_CPP_UNITTESTAPP_EXPORT __declspec(dllexport)
#else
#define MY_CPP_UNITTESTAPP_EXPORT
#endif
MY_CPP_UNITTESTAPP_EXPORT int Plus1(int i);
Include this header file in the main-cpp (here CPP_UnitTestApp.cpp) and define the EXPORT_TEST_FUNCTIONS before including the header:
#define EXPORT_TEST_FUNCTIONS
#include "CPP_UnitTestApp.h"
Now add a new project (Native unit test project: UnitTest1)
Include the header and the lib to the "unittest1.cpp" file (adopt the paths as you want):
#include "..\CPP_UnitTestApp.h"
#pragma comment(lib, "../Debug/CPP_UnitTestApp.lib")
Go to the project settings of the test project add add a reference to the "UnitTest1" project (Project|Properties|Common Properties|Add New Reference...: Select under "Projects" the "CPP_UnitTestApp"-Project)
Create the unit test function:
TEST_METHOD(TestMethod1)
{
int res = Plus1(12);
Assert::AreEqual(13, res);
}
Run your unit test ;)
As you can see, the main point was to export the function declaration! This is done via __declspec(dllexport) even if it is an EXE.
As I said, the demo project can be downloaded here: http://blog.kalmbachnet.de/files/CPP_UnitTestApp.zip

I have a third party lib, I have error LNK2019: unresolved external ... How to investigate to fix it

I have a third party libs. (msvc10) a MT/MD (Static cfgs's) and dynamic DLL cfg.
I have qt + msvc10 express + win sdk.7
Ok , I use the existing examples offered, (using the libs) I can't compile ..... I have 4 unresolved external errors of the same lib.
(But I have zero errors for the others)
I have not support for these lib...... (but they are legal, I am a member without rights)
Which are the steps to investigate a possible fix? Where I have to look ?
Thanks.
Edit 1:
The errors was:
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegEnumValueW#32 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegCloseKey#4 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegQueryValueExW#24 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol __imp__RegOpenKeyExW#20 referenced in function "public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(class OdTtfDescriptor const &,class OdString &)" (?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
..\exe\OdaQtApp.exe : fatal error LNK1120: 13 unresolved externals
During this post I have received a solution: I have to link with Advapi32.lib...
My question is : how can I know this ?
I have tried the dependencyywalker, but it cant use the .lib's....
During this post I have received a solution: I have to link with Advapi32.lib... My question is : how can I know this?
When you get an "unresolved external" error from the linker, that means that it was looking for a match for a function or variable name that some object file needs and the linker was unable to find that name defined in one of the object files or libraries.
Start by looking at the first of these errors (I've reformatted it a bit to make it slightly more readable - I encourage yo to do the same next time you come across one of these):
TD_ExamplesCommon.lib(ExHostAppServices.obj) : error LNK2019: unresolved external symbol
__imp__RegEnumValueW#32 referenced in function
"public: virtual bool __thiscall ExHostAppServices::ttfFileNameByDescriptor(
class OdTtfDescriptor const &,class OdString &)"
(?ttfFileNameByDescriptor#ExHostAppServices##UAE_N ABVOdTtfDescriptor##AAVOdString###Z)
There's a lot of stuff in that error message (much of it may look like garbage). Fortunately, much of it can be ignored in most cases. The most important item is that the linker is looking for the symbol __imp__RegEnumValueW#32 The name has some gunk on it, but fortunately it's pretty recognizable anyway.
the __imp__ prefix indicates it's looking for a DLL import. In nearly all cases that can be ignored for your purposes.
the #32 suffix is something the Microsoft compiler adds to function names for certain calling conventions. It's also generally not important for your purposes (for the record it indicates that the function expects 32 bytes of argument data)
So we're left with the fact that the linker is looking for RegEnumValueW. That looks a lot like the name of a Win32 API.
If you look at the docs for RegEnumValueW (or RegEnumValue, since many Win32 APIs have both an A and a W variant to handle ANSI/UNICODE builds) we'll find in the documentation this bit of information:
Requirements
Minimum supported client Windows 2000 Professional
Minimum supported server Windows 2000 Server
Header Winreg.h (include Windows.h)
>> Library Advapi32.lib
DLL Advapi32.dll
Unicode and ANSI names RegEnumValueW (Unicode) and
RegEnumValueA (ANSI)
That's how you know you need advapi32.lib.
So in the future, when you get an "unresolved external" error from the linker, just ignore most of the gunk in the error message and concentrate on the symbol it says it can't find - that should lead you to the library, object file or other item you might be missing.
Just for the record, advapi32.lib will be needed by most Windows applications of any complexity.
you can try to use dependencywalker to see the list of dependencies for your dlls and see what it's missing.
have you entered the *.lib file in the linker options? (input --> additional dependencies"), and in addition the path to the .lib in libraries directories option?

linking error with CMake and Visual Studio 2010

I'm trying to compile osgearth library with VS2010. The library uses CMake, so after setting all dependencies it generates a VS2010 solution file. However when running build in VS I get this linker error (and 200 similar ones)
Error 7 error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall std::basic_ofstream >::`vbase destructor'(void)" (_imp??_D?$basic_ofstream#DU?$char_traits#D#std###std##QAEXXZ) referenced in function "public: virtual void __thiscall osgEarth::DiskCache::setImage(class osgEarth::TileKey const &,struct osgEarth::CacheSpec const &,class osg::Image const *)" (?setImage#DiskCache#osgEarth##UAEXABVTileKey#2#ABUCacheSpec#2#PBVImage#osg###Z) C:\swproj\osgearth-src\src\osgEarth\Caching.obj osgEarth
I'm not very familiar with C++, is there anything else I have to set up?
You're missing a reference to std::ofstream. You either need an #include in one of your files or a reference to the standard library dll in your project.