Linking Ogre project to mygui using cmake

Seregon

13-11-2012 00:20:54

Windows 7
MinGW gcc 4.7
Ogre 1.8.1
MyGUI 3.2.0
Cmake 2.8
Boost 1.5.1

I've spent the past few days setting up my ogre project, and have managed to solve most problems I've had so far from posts on this and other forums (thanks!). I've compiled boost, ogre and mygui (MYGUI_Static = true) from source (including tools, demos, and plugins), the demos I've tested seem to work fine. The problem I've got now is linking mygui into my ogre project.

I've followed the quickstart guide (http://www.ogre3d.org/tikiwiki/tiki-ind ... quickstart), building on top of code from the Ogre basic tutorial project (http://www.ogre3d.org/tikiwiki/tiki-ind ... =Tutorials).

My cmakelists.txt is based on the one found one the ogre wiki (http://www.ogre3d.org/tikiwiki/tiki-ind ... With+CMake), with the following additions for MyGUI:
# Find MyGUI
set(MYGUI_COMPONENTS Common MyGUIEngine MyGUI.OgrePlatform)
find_package(MyGUI REQUIRED ${MYGUI_COMPONENTS})
find_library(MYGUI_LIBRARIES_FREETYPE
NAMES freetype
HINTS "${OGRE_MEDIA_DIR}/../Dependencies/lib"
PATH_SUFFIXES "" release debug)
find_package(Freetype REQUIRED)
include_directories(${MYGUI_INCLUDE_DIRS} ${MYGUI_PLATFORM_INCLUDE_DIRS})
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${MYGUI_LIBRARIES_FREETYPE} ${MYGUI_LIBRARIES} ${MYGUI_PLATFORM_LIBRARIES} )

target_link_libraries(${PROJECTNAME} ${OGRE_LIBRARIES} ${OIS_LIBRARIES})


and the findMyGUI.cmake I'm using:


# - Find MyGUI includes and library
#
# This module defines
# MYGUI_INCLUDE_DIRS
# MYGUI_LIBRARIES, the libraries to link against to use MYGUI.
# MYGUI_LIB_DIR, the location of the libraries
# MYGUI_FOUND, If false, do not try to use MYGUI
#
# Copyright © 2007, Matt Williams
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
CMAKE_POLICY(PUSH)
include(FindPkgMacros)

# IF (MYGUI_LIBRARIES AND MYGUI_INCLUDE_DIRS)
# SET(MYGUI_FIND_QUIETLY TRUE)
# ENDIF (MYGUI_LIBRARIES AND MYGUI_INCLUDE_DIRS)

IF (WIN32) #Windows
MESSAGE(STATUS "Looking for MyGUI")
SET(MYGUISDK $ENV{MYGUI_HOME})
IF (MYGUISDK)
findpkg_begin("MYGUI")
MESSAGE(STATUS "Using MyGUI in MyGUI SDK")
STRING(REGEX REPLACE "[\\]" "/" MYGUISDK "${MYGUISDK}")
message("${MYGUISDK}")

find_path(MYGUI_INCLUDE_DIRS
MyGUI.h
"${MYGUISDK}/MyGUIEngine/include"
NO_DEFAULT_PATH)

find_path(MYGUI_PLATFORM_INCLUDE_DIRS
MyGUI_OgrePlatform.h
"${MYGUISDK}/Platforms/Ogre/OgrePlatform/include"
NO_DEFAULT_PATH)

SET(MYGUI_LIB_DIR ${MYGUISDK}/lib ${MYGUISDK}/*/lib)

find_library(MYGUI_LIBRARIES_REL
NAMES MyGUIEngine MyGUI.OgrePlatform
HINTS ${MYGUI_LIB_DIR}
PATH_SUFFIXES "" release relwithdebinfo minsizerel)

find_library(MYGUI_LIBRARIES_DBG
NAMES MyGUIEngine_d MyGUI.OgrePlatform_d
HINTS ${MYGUI_LIB_DIR}
PATH_SUFFIXES "" debug)

find_library(MYGUI_PLATFORM_LIBRARIES_REL
NAMES MyGUI.OgrePlatform
HINTS ${MYGUI_LIB_DIR}
PATH_SUFFIXES "" release relwithdebinfo minsizerel)

find_library(MYGUI_PLATFORM_LIBRARIES_DBG
NAMES MyGUI.OgrePlatform_d
HINTS ${MYGUI_LIB_DIR}
PATH_SUFFIXES "" debug)

## Find freetype
find_library(MYGUI_LIBRARIES_FREETYPE
NAMES freetype
HINTS "$ENV{OGRE_DEPENDENCIES_DIR}/lib"
PATH_SUFFIXES "" Release relwithdebinfo minsizerel)
##

make_library_set(MYGUI_LIBRARIES)
make_library_set(MYGUI_PLATFORM_LIBRARIES)

MESSAGE("${MYGUI_LIBRARIES}")
MESSAGE("${MYGUI_PLATFORM_LIBRARIES}")
ENDIF (MYGUISDK)
IF (OGRESOURCE)
MESSAGE(STATUS "Using MyGUI in OGRE dependencies")
STRING(REGEX REPLACE "[\\]" "/" OGRESDK "${OGRESOURCE}" )
SET(MYGUI_INCLUDE_DIRS ${OGRESOURCE}/OgreMain/include/MYGUI)
SET(MYGUI_LIB_DIR ${OGRESOURCE}/lib)
SET(MYGUI_LIBRARIES debug Debug/MyGUIEngine_d optimized Release/MyGUIEngine)
ENDIF (OGRESOURCE)
ELSE (WIN32) #Unix
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.7 FATAL_ERROR)
FIND_PACKAGE(PkgConfig)
IF(MYGUI_STATIC)
IF (NOT APPLE)
PKG_SEARCH_MODULE(MYGUI MYGUIStatic MyGUIStatic)
IF (MYGUI_INCLUDE_DIRS)
SET(MYGUI_INCLUDE_DIRS ${MYGUI_INCLUDE_DIRS})
SET(MYGUI_LIB_DIR ${MYGUI_LIBDIR})
SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} CACHE STRING "")
ELSE (MYGUI_INCLUDE_DIRS)
FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI)
FIND_LIBRARY(MYGUI_LIBRARIES myguistatic PATHS /usr/lib /usr/local/lib)
SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES})
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}")
STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}")
ENDIF (MYGUI_INCLUDE_DIRS)
ELSE (NOT APPLE)
SET(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${MYGUI_DEPENDENCIES_DIR} ${OGRE_DEPENDENCIES_DIR})
FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI)
FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngineStatic PATHS /usr/lib /usr/local/lib)
SET(MYGUI_LIB_DIR ${MYGUI_LIBRARIES})
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIB_DIR}")
STRING(REGEX REPLACE ".*/" "" MYGUI_LIBRARIES "${MYGUI_LIBRARIES}")
# freetype is needed on OS X for static builds
FIND_PACKAGE(freetype)
SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} ${FREETYPE_LIBRARIES})
ENDIF (NOT APPLE)
ELSE(MYGUI_STATIC)
# Linux shared library
FIND_PATH(MYGUI_INCLUDE_DIRS MyGUI.h PATHS /usr/local/include /usr/include PATH_SUFFIXES MyGUI MYGUI)
FIND_LIBRARY(MYGUI_LIBRARIES MyGUIEngine PATHS /usr/lib /usr/local/lib)
STRING(REGEX REPLACE "(.*)/.*" "\\1" MYGUI_LIB_DIR "${MYGUI_LIBRARIES}")
ENDIF(MYGUI_STATIC)

SET(MYGUI_PLATFORM_LIBRARIES "MyGUI.OgrePlatform")
ENDIF (WIN32)

IF (MYGUI_INCLUDE_DIRS AND MYGUI_LIBRARIES)
SET(MYGUI_FOUND TRUE)
ENDIF()

# We need explicit freetype libs only on OS X for static build
IF (NOT FREETYPE_LIBRARIES AND APPLE AND MYGUI_STATIC)
MESSAGE(FATAL_ERROR "Freetype is requires for static build on OS X")
SET(MYGUI_FOUND FALSE)
ENDIF()

IF (MYGUI_FOUND)
MARK_AS_ADVANCED(MYGUI_LIB_DIR)
IF (NOT MYGUI_FIND_QUIETLY)
MESSAGE(STATUS " libraries : ${MYGUI_LIBRARIES} from ${MYGUI_LIB_DIR}")
MESSAGE(STATUS " includes : ${MYGUI_INCLUDE_DIRS}")
ENDIF (NOT MYGUI_FIND_QUIETLY)
ELSE (MYGUI_FOUND)
IF (MYGUI_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find MYGUI")
ENDIF (MYGUI_FIND_REQUIRED)
ENDIF (MYGUI_FOUND)

CMAKE_POLICY(POP)


all the libraries (inside the IF(WIN32), IF(MYGUISDK) block) are found succesfully, including freetype. Cmake runs succesfully, but the resulting makefile does not build (mingw32-make install) succesfully (simply including mygui.h is fine, but attempting to initialise MyGUI using the quickstart instructions breaks the compilation).

The output I get is lots of errors of the form:

C:/Ogre/built/MyGUI-3_2_0/lib/release/libMyGUI.OgrePlatform.a(MyGUI_OgreRTTextur
e.cpp.obj):MyGUI_OgreRTTexture.cpp:(.text+0x22a): undefined reference to `Ogre::
Viewport::setClearEveryFrame(bool, unsigned int)'


suggesting that either the MyGUI static libraries aren't properly linked to Ogre, or that they need to be linked at compile time and can't find Ogre (the rest of the app has no issues using OgreMain.dll). So, either I did something wrong when compiling MyGUI (suggestions?), or I need to provide a reference to Ogre when linking to MyGUI in my cmakelists.txt?

I could post a lot more information, but I suspect the solution is fairly obvious when you know what to look for, so let me know if you need more, or hopefully have a fix for me. Thanks!

Altren

13-11-2012 11:40:36

You also need to set -DMYGUI_STATIC in your build.

Seregon

13-11-2012 12:26:02

Thanks, I tried that by adding

add_definitions("-DMYGUI_STATIC")

above the find MyGUI block in cmakelistst.txt, but I'm still getting the same compilation errors.

Incase this helps, the linker call made by mingw32-make -d is below (indented to make it more readable)


CreateProcess(C:\MinGW\bin\g++.exe,
C:/MinGW/bin/g++.exe -O2 -g -DNDEBUG -mwindows -Wl,
--whole-archive CMakeFiles/Thrive.dir/objects.a -Wl,
--no-whole-archive -o dist/bin/Thrive.exe -Wl,
--out-implib,dist/bin/libThrive.dll.a -Wl,--major-image-version,0,--minor-image-version,
0 C:/Ogre/built/ogre-sdk/lib/release/libOgreMain.dll.a
C:/boost/lib/libboost_thread-mgw47-mt-1_51.a
C:/boost/lib/libboost_date_time-mgw47-mt-1_51.a
C:/boost/lib/libboost_system-mgw47-mt-1_51.a
C:/Ogre/built/dependencies/lib/Release/libfreetype.a
C:/Ogre/built/MyGUI-3_2_0/lib/release/libMyGUIEngine.dll.a
C:/Ogre/built/MyGUI-3_2_0/lib/release/libMyGUI.OgrePlatform.a
C:/Ogre/built/dependencies/lib/release/libOIS.dll.a
-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32,...)

Seregon

13-11-2012 12:56:13

Ok, so looking at the linker call, add_definitions() didn't do what I expected it to, so I've replaced it with

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMYGUI_STATIC")

and the linker call now looks like the below. The errors are still the same though.


CreateProcess(C:\MinGW\bin\g++.exe,C:/MinGW/bin/g++.exe -DMYGUI_STATIC -O2 -g -DNDEBUG
-mwindows -Wl,--whole-archive CMakeFiles/Thrive.dir/objects.a -Wl,
--no-whole-archive -o dist/bin/Thrive.exe -Wl,
--out-implib,dist/bin/libThrive.dll.a -Wl,
--major-image-version,0,--minor-image-version,
0 C:/Ogre/built/ogre-sdk/lib/release/libOgreMain.dll.a
C:/boost/lib/libboost_thread-mgw47-mt-1_51.a
C:/boost/lib/libboost_date_time-mgw47-mt-1_51.a
C:/boost/lib/libboost_system-mgw47-mt-1_51.a
C:/Ogre/built/dependencies/lib/Release/libfreetype.a
C:/Ogre/built/MyGUI-3_2_0/lib/release/libMyGUIEngine.dll.a
C:/Ogre/built/MyGUI-3_2_0/lib/release/libMyGUI.OgrePlatform.a
C:/Ogre/built/dependencies/lib/release/libOIS.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32,...)