Using HlmsColibri causes LNK error Topic is solved

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


knn217
Halfling
Posts: 78
Joined: Wed Jan 25, 2023 9:04 am
x 5

Using HlmsColibri causes LNK error

Post by knn217 »

Hello, I decided to try ColibriGUI recently and managed to build and run the sample successfully.

Then I tried implementing it in my project, and my 1st step was replacing HlmsUnlit with Hlms Colibri in the function "registerHlms()", but I got the errors:

Code: Select all

1>main.obj : error LNK2019: unresolved external symbol "public: __cdecl Ogre::HlmsColibri::HlmsColibri(class Ogre::Archive *,class std::vector<class Ogre::Archive *,class std::allocator<class Ogre::Archive *> > *)"
1>main.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Ogre::HlmsColibri::getDefaultPaths(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::vector<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> > > > &)" 

I figured this was caused by my VS project settings, so I created a test project with only 1 file "main.cpp":

Code: Select all

#include <windows.h>
#include <windowsx.h>
#include <ole2.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <fstream>
#include <thread>
#include <strsafe.h>

#include "OgreAbiUtils.h"
#include "OgreArchiveManager.h"
#include "OgreCamera.h"
#include "OgreConfigFile.h"
#include "OgreRoot.h"
#include "OgreWindow.h"
#include "OgreHlmsManager.h"
#include "OgreHlmsPbs.h"
#include "OgreHlmsUnlit.h"
#include "OgreHlmsDiskCache.h"
#include "OgreOverlay.h"
#include "OgreOverlayContainer.h"
#include "OgreOverlayManager.h"
#include "OgreOverlaySystem.h"
#include "OgreTextAreaOverlayElement.h"
#include "OgreBorderPanelOverlayElement.h"
#include "OgreBillboardSet.h"
#include "OgreRectangle2D2.h"
#include "OgreSingleton.h"
#include "OgreRenderSystem.h"
#include "OgreTextureGpu.h"
#include "OgreTextureGpuManager.h"
#include "OgreSceneManager.h"
#include "OgreMeshManager.h"
#include "OgreMeshManager2.h"
#include "OgreGpuProgramManager.h"
#include "OgreLogManager.h"
#include "OgrePlatformInformation.h"
#include "Compositor/OgreCompositorManager2.h"
#include "OgreWindowEventUtilities.h"
#include "System/Android/AndroidSystems.h"
#include "OgreItem.h"
#include "Animation/OgreSkeletonAnimation.h"
#include "Animation/OgreSkeletonInstance.h"
#include "Animation/OgreTagPoint.h"
#include "Threading/YieldTimer.h"
#include "OgreTimer.h"
#include "OgrePixelFormatGpuUtils.h"
#include "OgreTextureBox.h"
#include "OgreHardwareBufferManager.h"
#include "OgreMesh.h"
#include "OgreMesh2.h"
#include "OgreHlmsPbsDatablock.h"
#include "OgreHlmsSamplerblock.h"
#include "OgreHlmsUnlitDatablock.h"
//---------------------------------------------------------------------------------------------------------------------
#include "SDL.h"
#include "ColibriGui/ColibriManager.h"
#include "ColibriGui/Text/ColibriShaperManager.h"
#include "ColibriGui/Text/ColibriShaper.h"
#include "ColibriGui/Ogre/CompositorPassColibriGuiProvider.h"

#include "ColibriGui/Ogre/OgreHlmsColibri.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR strCmdLine, INT nCmdShow)
#else
int main(int argc, const char* argv[])
#endif
{
	Ogre::HlmsColibri* hlmsColibri = 0;
	Ogre::String mainFolderPath;
	Ogre::StringVector libraryFoldersPaths;
	Ogre::HlmsColibri::getDefaultPaths(mainFolderPath, libraryFoldersPaths);

return 0;
}

After that, I copied the "ColibriGui" project's property settings to this new test project.
However, I still get the error:

Code: Select all

1>main.obj : error LNK2019: unresolved external symbol "public: static void __cdecl Ogre::HlmsColibri::getDefaultPaths(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &,class std::vector<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> > > > &)"

The test project does have "calling convention" set to /Gd and was linked to the same libs as "ColibriGui" project.
I'm kinda stuck at this point, anyone got an idea?

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5477
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1359

Re: Using HlmsColibri causes LNK error

Post by dark_sylinc »

Hi!

Colibri is not a header-only library, you need to link against its library. It was thought so that it could be added to CMake projects like this:

Code: Select all

set( BUILD_SHARED_LIBS OFF ) # optional
set( COLIBRIGUI_LIB_ONLY 1 )
add_subdirectory( path_to_colibri_repository_root )

target_link_libraries( ${PROJECT_NAME}  ColibriGui )

If you're not using CMake, you'll have to create a library yourself and link against it.

I think you can do so if you edit CMakeLists.txt in Colibri and set early in the beginning:

Code: Select all

set( COLIBRIGUI_LIB_ONLY 1 )

Cheers

knn217
Halfling
Posts: 78
Joined: Wed Jan 25, 2023 9:04 am
x 5

Re: Using HlmsColibri causes LNK error

Post by knn217 »

Ah! I see, I'll try to build the libs then

knn217
Halfling
Posts: 78
Joined: Wed Jan 25, 2023 9:04 am
x 5

Re: Using HlmsColibri causes LNK error

Post by knn217 »

dark_sylinc wrote: Wed Jul 26, 2023 3:14 pm

I think you can do so if you edit CMakeLists.txt in Colibri and set early in the beginning:

Code: Select all

set( COLIBRIGUI_LIB_ONLY 1 )

Cheers

I'm using Visual Studio, MSVC

When I tried running cmakeGUI after adding this line to "CMakeLists.txt", The solution and projects are generated but some Ogre include files weren't found.

But it worked when I run Cmake configure without

Code: Select all

set( COLIBRIGUI_LIB_ONLY 1 )

beforehand, and then run Cmake again with this line and configure -> generate.
Apparently, if I add this line, CmakeGui won't show these during configuration:

Code: Select all

Detected DLL build of Ogre
Found SDL2
Detected Atmosphere Component. Linking against it.
Copying Hlms data files from Ogre repository
Copying Common data files from Ogre repository
Copying DLLs and generating Plugins.cfg for Debug
Copying DLLs and generating Plugins.cfg for Release
Copying DLLs and generating Plugins.cfg for RelWithDebInfo
Copying DLLs and generating Plugins.cfg for MinSizeRel
Generating D:/OGRE_NEXT/colibrigui/bin/Data/resources2.cfg from template
		D:/OGRE_NEXT/colibrigui/CMake/Templates/Resources.cfg.in
Copying OgreSamplesCommon cpp and header files to
		D:/OGRE_NEXT/colibrigui/include/OgreCommon
		D:/OGRE_NEXT/colibrigui/src/OgreCommon/

The last line is probably the cause of this problem, I tried fixing ColibriGui's "CMakeLists.txt" myself but still new to cmake.
I think the problem is probably here

Code: Select all

if( NOT COLIBRIGUI_LIB_ONLY )
	setupOgre( OGRE_SOURCE, OGRE_BINARIES, OGRE_LIBRARIES )
else()
	include_directories( "${OGRE_SOURCE}/OgreMain/include" )
	include_directories( "${OGRE_BINARIES}/include" )
	include_directories( "${OGRE_SOURCE}/Components/Hlms/Common/include" )
	include_directories( "${OGRE_SOURCE}/Components/Hlms/Unlit/include" )
endif()

but when I copied setupOgre( OGRE_SOURCE, OGRE_BINARIES, OGRE_LIBRARIES ) to else(), cmake couldn't understand setupOgre

TL;DR - Ogre modules aren't included in the generated project if run CMake with set( COLIBRIGUI_LIB_ONLY ON ), an easy get around is to run CMake configure once more with set( COLIBRIGUI_LIB_ONLY OFF ).