I'm basically trying to make an SFML project in CLion which uses CMake.
I first downloaded SFML 2.2 which already had the .dylib files built. It said to install them in usr/local/lib and usr/local/include, but they didn't exist, so I created them and then put the files there.
I then opened up CLion, created a subdirectoy cmake_modules, placed the FindSFML.cmake file inside, and in the root project directory placed these files:
main.cpp
#include <SFML/Graphics.hpp>
int main()
{
sf::err() << "Hello, World!" << std::endl;
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.2)
project(HelloWorld)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(HelloWorld ${SOURCE_FILES})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
find_package(SFML COMPONENTS graphics window system REQUIRED)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(HelloWorld ${SFML_Libraries})
The problem is that when I try to build the project, I get the following error:
Undefined symbols for architecture x86_64:
"sf::err()", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've tried searching for a solution, but none of them seem to be working. Did I put the files in the wrong place, or did I forget some import CMake setting? I know that setting SFML up with Xcode would be easier, but I'd prefer to use CLion if at all possible.
Ok, so I made an entirely new project, ran xcode-select --install on my terminal to make /usr/local/ a directory that gets searched by the compiler, downloaded SFML 2.3 instead of 2.2, decided to use the FindSFML.cmake file shipped with SFML, and made my CmakeLists.txt file look like so:
cmake_minimum_required(VERSION 3.2)
project(SFMLTest)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(SFMLTest ${SOURCE_FILES})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "~/SFML-2.3/cmake/Modules/")
find_package(SFML REQUIRED graphics window system)
if (SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(SFMLTest ${SFML_LIBRARIES})
endif(SFML_FOUND)
This compiled and ran the following code in CLion:
#include <iostream>
#include <SFML/Graphics.hpp>
using namespace std;
int main()
{
sf::RenderWindow window(sf::VideoMode(640, 480), "Window");
while (window.isOpen())
{
sf::Event e;
while (window.pollEvent(e))
{
if (e.type == sf::Event::Closed)
{
window.close();
}
}
window.clear();
window.display();
}
return 0;
}
I don't know what exactly fixed everything, but I'm just glad it did. Hopefully this helps anyone else who's in a similar jam.
For SFML 2.5 and greater a more modern approach has been taken and setting up cmake is easier.
Example CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
project(SFMLTest)
find_package(SFML 2.5 COMPONENTS graphics audio REQUIRED)
add_executable(SFMLTest main.cpp)
target_link_libraries(SFMLTest sfml-graphics sfml-audio)
Note :
Its no longer needed to setup FindSFML.cmake or SFML_ROOT etc.
SFML_LIBRARIES, SFML_DEPENDENCIES and SFML_INCLUDE_DIR don't exist
anymore
More info https://en.sfml-dev.org/forums/index.php?topic=24070.0
For others who downloaded SFML via brew, I managed to fix this by adding this to my CMakeLists.txt
set(SFML_ROOT /usr/local/lib)
Related
I've implemented the GLFW basic example.
The GLFW header file is reported as not being found and such the CLion IDE is reporting and error and not providing intellisense however the project correctly compiles and runs.
I've added the GLFW library as per the guidance in their documentation (See CMakeLists.txt).
The project is being built and run remotely on Ubuntu 20.04.
main.cpp
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
...
}
CMakeLists.txt
project(untitled1)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES main.cpp)
find_package(glfw3 3.3 REQUIRED)
add_executable(untitled1 ${SOURCE_FILES})
target_link_libraries(untitled1 glfw)
For anyone encountering this issue call Tools | Resync with Remote Hosts -
I downloaded SFML using vcpkg, and I wanted to use SFML in CLion. So, in the CMake options I put:
-DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake
for using vcpkg modules.
My CMakeList.txt is:
cmake_minimum_required(VERSION 3.7)
project(Test)
set(CMAKE_CXX_STANDARD 20)
FIND_PACKAGE(SFML REQUIRED system window graphics network audio)
INCLUDE_DIRECTORIES(${SFML_INCLUDE_DIR})
add_executable(Test main.cpp)
TARGET_LINK_LIBRARIES(Test ${SFML_LIBRARIES} ${SFML_DEPENDENC})
CMake shows:
Found SFML 2.5.1 in C:/vcpkg/installed/x86-windows/share/sfml
But CLion tells me that SFML/Audio.hpp was not found.
Is there something wrong with my CMakeList?
How can I configure SFML in CLion?
I want to run the following simple C++ SFML application in CLion but when I try to do it, I always get the error message Test2.exe has stopped working.
main.cpp
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::CircleShape shape(100.f);
shape.setFillColor(sf::Color::Green);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(shape);
window.display();
}
return 0;
}
This might be a problem with CMake, but I don't get any error message from CLion, so I think SFML is found properly.
CMakeLists.txt
cmake_minimum_required(VERSION 3.9)
project(Test2)
set(CMAKE_CXX_STANDARD 17)
add_executable(Test2 main.cpp)
set(SFML_ROOT "C:/Program Files/SFML-2.4.2")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
find_package(SFML 2 REQUIRED graphics network audio window system)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
endif()
My SFML is located in C:/Program Files/SFML-2.4.2, and I use the latest version (2.4.2) for MinGW. I have the following MinGW version:
MingGW configuration. My operating system is Windows 8.1 Enterprise.
Separately both CLion and SFML (with Code::Blocks) can work perfectly.
Is there anything I forgot to add to CMakeLists.txt or should I modify some settings in CLion to get SFML to work?
After modifying the CMakeLists.txt in the following way, the created .exe worked without any errors.
cmake_minimum_required(VERSION 3.9)
project(Test2)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc")
set(SFML_STATIC_LIBRARIES TRUE)
add_executable(Test2 main.cpp)
set(SFML_ROOT "C:/Program Files/SFML-2.4.2")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
find_package(SFML 2 REQUIRED graphics network audio window system)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
endif()
I'm looking for the simplest way to compile a c++ program using SDL2 and SDL_image with cmake.
Here is my best attempt, after hours of searching:
CMakeLists.txt
project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(SOURCES
shooter.cpp
classes.cpp
utils.cpp
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} ${SOURCES})
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2_image REQUIRED sdl2_image)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARY})
I get these errors:
In function `loadTexture(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SDL_Renderer*)':
undefined reference to `IMG_LoadTexture'
collect2: ld returned 1 exit status
Here is the function call:
#include "SDL.h"
#include "SDL_image.h"
SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){
SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
texture != nullptr or die("LoadTexture");
return texture;
}
I think that the following will work, as it finds the libraries on my ubuntu system and the example function you provided can link:
project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} src/test.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})
If cmake is executed with --debug-output it outputs:
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26")
Called from: [2] /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake
[1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'sdl2'
Called from: [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'SDL2_image>=2.0.0'
Called from: [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
This made me check the contents of
/usr/lib/x86_64-linux-gnu/pkgconfig/sdl2.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/SDL2_image.pc
I noticed that SDL2_image.pc contains
Name: SDL2_image
which I assumed should match the third parameter to PKG_SEARCH_MODULE for this library.
There are two blog posts about this here:
Using SDL2 with CMake
Using SDL2_image with CMake
Basically you need a FindSDL2.cmake and FindSDL2_image.cmake module. They can be based of the ones that work for SDL 1.2 which are included in CMake already. Using these Find modules will also work on Windows.
If you are on Linux and only need SDL2 you don't even need the FindSDL2.cmake as the following already works:
cmake_minimum_required(VERSION 3.7)
project(SDL2Test)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test ${SDL2_LIBRARIES})
I was having trouble with these answers, I think cmake changed the way to import targets. Following #trenki blog post I needed to change my CMakeLists.txt to:
project(SDL2Test)
find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2)
add_executable(SDL2Test main.cpp)
target_link_libraries(SDL2Test SDL2::SDL2)
Currently this works out of the box on Arch Linux.
I introduced a modern and portable approach for linking to the SDL2, SDL2_image. These SDL2 CMake modules let you build an SDL2 & SDL2_image project as follows :
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main SDL2::Image)
You should just clone the repo in your project:
git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2
Note: If CMake didn't find the SDL2/SDL2_image libraries (in Windows), we can specify the CMake options SDL2_PATH and SDL2_IMAGE_PATH as follows:
cmake .. -DSDL2_PATH="/path/to/sdl2" -DSDL2_IMAGE_PATH="/path/to/sdl2-image"
It supports also other related libraries : SDL2_ttf, SDL2_net, SDL2_mixer and SDL2_gfx. For more details, please read the README.md file.
You can find a list of examples/samples and projects that uses these modules here : https://github.com/aminosbh/sdl-samples-and-projects
Since 2.6 version, SDL2_image installation is shipped with CMake config script SDL2_imageConfig.cmake/SDL2_image-config.cmake.
So find_package(SDL2_image) works without any additional FindSDL2_image.cmake module, and creates IMPORTED target SDL2_image::SDL2_image:
find_package(SDL2_image REQUIRED)
target_link_libraries(<executable-target> SDL2_image::SDL2_image)
Note, that variables like SDL2_IMAGE_LIBRARIES or SDL2_IMAGE_INCLUDE_DIRS are NOT set in this case, so using them is meaningless.
The following commands works fine for me:
set(SDL_INCLUDE_DIR "/usr/include/SDL2")
set(SDL_LIBRARY "SDL2")
include(FindSDL)
if(SDL_FOUND)
message(STATUS "SDL FOUND")
endif()
I'm looking for the simplest way to compile a c++ program using SDL2 and SDL_image with cmake.
Here is my best attempt, after hours of searching:
CMakeLists.txt
project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(SOURCES
shooter.cpp
classes.cpp
utils.cpp
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} ${SOURCES})
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2_image REQUIRED sdl2_image)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARY})
I get these errors:
In function `loadTexture(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SDL_Renderer*)':
undefined reference to `IMG_LoadTexture'
collect2: ld returned 1 exit status
Here is the function call:
#include "SDL.h"
#include "SDL_image.h"
SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){
SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
texture != nullptr or die("LoadTexture");
return texture;
}
I think that the following will work, as it finds the libraries on my ubuntu system and the example function you provided can link:
project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} src/test.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})
If cmake is executed with --debug-output it outputs:
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26")
Called from: [2] /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake
[1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'sdl2'
Called from: [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'SDL2_image>=2.0.0'
Called from: [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
This made me check the contents of
/usr/lib/x86_64-linux-gnu/pkgconfig/sdl2.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/SDL2_image.pc
I noticed that SDL2_image.pc contains
Name: SDL2_image
which I assumed should match the third parameter to PKG_SEARCH_MODULE for this library.
There are two blog posts about this here:
Using SDL2 with CMake
Using SDL2_image with CMake
Basically you need a FindSDL2.cmake and FindSDL2_image.cmake module. They can be based of the ones that work for SDL 1.2 which are included in CMake already. Using these Find modules will also work on Windows.
If you are on Linux and only need SDL2 you don't even need the FindSDL2.cmake as the following already works:
cmake_minimum_required(VERSION 3.7)
project(SDL2Test)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test ${SDL2_LIBRARIES})
I was having trouble with these answers, I think cmake changed the way to import targets. Following #trenki blog post I needed to change my CMakeLists.txt to:
project(SDL2Test)
find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2)
add_executable(SDL2Test main.cpp)
target_link_libraries(SDL2Test SDL2::SDL2)
Currently this works out of the box on Arch Linux.
I introduced a modern and portable approach for linking to the SDL2, SDL2_image. These SDL2 CMake modules let you build an SDL2 & SDL2_image project as follows :
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main SDL2::Image)
You should just clone the repo in your project:
git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2
Note: If CMake didn't find the SDL2/SDL2_image libraries (in Windows), we can specify the CMake options SDL2_PATH and SDL2_IMAGE_PATH as follows:
cmake .. -DSDL2_PATH="/path/to/sdl2" -DSDL2_IMAGE_PATH="/path/to/sdl2-image"
It supports also other related libraries : SDL2_ttf, SDL2_net, SDL2_mixer and SDL2_gfx. For more details, please read the README.md file.
You can find a list of examples/samples and projects that uses these modules here : https://github.com/aminosbh/sdl-samples-and-projects
Since 2.6 version, SDL2_image installation is shipped with CMake config script SDL2_imageConfig.cmake/SDL2_image-config.cmake.
So find_package(SDL2_image) works without any additional FindSDL2_image.cmake module, and creates IMPORTED target SDL2_image::SDL2_image:
find_package(SDL2_image REQUIRED)
target_link_libraries(<executable-target> SDL2_image::SDL2_image)
Note, that variables like SDL2_IMAGE_LIBRARIES or SDL2_IMAGE_INCLUDE_DIRS are NOT set in this case, so using them is meaningless.
The following commands works fine for me:
set(SDL_INCLUDE_DIR "/usr/include/SDL2")
set(SDL_LIBRARY "SDL2")
include(FindSDL)
if(SDL_FOUND)
message(STATUS "SDL FOUND")
endif()