When I want to compile project using CMake with SFML library by mingw (last verison), I catch a lot of strange errors (c++).
CMake code:
cmake_minimum_required(VERSION 3.0)
project(MLproject)
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc")
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++")
SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib")
set(CMAKE_CXX_STANDARD 17)
SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(SOURCE_EXE src/main.cpp)
set(SOURCE_GAME
src/Boss/Boss.cpp
*...*
src/Game/Game.cpp)
set(SOURCE_UI
src/UI/ScrollBar/ScrollBar.cpp)
add_library(UI SHARED ${SOURCE_UI})
add_library(Game SHARED ${SOURCE_GAME})
add_executable(main ${SOURCE_EXE})
target_link_libraries(main Game UI
sfml-graphics sfml-system sfml-windos sfml-audio)
Error:
CMakeFiles/UI.dir/src/UI/ScrollBar/ScrollBar.cpp.o:ScrollBar.cpp:(.text+0x6d): undefined reference to `_imp___ZN2sf14RectangleShapeC1ERKNS_7Vector2IfEE'
CMakeFiles/UI.dir/src/UI/ScrollBar/ScrollBar.cpp.o:ScrollBar.cpp:(.text+0x399): undefined reference to `_imp___ZN2sf12RenderStates7DefaultE.....
How can I fix it? Does I catch error because have too old C++ version? (Everything is successfully compiled for Linux, but I wanted to make cross-platform)
The error:
CMakeFiles/UI.dir/src/UI/ScrollBar/ScrollBar.cpp.o:ScrollBar.cpp:(.text+0x6d): undefined reference to `_imp___ZN2sf14RectangleShapeC1ERKNS_7Vector2IfEE'
indicates that the UI
library uses some SFML components. However, you only link the SFML libraries to the main
executable, so the library doesn't know where these SFML references are defined. So, you must link any relevant SFML libraries to the UI
target:
target_link_libraries(UI PUBLIC sfml-graphics sfml-system sfml-windos sfml-audio)
Use PUBLIC
here to propagate the SFML libraries to consumers of the UI
target, such as your main
executable. This removes the need to explicitly link them to main
. Here is your full CMake with these changes:
cmake_minimum_required(VERSION 3.0)
project(MLproject)
# As commented, consider moving these calls to your toolchain file.
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc")
SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++")
SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib")
SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_CXX_STANDARD 17)
set(SOURCE_EXE src/main.cpp)
set(SOURCE_GAME
src/Boss/Boss.cpp
*...*
src/Game/Game.cpp)
set(SOURCE_UI
src/UI/ScrollBar/ScrollBar.cpp)
add_library(UI SHARED ${SOURCE_UI})
# Link SFML libraries to UI.
target_link_libraries(UI PUBLIC sfml-graphics sfml-system sfml-windos sfml-audio)
add_library(Game SHARED ${SOURCE_GAME})
add_executable(main ${SOURCE_EXE})
# Link Game and UI to the executable, which propagates the SFML libraries from UI also.
target_link_libraries(main PRIVATE Game UI)
Note, many of the calls at the top of your CMake belong in a toolchain file (as commented), often for cross-compiling. I encourage you to read through the documentation to determine your need for it, and understand how to set it up.