openvr icon indicating copy to clipboard operation
openvr copied to clipboard

Correct linking vs. building from src

Open crauterb opened this issue 8 years ago • 7 comments

Ahoi!

I seem to be getting quite frustrated right now, so please bear with me if this is just some stupid small thing I am currently overlooking...

After having a look at the documentation here and some example, I would just want to run a simple example to determine my correct linking. Assume the example looks something like this:

#include <openvr.h>

 vr::IVRSystem *vr_sys = nullptr;

 int main()
{
	vr::EVRInitError eError = vr::VRInitError_None;
	vr_sys = vr::VR_Init(&eError, vr::VRApplication_Scene);
	vr::VR_Shutdown();
    return 0;
}

As far as I got it, I just need to link to the according .lib files in the lib/ folder from openvr, and use the .dll and .pdb from the bin/ folder from openvr and the build the whole schazam in VS. However, now VS throws around something akin to:

    Error LNK2019: unresolved external symbol __imp__VR_GetGenericInterface referenced in function "public: class vr::IVRSystem * __thiscall vr::COpenVRContext::VRSystem(void)" (?VRSystem@COpenVRContext@vr@@QAEPAVIVRSystem@2@XZ)
    Error LNK2019: unresolved external symbol __imp__VR_IsInterfaceVersionValid referenced in function "class vr::IVRSystem * __cdecl vr::VR_Init(enum vr::EVRInitError *,enum vr::EVRApplicationType)" (?VR_Init@vr@@YAPAVIVRSystem@1@PAW4EVRInitError@1@W4EVRApplicationType@1@@Z)
    Error LNK2019: unresolved external symbol __imp__VR_GetInitToken referenced in function "public: void __thiscall vr::COpenVRContext::CheckClear(void)" (?CheckClear@COpenVRContext@vr@@QAEXXZ)
    Error LNK2019: unresolved external symbol __imp__VR_InitInternal referenced in function "class vr::IVRSystem * __cdecl vr::VR_Init(enum vr::EVRInitError *,enum vr::EVRApplicationType)" (?VR_Init@vr@@YAPAVIVRSystem@1@PAW4EVRInitError@1@W4EVRApplicationType@1@@Z)
    Error LNK2019: unresolved external symbol __imp__VR_ShutdownInternal referenced in function "class vr::IVRSystem * __cdecl vr::VR_Init(enum vr::EVRInitError *,enum vr::EVRApplicationType)" (?VR_Init@vr@@YAPAVIVRSystem@1@PAW4EVRInitError@1@W4EVRApplicationType@1@@Z)
    Error LNK1120: 5 unresolved externals

therefore I guess I am safe to assume some form of error in the linking ;-)

Question here being: Is my understanding correct, that I can use the provided librarys from lib/ and bin/ - or should I compile all of it from source and use the .lib files that VS generates from there on?

Appreciate some help :-)

crauterb avatar Jan 12 '17 14:01 crauterb

All of those symbols are defined as inlines in openvr.h. Is there something strange about your compile settings that cause inlines to not resolve?

JoeLudwig avatar Jan 12 '17 17:01 JoeLudwig

You have most likely forgot to point to the openvr_api.lib file in the linker input of your project.

If you go to the (I'll refer to VS2013 here, your path might vary):

Project properties >Configuration Properties > Linker > Input > Additional Dependencies

you should add the openvr_api.lib into that field. You should now be able to build your project.

I assume you've already managed to point to the openvr base and header folder in your C/C++ Additional Include Directories.

petethor avatar Jan 13 '17 09:01 petethor

Alright. First off: Thanks for you input guys!

@petethor So far, I did link the openvr_api.lib as an Additional Dependency, I did update the Library Path with the corresponding directory and I have listed the directories of headers etc. as Additional Include Directories.

Following @JoeLudwig , I did check about them inline functions. I am beginning to have my suspicions about a fault there - however with my current line of thoughts, I figure that someone else surely must have encountered this :D

If we have a look here, we find the money quote:

Note: It’s imperative that the function’s definition (the part between the {...}) be placed in a header file, unless the function is used only in a single .cpp file. In particular, if you put the inline function’s definition into a .cpp file and you call it from some other .cpp file, you’ll get an “unresolved external” error from the linker.

... which would exactly explain why I get the error with the above example - if I am not mistaken, as the listed inline functions are not defined in the header file openvr.h. Again, if that would truly be the case, someone else must have encountered the same error - which is apparently not the case and I am still thinking I am overlooking something terribly obvious :D

Using g++ through the git bash under Windows, I do run into the same errors:

g++ -o OpenVrTest OpenVrTest.cpp -I ../openvr/headers -I ../openvr/src/ -std=c++0x -L ./lib/ -l openvr_api

C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr14COpenVRContext10CheckClearEv[__ZN2vr14COpenVRContext10CheckClearEv]+0x12): undefined reference to `_imp__VR_GetInitToken'
C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr14COpenVRContext10CheckClearEv[__ZN2vr14COpenVRContext10CheckClearEv]+0x33): undefined reference to `_imp__VR_GetInitToken'
C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr14COpenVRContext8VRSystemEv[__ZN2vr14COpenVRContext8VRSystemEv]+0x2c): undefined reference to `_imp__VR_GetGenericInterface'
C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr7VR_InitEPNS_12EVRInitErrorENS_18EVRApplicationTypeE[__ZN2vr7VR_InitEPNS_12EVRInitErrorENS_18EVRApplicationTypeE]+0x23): undefined reference to `_imp__VR_InitInternal'
C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr7VR_InitEPNS_12EVRInitErrorENS_18EVRApplicationTypeE[__ZN2vr7VR_InitEPNS_12EVRInitErrorENS_18EVRApplicationTypeE]+0x4d): undefined reference to `_imp__VR_IsInterfaceVersionValid'
C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr7VR_InitEPNS_12EVRInitErrorENS_18EVRApplicationTypeE[__ZN2vr7VR_InitEPNS_12EVRInitErrorENS_18EVRApplicationTypeE]+0x62): undefined reference to `_imp__VR_ShutdownInternal'
C:\Users\CHRIST~1\AppData\Local\Temp\ccNsgtTh.o:OpenVrTest.cpp:(.text$_ZN2vr11VR_ShutdownEv[__ZN2vr11VR_ShutdownEv]+0x7): undefined reference to `_imp__VR_ShutdownInternal'
collect2.exe: error: ld returned 1 exit status

crauterb avatar Jan 19 '17 13:01 crauterb

I just ran into the same issue when compiling OpenVR myself. When using cmake, the default settings make it a static library. The problem is that openvr.h defines VR_INTERFACE as either dllimport or dllexport, which is perfectly fine for building and using a dll, but breaks with static linking.

Because static linking is what I want to do, I fixed it by defining VR_BUILD_SHARED from cmake if BUILD_SHARED is on and then checking for the VR_BUILD_SHARED define in openvr.h. If it isn't defined: #define VR_INTERFACE extern "C"

I also made pull request with my changes: https://github.com/ValveSoftware/openvr/pull/483

Slin avatar Apr 25 '17 23:04 Slin

1 - Make sure you have added the location of "openvr_api.lib" to "Additional Library Directories" : image

2 - Make sure you have added it to "Additional Dependencies": image

kbigdelysh avatar Oct 04 '18 17:10 kbigdelysh

I still run into this issue. Does anyone know how to fix it with the openvr_api.lib provided?

AlexanderWelling avatar Dec 13 '22 17:12 AlexanderWelling

In the project where you include openvr.h you should define OPENVR_BUILD_STATIC. This should stop the header from trying to dynamically import/export static stuff.

MillzyDev avatar Jun 12 '24 17:06 MillzyDev