• Create Account

# CMake Issue - Need Help Getting it to work with GLEW and SFML

25 replies to this topic

### #1hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 05:51 PM

Hello all, so I've been working with SFML and GLEW in MSVC 2010 and have had very few issues (despite using static libraries for both, which can be an issue).  I'm able to compile and run and have no linking issues or anything.  However, I have plenty of friends whom I'd like to play my game that use Linux exclusively (Macs also for that matter).  So, I wanted to use CMake to allow me to compile on several different platforms.  I followed along the articles written here (http://www.gamedev.net/page/resources/_/technical/general-programming/cross-platform-test-driven-development-environment-using-cmake-part-1-r2986).   I put together a successful CMakeLists.txt and it gets through fine, finding my GLEW and SFML directories.  However, I get GLEW linking errors when I try to compile.  It compiles the game fine, but when it gets to linking it cannot get past this GLEW stuff.  At first I just thought it was the GLEW in SFML conflicting with my GLEW, but no matter what order I put the libraries in, I have the same issue.  I'm hoping that since I can compile with MSVC2010 .sln file, but not with this, it's just a configuration issue.  Hopefully someone here with experience with these 3 systems can give me some advice.  Here's my CMakeList.txt:

cmake_minimum_required(VERSION 2.6)
project(BattleMap)

include_directories(
"${PROJECT_BINARY_DIR}"$ENV{GLM_ROOT}
$ENV{RAPIDXML_ROOT}$ENV{GLEW_ROOT}/include
)

set(EXECUTABLE_NAME "BattleMap")
set(BattleMap_SRCS
battlemap.cpp
battlemap.h

bufferobject.cpp
bufferobject.h

camera.cpp
camera.h

globals.h

vertices.h

texture.cpp
texture.h

vao.cpp
vao.h

supertexture.cpp
supertexture.h

scene.cpp
scene.h

submapscene.cpp
submapscene.h

mapscene.cpp
mapscene.h

mousepointerscene.cpp
mousepointerscene.h

application.cpp
application.h

main.cpp
)

add_executable(${EXECUTABLE_NAME}${BattleMap_SRCS})

IF (WIN32)
MESSAGE("IS Win32")
ELSE (WIN32)
MESSAGE("NOT Win32")
ENDIF (WIN32)

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules"${CMAKE_MODULE_PATH})

IF (WIN32)
set_target_properties(glew_static PROPERTIES
IMPORTED_LOCATION $ENV{GLEW_ROOT}/lib/glew32s.lib) target_link_libraries(${EXECUTABLE_NAME} glew_static)
ELSE (WIN32)
find_package(GLEW REQUIRED)
ENDIF (WIN32)

find_package(SFML 2.0 REQUIRED system window graphics)
#find_package(GLEW REQUIRED)

if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR}) target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES}) endif() #if(GLEW_FOUND) # MESSAGE("GLEW include path found!") # include_directories(${GLEW_INCLUDE_PATH})
#	target_link_libraries(${EXECUTABLE_NAME}${GLEW_LIBRARY})
#endif()

# Install target
install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)  Some of the GLEW stuff commented out is just me trying different orders for CMake. If more information would be helpful, I'm more than happy to provide it. Thanks ahead of time. Sponsor: ### #2AllEightUp Moderators - Reputation: 4211 Like 2Likes Like Posted 23 May 2013 - 07:43 PM This is unfortunately a pain in the butt, I went through the problems myself recently. The simple answer is to look at the updated environment which is part of my next article, you can find the source at: https://code.google.com/p/a8u-tutorial-sources/. (Under the Game directory, not the "environment" one, that's out of date.) The SFML and XO applications link against SFML 2 statically on all three platforms. In your above cmake code you are likely linking against shared objects on Linux which can cause other problems. I'll take a further look into your code listfile when I move downstairs and get on my laptop and see if I can't point out specific issues. Oh, an important item of note. SFML links against glew already, so if you link statically as I do, don't bother trying to link glew, it's already there. Edited by AllEightUp, 23 May 2013 - 07:45 PM. ### #3hatfarm Members - Reputation: 224 Like 0Likes Like Posted 23 May 2013 - 08:05 PM Hmm... see it seems like it can't find a GLEW to link against, despite linking it or not... here's some of the linking output: >bufferobject.obj : error LNK2001: unresolved external symbol __imp____glewBindBuffer 2>texture.obj : error LNK2019: unresolved external symbol __imp__glTexImage2D@36 I'm having trouble figuring out why. It knows where my GLEW library is, because the glew.h include isn't a problem. CMake is such a hassle... ### #4AllEightUp Moderators - Reputation: 4211 Like 2Likes Like Posted 23 May 2013 - 08:17 PM CMake is not really the problem here, mixing dll's, static libs and such on Window's is being a pain in the butt for you. Notice in your link errors the prefix portion: __imp__. That means something is still attempting to use the glew headers without having defined GLEW_STATIC. Given this is windows, I'd suggest taking a look at the updated CMake files which deal with all this nonsense. I'm going to take a look at your listfile in more detail now, give me about 15-20 minutes. ### #5AllEightUp Moderators - Reputation: 4211 Like 2Likes Like Posted 23 May 2013 - 08:41 PM First pass notes, obviously I'm only able to poke at this so much without having a better idea of your setup. Basically you should not have to include the glew stuff at all for Window's, just point at the SFML glew include directory (in order to keep the version sync'd) in the extlibs dir. The other problem is not setting the static flag for SFML before the find. Hope this gets you going forward, let me know what goes wrong next.  #<snippity snip> set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) IF (WIN32) # Don't do this, glew is already statically linked as part of SFML 2.0. # It is probable that CMake strips this all out anyway, just be safe. # add_library(glew_static STATIC IMPORTED) # set_target_properties(glew_static PROPERTIES # IMPORTED_LOCATION$ENV{GLEW_ROOT}/lib/glew32s.lib)
#   target_link_libraries(${EXECUTABLE_NAME} glew_static) ELSE (WIN32) # NOTE: this will give you the shared object on other platforms. # not a problem, just important to keep in mind. find_package(GLEW REQUIRED) ENDIF (WIN32) # Detect and add SFML # You need to tell this to use static libs, probably only on Windows though: IF( WIN32 ) SET( SFML_STATIC_LIBRARIES TRUE ) ENDIF() find_package(SFML 2.0 REQUIRED system window graphics) #find_package(GLEW REQUIRED) if(SFML_FOUND) include_directories(${SFML_INCLUDE_DIR} )
target_link_libraries(${EXECUTABLE_NAME}${SFML_LIBRARIES})
endif()

#if(GLEW_FOUND)
#   MESSAGE("GLEW include path found!")
#   include_directories(${GLEW_INCLUDE_PATH}) # target_link_libraries(${EXECUTABLE_NAME} ${GLEW_LIBRARY}) #endif() # Install target install(TARGETS${EXECUTABLE_NAME} DESTINATION bin)



### #6hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 09:03 PM

I've still got the same problem.  I'm wondering if this is due to me using a different version of GLEW as SFML.  I'm using 1.9.0, I don't know what SFML uses, but could that be an issue?

... nope, that is not the issue.  Even if I add {SFML_ROOT}/extlib/headers to my includes, it gives me the same linking error.  I'm not sure what the difference could possibly be.

### #7AllEightUp  Moderators   -  Reputation: 4211

Like
2Likes
Like

Posted 23 May 2013 - 09:07 PM

Oops, forgot one other item.  You need to add:

ADD_DEFINITIONS( -DSFML_STATIC -DGLEW_STATIC )

To your application..  Without this you are trying to use the dynamic includes.

### #8hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 09:36 PM

Well, that changes things, but nothing good unfortunately.  It just tells me that I defined GLEW_STATIC in more than one file.  Which is nice to know, but not helpful.  It still has the same problem once I get to linking.  This is pretty frustrating...

### #9hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 09:44 PM

I also want to say, thank you so much for your help.  Even though I haven't been able to resolve the issue, I really appreciate that you are helping me so much.

### #10AllEightUp  Moderators   -  Reputation: 4211

Like
2Likes
Like

Posted 23 May 2013 - 10:05 PM

Well, for the moment, I'm not sure.  Probably you need to remove the glew static define since that is obviously not needed.  But I'm not sure how to fix the link error, that is almost surely an indication of glew static not being defined somewhere and as such trying to use declspec'd versions incorrectly, but I can't think of anything we've missed right now.  I'll go poke around in my codebase and see if I can find anything I did there that hasn't been covered yet.

One thing you might try is to remove any inclusions of glew/gl headers and only use the <SFML/OpenGL.hpp> header just in case there is an include order conflict somewhere.

As to helping out, no worries.  Been fighting with an SFML integration problem tonight trying to test the Spine runtimes, might use them for 2D stuff, just an experiment but it doesn't want to work correctly as of yet.

### #11hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 10:10 PM

Yeah, I'm wondering if using SDL might be a better option, or if maybe I should use Qt.  Qt 5.1 removes a need for GLEW at all, and would lose my need for GLM or SFML type stuff (and RapidXML).  However, I'd have to go in and refactor all my code for the way Qt does things, which is no fun.  However, I'd have a multiplatform project file that I understand pretty well already.  Anyway, thanks again.  I'm gonna keep plugging away, because I'd prefer not to have to refactor, but at some point I'm going to have to work on making actual code progress as opposed to CMake tinkering.

### #12AllEightUp  Moderators   -  Reputation: 4211

Like
2Likes
Like

Posted 23 May 2013 - 10:15 PM

Before you do anything drastic.  The best way I could help is with a buildable item.  Make a copy, remove all your code and just stick a main file in there that creates a window.  Assuming that still has the link problems, zip it up and let me take a look at it, can probably figure it out in fairly short order that way.

### #13hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 10:56 PM

Wow!  I got it to work.  It started with me essentially copying your CMakeLists.txt and adjusting it in ways I knew I could get it to work.  I think the problem was with FindSFML.cmake, because removing that and linking the directories made it compile (after some finessing).  Here's my final file, maybe you can think of a way to make it more brief

cmake_minimum_required(VERSION 2.6)
project(BattleMap)

include_directories(
"${PROJECT_BINARY_DIR}"$ENV{GLM_ROOT}
$ENV{RAPIDXML_ROOT}$ENV{SFML_ROOT}/extlibs/headers
$ENV{SFML_ROOT}/include ) set(EXECUTABLE_NAME "BattleMap") set(BattleMap_SRCS battlemap.cpp battlemap.h bufferobject.cpp bufferobject.h camera.cpp camera.h globals.h vertices.h texture.cpp texture.h vao.cpp vao.h supertexture.cpp supertexture.h shaderprog.cpp shaderprog.h scene.cpp scene.h submapscene.cpp submapscene.h mapscene.cpp mapscene.h mousepointerscene.cpp mousepointerscene.h application.cpp application.h main.cpp ) IF (WIN32) MESSAGE("IS Win32") ELSE (WIN32) MESSAGE("NOT Win32") ENDIF (WIN32) ADD_DEFINITIONS( -DSFML_STATIC ) add_executable(${EXECUTABLE_NAME} ${BattleMap_SRCS}) add_library(sfml_main STATIC IMPORTED) add_library(sfml_window STATIC IMPORTED) add_library(sfml_system STATIC IMPORTED) add_library(sfml_graphics STATIC IMPORTED) set_target_properties(sfml_main PROPERTIES IMPORTED_LOCATION$ENV{SFML_ROOT}/lib/sfml-main.lib)

set_target_properties(sfml_window PROPERTIES
IMPORTED_LOCATION $ENV{SFML_ROOT}/lib/sfml-window-s.lib) set_target_properties(sfml_system PROPERTIES IMPORTED_LOCATION$ENV{SFML_ROOT}/lib/sfml-system-s.lib)

set_target_properties(sfml_graphics PROPERTIES
IMPORTED_LOCATION $ENV{SFML_ROOT}/lib/sfml-graphics-s.lib) add_library(sfml_main_d STATIC IMPORTED) add_library(sfml_window_d STATIC IMPORTED) add_library(sfml_system_d STATIC IMPORTED) add_library(sfml_graphics_d STATIC IMPORTED) set_target_properties(sfml_main_d PROPERTIES IMPORTED_LOCATION$ENV{SFML_ROOT}/lib/sfml-main-d.lib)

set_target_properties(sfml_window_d PROPERTIES
IMPORTED_LOCATION $ENV{SFML_ROOT}/lib/sfml-window-s-d.lib) set_target_properties(sfml_system_d PROPERTIES IMPORTED_LOCATION$ENV{SFML_ROOT}/lib/sfml-system-s-d.lib)

set_target_properties(sfml_graphics_d PROPERTIES
IMPORTED_LOCATION $ENV{SFML_ROOT}/lib/sfml-graphics-s-d.lib) SET(link_sfml_main optimized sfml_main debug sfml_main_d) SET(link_sfml_window optimized sfml_window debug sfml_window_d) SET(link_sfml_system optimized sfml_system debug sfml_system_d) SET(link_sfml_graphics optimized sfml_graphics debug sfml_graphics_d) TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME}
${link_sfml_main}${link_sfml_window}
${link_sfml_system}${link_sfml_graphics}
)

SET_TARGET_PROPERTIES(${EXECUTABLE_NAME} PROPERTIES COMPILE_DEFINITIONS "GLEW_STATIC=" ) # Install target install(TARGETS${EXECUTABLE_NAME} DESTINATION bin)



Thank you again for your help.  Without your file, I wouldn't have been able to get this working.

### #14hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 11:14 PM

Now, I'm having an issue, but it's one I can stand to have.  It's generating a bad VS2010 solution.  When I try to run it, it tells me that it cannot find the file "path_to_bin\bin\Debug\ALL_BUILD".  Any experience with anything like that?  I'm not going to complain too much, but I'd like to be able to use the VS2010 debugger for debugging my code.  Thanks.

### #15hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 May 2013 - 11:17 PM

And, that's just me being dumb.  It's because VS2010 will have ALL_BUILD as the default project.  Setting the BattleMap project as the default project fixed it.

### #16AllEightUp  Moderators   -  Reputation: 4211

Like
2Likes
Like

Posted 23 May 2013 - 11:45 PM

Glad you figured it all out.  I'll see if I can come up with any simplifications for your new listfile, though CMake is often quite verbose as you know, so maybe not.  I'm going to be looking into the new 2.8.11 target usage requirement stuff because it solves a huge number of annoyances I have with CMake in larger projects.  It makes all the nonsense with passing parent scoped variables up the context chains go away.

Of course I rather expect you might be back in a bit with issues getting it to build on OsX and Linux.  I remember there being a couple gotcha's, mostly on OsX to make it all work.

### #17hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 24 May 2013 - 01:04 AM

I don't know how soon I'll be building in those environments.  Right now the code is only barely functional and not really something anyone would want to use and the only Mac I've got is my wife's Macbook that's a little over 4 years old.  As for Linux, I've got a virtual machine running Linux Mint that I could load up, but I really don't feel like troubleshooting that right now  However, I'm sure it's a good idea to troubleshoot now as opposed to later when I'm just trying to build it for a friend real quick.  Looking forward to your future articles!

### #18AllEightUp  Moderators   -  Reputation: 4211

Like
0Likes
Like

Posted 31 May 2013 - 08:48 PM

As a note, I started experimenting with the new target usage requirements introduced in CMake 2.8.11.  As soon as folks start pushing those out in their CMake environments your list files get quite a bit more simplified.  No more futzing around with figuring out required includes, support libraries or compile definitions.  All that work I did standardizing the parent scoped values goes away completely.  I think a CMake Part 5 will be coming soon as the changes are well worth a good article.

### #19hatfarm  Members   -  Reputation: 224

Like
0Likes
Like

Posted 23 July 2013 - 07:11 PM

So, I think I'm a day short of a necro on this, so just under the gun.  However, I thought I'd post in this thread again because it's related to that.  So, I've got it working in Windows, but I'm having issues with Linux.  I have it generate a Makefile, but it's not listing my include directories/libraries.  Any thoughts?  It's essentially the same as the text that was posted above (just a few more source files).

### #20AllEightUp  Moderators   -  Reputation: 4211

Like
0Likes
Like

Posted 24 July 2013 - 07:27 AM

So, I think I'm a day short of a necro on this, so just under the gun.  However, I thought I'd post in this thread again because it's related to that.  So, I've got it working in Windows, but I'm having issues with Linux.  I have it generate a Makefile, but it's not listing my include directories/libraries.  Any thoughts?  It's essentially the same as the text that was posted above (just a few more source files).

My first thought is to double check that on Linux you have the static version of SFML installed, I don't believe most Linux installations bother with the static version and only install the shared library versions.  As such, yup, you won't find what you are looking for.  Perhaps for Linux just try to use the shared version and see if that changes anything for you.

PARTNERS