OSG integration with QT...Trouble linking libraries.



  • I have had trouble linking OSG to QT. I am trying to use .pro file over CMakelists.
    I have tried the -L<path> -l<library> to import all the OSG libraries.
    At first i receive multiple LNK2001 errors , which were resolved by building OSG in QT.
    This resolved most of the LNK2001 erros.
    Now I still receive plenty of LNK2019 errors similar to below. I understand it is a linking problem but I can wrap my head around what I am missing. I have made sure Im using the correct release/debug libraries.

    myFiles.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: static class osg::Matrixd __cdecl osg::Matrixd::rotate(double,class osg::Vec3f const &,double,class osg::Vec3f const &,double,class osg::Vec3f const &)" (_imp?rotate@Matrixd@osg@@SA?AV12@NAEBVVec3f@2@N0N0@Z) referenced in function "public: virtual void __cdecl myFiles::saveAs(void)" (?saveAs@myFiles@@UEAAXXZ)


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Then are you sure that you are linking to all the required libraries from OSG ?



  • @SGaist yes.
    Yes. I link ALL of the libraries. I left out the wrappers and plugins but those dont seem related.

    LIBS += -Lpath/to/osg-3.5.1-qtcreator/lib -lot20-OpenThreads
    -losg141-osgAnimation
    -losg141-osgDB
    -losg141-osgFX
    -losg141-osgGA
    -losg141-osgManipulator
    -losg141-osgParticle
    -losg141-osgPresentation
    -losg141-osgQt
    -losg141-osgShadow
    -losg141-osgSim
    -losg141-osgTerrain
    -losg141-osgText
    -losg141-osgUI
    -losg141-osgUtil
    -losg141-osgViewer
    -losg141-osgVolume
    -losg141-osg


  • Lifetime Qt Champion

    Ok, then check the corresponding header file to see if that symbol is properly exported.



  • @SGaist Can you explain what you mean more?
    I checked all the include headers and for example Matrixd is present in the include folder and should be part of the osg141-osg.lib


  • Lifetime Qt Champion

    With Visual Studio, if you have a shared library and you want to be able to use a class/method from another application/library, you have to export it properly.

    You can see more details about that here.



  • @SGaist it was to my understanding I was building OSG as a static lib.
    I am able to build and execute the application using CMakelists, but I'm trying to convert it to a .pro file for experimental reason.


  • Lifetime Qt Champion

    Ok, then are you linking them in the correct order ?



  • This post is deleted!


  • @SGaist I would like to think so. I was linking them the way i commented above but that was wrong so i went and changed it. But no results. same errors
    LIBS += -L"C:/Packages/VC14/osg-3.5.1-qtcreator/lib" -losg141-osg
    -lot20-OpenThreads
    -losg141-osgAnimation
    -losg141-osgDB
    -losg141-osgFX
    -losg141-osgGA
    -losg141-osgManipulator
    -losg141-osgParticle
    -losg141-osgPresentation
    -losg141-osgQt
    -losg141-osgShadow
    -losg141-osgSim
    -losg141-osgTerrain
    -losg141-osgText
    -losg141-osgUI
    -losg141-osgUtil
    -losg141-osgViewer
    -losg141-osgVolume
    -losg141-osgWidget


  • Lifetime Qt Champion

    And the exact same application builds properly with cmake ?



  • @SGaist
    Yes. With CMake I can run it just fine.
    Could it be because I have not linked the plugins?


  • Lifetime Qt Champion

    Which plugins are you referring to ?



  • @SGaist 0_1478558672144_upload-789a9b9f-9e5e-4bde-9100-687d3b1c5483

    0_1478558684171_upload-8adf3c55-f061-4cb5-a7cd-4ed82e2916e8

    First is the page of lib folder
    2nd is the plugins.

    Fixing the order of the libraries got rid of the remaining LNK2001 errors i had.
    Now all I have left is 7 LNK2019 errors similar to the original post



  • @SGaist i thought i attached the images but i hadnt seen they arent visible. I will link them first hting in the morning. I appreciate the input greatly.
    Thank you


  • Lifetime Qt Champion

    The upload feature is currently broken so you have to use an image sharing site in between.



  • @SGaist [url=https://postimg.org/image/a2npfn1en/][img]https://s3.postimg.org/a2npfn1en/osglib.png[/img][/url]

    [url=https://postimg.org/image/w341w9k2n/][img]https://s3.postimg.org/w341w9k2n/plugins.png[/img][/url]

    [url=https://postimage.org/]image hosting over 5mb[/url]
    there are more plugins but the ones I use are
    osgdb_osg
    osgdb_serializers_osg
    osgdb_ply
    osgdb_3ds
    osgdb_stl
    osgdb_obj)
    osgdb_bmp
    osgdb_bvh
    osgdb_cfg
    osgdb_dxf
    osgdb_glsl
    osgdb_tga
    osgdb_png
    osgdb_jpeg
    osgdb_tiff
    osgdb_gif
    osgdb_freetype




  • Lifetime Qt Champion

    Can you compare the link line you have between your cmake project and your qmake project ?



  • @SGaist I went an added all the plugins in the order the CMakelist does it and it didnt fix any errors. The problems seem. THe remaining errors have to do with
    osg::Matrixd
    osg::Matrixf

    osgVolume::Volume
    osgVolume::Layer
    osg::Group
    osg::BoundingSphereImpl

    I was able to eliminate another error by simply linking the libraries before certain statements in the .pro file but im still at 6 errors

    I had 2 additional errors previously at
    osg::Sphere
    osg::Vec3f
    but I was able to get this remove by simply moving my LIBS statement higher up in the .pro.
    What i dont understand is that even though im using a .pri file and including in every subproject, unless i directly add the libraries to the .pro file more errors persist


  • Lifetime Qt Champion

    Check the order of the libraries you are linking, when building with static libraries it is important.



  • I have. The order is identical to the CMakeList.
    What im noticing though is that depending on where i call the LIBS i get more LNK2019 errors.

    What is the ideal way to import Libraries on a high level thus that the subproject inherit them.

    I have included the OSG libs in every subproject and in my .pri file that I am currently adding to every project.



  • isnt a .pri file just an extension of a .pro ?
    my first statement in every .pro file is including the .pri which then has the dependecies and includepaths/depedentpath and libs set up.
    But I get less LNK2019 errors when i directly go and add the LIBS to the .pro in every subproject.

    If what im saying is unclear. Ill try another explanation.
    in my 5 subprojects i copy pasted the OSG LIBS in the right order. Which minimized my LNK2019 errors. At the same time I include a .pri file that calls OSG LIBS anyway. With that set up I received 6 LNK2019 errors.
    IF i remove the LIBS call in every .pro, and just call it in my .pri file. I receive 26 Lnk2019 errors


  • Lifetime Qt Champion

    No, a .pri file follows exactly the same patterns as a .pro file. The difference is purely that .pri files are meant to be included in other .pro/.pri files while .pro files represent the project itself.

    However, if you have other LIBS statement in your .pro files then you should include your .pri file after that. The point where you include your .pri files depend on what you are doing in that .pri file. e.g. if you modify the TARGET variable then you should include that .pri file after you have setup TARGET in your .pro file.



  • my .pro files follow the following format

    include .pri

    target <project name>
    template = lib
    Config += staticlib
    DEFINES += <name>

    sources

    headers

    my .pri file looks like this

    QT += core gui opengl widgets
    LIBS -L<path to osg> -l<lib>
    ...
    -l<last osg lib>

    includepaths
    dependentpaths

    Then i use the following code to set my dependencies as my main is in a subproject and i want to link the other lib subprojects to the app. the following code below seems to work just fine.
    TARGET_DIRECTORY_NAME = 0 #The target directory name (just the project folder name)
    TARGET_PATH = 0 #The path to the project directory from the root folder
    LIB_PATH = 0 #The path to the LIB

    [The MACRO]

    The "dep" variable that is used in these two for loops will hold the paramaters from the DEPENDENCY_PROJECT.

    From the example above this would hold projectX and projectY (a litteral string)

    Now this function will loop through all the parameters

    [Setup the Dependencies]

    for(dep, DEPENDENCY_PROJECT) {
    TARGET_NAME = $${dep} # The name of the depending target
    message($${TARGET}.depends = $${TARGET_NAME})
    $${TARGET}.depends += $${TARGET_NAME}
    }

    [setup the actual library dependencies]

    for(dep, DEPENDENCY_PROJECT) {
    TARGET_NAME = $${dep} # The name of the depending target
    TARGET_PATH = $${PWD} # The path to the depending target source
    LIB_PATH = $${OUT_PWD}/../$${TARGET_NAME} # The path to the depending compiled target
    #message(Depending target "$${TARGET_NAME}" source path: $${TARGET_PATH})
    #message(Depending target "$${TARGET_NAME}" compiled path: $${LIB_PATH})

    # Adds the wanted lib to the linker
    win32:CONFIG(release, debug|release): LIBS += -L$${LIB_PATH}/release/ -l$${TARGET_NAME}
    else:win32:CONFIG(debug, debug|release): LIBS += -L$${LIB_PATH}/debug/ -l$${TARGET_NAME}
    #message(Depending lib to linker "$$LIBS")
    
    # Adds the wanted lib to the project.
    INCLUDEPATH += $${TARGET_PATH}
    #message(INCLUDEPATH: $${INCLUDEPATH})
    
    # Adds a dependpath to the project
    # This forces a rebuild if the headers change
    DEPENDPATH += $${TARGET_PATH}
    #message(DEPENDPATH: $${DEPENDPATH})
    
    #Pre target
    PRE_TARGETDEPS += $${PWD}/$${dep}
    message(PRE_TARGETDEPS: $${PRE_TARGETDEPS})
    

    }


  • Lifetime Qt Champion

    Do you mean you use the subdirs template ?



  • I use that on my Top level.
    the lay out is somewhat like this

    .pro<subdir template>
    -.pro<lib template>
    -.pro<lib template>
    -.pro<lib template>
    -.pro<app where main resides><links to the other 4 subprojects as dependent libs
    -.pro<lib template>


  • Lifetime Qt Champion

    The myFiles class is part of your application ?



  • @SGaist Yes. It is one of the libraries I am building. The errors dont all occur in myFile.
    they occur in side other libraries im building as well. In each it seems to be a different osg function.


  • Moderators

    One thing you could do since both cmake and qmake create a Makefile is to compare the differences in linking in both generated Makefile's and see where things may go wrong.

    That being said I highly recommend using cmake. Qt has full cmake support. It can be a bit confusing at first, but cmake is the most powerful and awesome build creation system I've used in my career. I bet if you use it you'll find it just as good as I do and drop using qmake. ;)

    When I get contracts to work on systems that don't use cmake I get bummed now. Especially since my favorite IDE these days (Clion from jetbrains) only really works with cmake.



  • @ambershark The reason i chose qmake is to avoid reading opengles with CMake. I had multiple errors with CMake and problems when trying to run stuff like find_pagkages(OPENGLES)
    As much as i Like Cmake it doesnt seem good for android


  • Moderators

    @mBiz I've never worked with opengles so no comment on cmake in regards to that. :) I've definitely switched build systems when one is too nightmarish to work with on someone else's project.

    I have successfully used cmake on a few android projects though. I find it is quite good at android. Android after all is just linux and that is my primary development environment so I usually need very few modifications to make my linux cmake work properly with android. Usually it just comes down to toolchain settings and finding android packages (like you referenced above).

    Anyway didn't mean to detract for your real issue with my cmake stuff, just wanted to mention that since it seemed like you were converting away from cmake to qmake, which to me is the wrong direction. ;)

    I've had similar problems to yours and having a working Makefile (i.e. the one from cmake) means you can find the differences in the qmake version that isn't linking properly. I'd just start comparing those (assuming you know make fairly well, otherwise they can be hard to read/understand).

    The other thing I'd do is find which library the missing symbol is in and find out if you include that library and if your syntax for the include is correct. Another thing that has caught me up before is linking a library that wasn't built for the platform I'm targeting. I.e. linking an x86/amd64 .so file to an ARM platform (android). There will be no errors but the link will not include those symbols. That one is probably the one that gets me the most.

    Assuming a posix os you could try using the file command on your libraries to make sure they are in the proper format. You could also use nm and ar to see what symbols are in each lib/object file to make sure they are being built properly.

    My guess based is you are linking to libraries for the wrong platform. Something easy to do when your build machine is not the same architecture as your deployment target.

    Oh and one final note, make sure that the linking isn't picking up libraries installed at a system level rather than the ones you've built for android. This can happen a lot especially with Qt and other libs that are used in a development environment and for a Linux system. So you may think you are linking against your Qt-5.7 built for android but in reality the linker is finding the Qt-5.2 that is installed in /usr/lib64.

    Hope those tips help, good luck! :)



  • @ambershark Im mostly trying to find the most effective way to port this chunk of code i have. It works in Cmake just fine. I have been able to import all the libraries fine for android but Opengl has been an absolute pain. QT ports open gl easily


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.