Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: CMake not finding static SFML libraries of Windows  (Read 6459 times)

0 Members and 1 Guest are viewing this topic.

Zhuge

  • Newbie
  • *
  • Posts: 4
    • View Profile
CMake not finding static SFML libraries of Windows
« on: October 17, 2015, 09:25:36 pm »
In an attempt to learn how to use CMake to generate projects, I'm writing a simple project that uses CMake and trying to implement features I'm interested in. I was able to configure a project that has both an executable and another library file as well as including the version of Boost I have installed.

Versions of things I am using, in case it is relevant:
  • CMake 3.3.0
  • Visual Studio 2015 Community Edition
  • SFML 2.3.2 (built with CMake & VS above)
  • Boost 1.54.0
I've run into some trouble trying to configure the project to include SFML as well.

The first thing I did was copy the FindSFML.cmake file into my project's /cmake/Modules directory then including a line to make sure it is in the CMake module path:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")

Since I was using Windows, I wanted to specify where SFML was and then use the find_package() command. I was hoping to try to link statically, so I also defined the option for that. This is what I wrote:
if(NOT DEFINED     SFML_ROOT  AND
   NOT DEFINED ENV{SFML_ROOT})
        if(WIN32)
                set(SFML_ROOT "C:/Program Files (x86)/SFML")
        endif()
endif()
set(SFML_STATIC_LIBRARIES TRUE)
find_package(SFML 2 REQUIRED COMPONENTS system window graphics network audio)
include_directories(SYSTEM ${SFML_INCLUDE_DIR})
The SFML folder in Program Files is where I installed SFML to after building it with CMake.

Finally, I added this command to the properties for my main executable target:
target_link_libraries(Game ${Boost_LIBRARIES}
                           ${SFML_LIBRARIES}
                           Utilities)
Where Utilities is another target I was building as part of this project.

When I run CMake through the GUI, I get the following error message when it tries to find SFML:
CMake Error at cmake/Modules/FindSFML.cmake:358 (message):
  Could NOT find SFML (missing: SFML_SYSTEM_LIBRARY SFML_WINDOW_LIBRARY
  SFML_GRAPHICS_LIBRARY SFML_NETWORK_LIBRARY SFML_AUDIO_LIBRARY)
Call Stack (most recent call first):
  CMakeLists.txt:39 (find_package)

I looked at the properties CMake lists (checking Advanced so I can see all of them) and note something that seems strange to me: All of the SFML_X_LIBRARY_DYNAMIC_X properties are set to lib files, rather than DLLs as I would have expected. All of the properties for STATIC libraries are shown as not found.

If I manually copy over the lib file paths into the STATIC properties and reconfigure, the project generates correctly and I am able to compile and link. However, when I run the executable, it reports an error saying it cannot find sfml-system-d-2.dll, which I didn't think would be necessary since I was trying to link statically.

First, I'd like to know what I need to do in order to allow SFML's static libs to be found through CMake so I don't have to manually fix the properties. Assuming this doesn't also somehow fix the other issue, I'd like to know what I else I need to do if I want the generated project to link SFML statically rather than requiring DLLs.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11016
    • View Profile
    • development blog
    • Email
Re: CMake not finding static SFML libraries of Windows
« Reply #1 on: October 17, 2015, 09:35:31 pm »
You have a misunderstanding of what static libraries are.
(On Windows) shared libraries come with an import library (*.lib for MSVC or *.a for MinGW) and a shared library (*.dll). You link against the import library to tell your linker what symbols are available in the shared library.
Now static libraries also use *.lib for MSVC or *.a for MinGW, but they contain the full code and get built directly into your application.

For SFML the static libraries use the -s suffix (sfml-xyz-s.lib for release, sfml-xyz-s-d.lib for debug). If you don't have these in your SFML directory, you haven't  created static libraries of SFML.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Zhuge

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: CMake not finding static SFML libraries of Windows
« Reply #2 on: October 17, 2015, 09:47:41 pm »
Ok, looks like I don't have any of the static libraries built, so I some more work to do. Thanks for the prompt and helpful response!

Zhuge

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: CMake not finding static SFML libraries of Windows
« Reply #3 on: October 18, 2015, 09:16:52 pm »
I built the static libraries for SFML and am now having problems linking. The first set of linker errors were just me not linking some libraries SFML used, so I added this to my target:
target_link_libraries(Game ${Boost_LIBRARIES}
                           ${SFML_LIBRARIES}
                           ${FLAC_LIBRARY}
                           ${FREETYPE_LIBRARY}
                           ${JPEG_LIBRARY}
                           ${OGG_LIBRARY}
                           ${OPENAL_LIBRARY}
                           ${VORBIS_LIBRARY}
                           ${VORBISENC_LIBRARY}
                           ${VORBISFILE_LIBRARY}
                           Utilities)
This fixed a good number of the issues, but I was still getting issues with OpenGL functions not being resolved. I'm not sure if this was what I was meant to do, but I added the following to link to the OpenGL library:
find_package(OPENGL)
then used the library in my target so I ended up with:
target_link_libraries(Game ${Boost_LIBRARIES}
                           ${SFML_LIBRARIES}
                           ${FLAC_LIBRARY}
                           ${FREETYPE_LIBRARY}
                           ${JPEG_LIBRARY}
                           ${OGG_LIBRARY}
                           ${OPENAL_LIBRARY}
                           ${VORBIS_LIBRARY}
                           ${VORBISENC_LIBRARY}
                           ${VORBISFILE_LIBRARY}
                           ${OPENGL_gl_LIBRARY} # added
                           Utilities)
This fixed the OpenGL function errors, but there are still a few remaining I don't know the source of.

I have two questions about this:

First, was adding the CMake directives to find OpenGL the way I should be doing it, or was there something I was missing with SFML that I should have done to include OpenGL "properly"?

Second, I'm still getting a few linker errors in VS2015:
sfml-window-s-d.lib(JoystickImpl.obj) : error LNK2019: unresolved external symbol __imp__joyGetPosEx@8 referenced in function "public: static void __cdecl sf::priv::JoystickImpl::initialize(void)" (?initialize@JoystickImpl@priv@sf@@SAXXZ)
sfml-window-s-d.lib(JoystickImpl.obj) : error LNK2019: unresolved external symbol __imp__joyGetDevCapsW@12 referenced in function "public: bool __thiscall sf::priv::JoystickImpl::open(unsigned int)" (?open@JoystickImpl@priv@sf@@QAE_NI@Z)
sfml-system-s-d.lib(SleepImpl.obj) : error LNK2019: unresolved external symbol __imp__timeGetDevCaps@8 referenced in function "void __cdecl sf::priv::sleepImpl(class sf::Time)" (?sleepImpl@priv@sf@@YAXVTime@2@@Z)
sfml-system-s-d.lib(SleepImpl.obj) : error LNK2019: unresolved external symbol __imp__timeBeginPeriod@4 referenced in function "void __cdecl sf::priv::sleepImpl(class sf::Time)" (?sleepImpl@priv@sf@@YAXVTime@2@@Z)
sfml-system-s-d.lib(SleepImpl.obj) : error LNK2019: unresolved external symbol __imp__timeEndPeriod@4 referenced in function "void __cdecl sf::priv::sleepImpl(class sf::Time)" (?sleepImpl@priv@sf@@YAXVTime@2@@Z)

Is there another library I need to link like OpenGL that was used for these functions?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11016
    • View Profile
    • development blog
    • Email
Re: CMake not finding static SFML libraries of Windows
« Reply #4 on: October 18, 2015, 09:42:36 pm »
Right, I forgot to mention that after I saw that you hadn't added it.
You can simply add ${SFML_DEPENDENCIES} after ${SFML_LIBRARIES} and it will/should link all of SFML's dependencies.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Zhuge

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: CMake not finding static SFML libraries of Windows
« Reply #5 on: October 20, 2015, 05:36:36 am »
Oh, I had missed SFML_DEPENDENCIES even though it was mentioned in the CMake module. That addition got everything building. The last step was making sure the openal32.dll got into the executable's working directory, which I did with:
if(WIN32)
        add_custom_command(TARGET Game POST_BUILD
                           COMMAND ${CMAKE_COMMAND} -E copy_if_different
                                   "${SFML_ROOT}/bin/openal32.dll"
                                   $<TARGET_FILE_DIR:Game>)
endif()
Everything runs now; thanks again.