7

I apologize for bothering you all, but I have a little compilation problem with cmake.

I have a CMakeLists.txt file I'm using to build a test executable, and a shared library. They both have dependency to another library (SFML).

I'm using cmake on window with MinGW.

I know the name of the lib I'm building is kinda confusing with the sfml one, but it's supposed to be a SFML wrapper, so, I didn't find a better name!

Here the CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(projectName)

set(EXECUTABLE_NAME testSFML)
set(LIBRARY_NAME    SFMLwindow)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include /
${CMAKE_CURRENT_SOURCE_DIR}/../../include
)

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/)

file(
    GLOB_RECURSE
    SRC_FILES
    src/*
)

file(
    GLOB_RECURSE
    INCLUDE_FILES
    include/*
)

add_executable(
${EXECUTABLE_NAME}
main.cpp
${SRC_FILES}
${INCLUDE_FILES}
)

target_link_libraries(
    ${EXECUTABLE_NAME}
    sfml-main
    sfml-system
    sfml-window
)


add_library(
${LIBRARY_NAME}
SHARED
${SRC_FILES}
)

And what I get in the terminal :

"C:\MinGW\bin\mingw32-make.exe" 
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/iksemel/docs/WorkBench/programming/projets/TestSFML/cmake
Linking CXX shared library libSFMLwindow.dll
Creating library file: libSFMLwindow.dll.a
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x59):undefined reference to `_imp___ZN2sf9VideoModeC1Ejjj'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0xda): undefined reference to `_imp___ZN2sf6WindowC1ENS_9VideoModeERKSsjRKNS_15ContextSettingsE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x163): undefined reference to `_imp___ZN2sf6Window5closeEv'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1bd): undefined reference to `_imp___ZN2sf6Window9pollEventERNS_5EventE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1d8): undefined reference to `_imp___ZN2sf6Window7displayEv'
collect2: ld a retourné 1 code d'état d'exécution
mingw32-make.exe[2]: *** [libSFMLwindow.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles/SFMLwindow.dir/all] Error 2
mingw32-make.exe: *** [all] Error 2

If anybody have a clue on what's happening, I'd be very gratefull!

Fraser
  • 74,704
  • 20
  • 238
  • 215
Cuthalion
  • 73
  • 1
  • 1
  • 3

1 Answers1

14

At a guess, your SFMLwindow library needs linked to some or all of sfml-main, sfml-system, sfml-window.

You could try changing the end of your CMakeLists.txt to:

add_library(
    ${LIBRARY_NAME}
    SHARED
    ${SRC_FILES}
    ${INCLUDE_FILES}
)

add_executable(
    ${EXECUTABLE_NAME}
    main.cpp
)

target_link_libraries(
    ${LIBRARY_NAME}
    sfml-main
    sfml-system
    sfml-window
)

target_link_libraries(
    ${EXECUTABLE_NAME}
    ${LIBRARY_NAME}
)


As an aside, file(GLOB_RECURSE... is generally frowned upon as a way to gather a list of sources. From the docs for file:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.


Also, find_library should be preferred to link_directories in this case. From the docs for link_directories:

Note that this command is rarely necessary. Library locations returned by find_package() and find_library() are absolute paths. Pass these absolute library file paths directly to the target_link_libraries() command. CMake will ensure the linker finds them.

Fraser
  • 74,704
  • 20
  • 238
  • 215
  • Thanks for the help, I edited my CMakeLists.txt, but it doesn't seem to work yet. But what's strange is, if I'm only building the executable, it works fine, it's only when building the library that I'm encountering this problem. And the .o files seem to be created as they should be. My CmakeLists.txt now : http://pastebin.com/hLux8Lvi – Cuthalion Jun 27 '12 at 08:39
  • I figured out the problem! You were right about the linking problem, but to correct it, I had to use 2 target_link_libraries. One for the executable and the other one for the library. The other problem I had was the command order. It seem that the *target_link_libraries* must appear after add_executable and add_library. Here's my current cmake, and again, thanks for the general information about cmake and helping me! http://pastebin.com/ErgbGir0 – Cuthalion Jun 27 '12 at 09:51
  • OK - glad it works. The main difference between our solutions is that you compile the sources into both the library *and* the exe. This is OK for small projects, but becomes a pain if you have a lot of source files. Normally, you'd compile the sources once only into the library, then just link that library to the test exe. With CMake, if you specify that lib A depends on lib B, and exe Z depends on lib A, then it automatically adds lib B as a dependency of Z too. Which is why I specified just `${LIBRARY_NAME}` as the dependency of `${EXECUTABLE_NAME}`. No biggie though :-) – Fraser Jun 27 '12 at 11:14
  • Again, thanks a lot for your experience! I now clearly understand what you wanted me to do and I must admit your solution is very efficient! I edited my CMakeLists.txt according to you : http://pastebin.com/xL5FATsL – Cuthalion Jun 28 '12 at 08:36