Search code examples
c++qtcmakesfml

Integrating Qt with SFML using cmake for cross-platform development


I want to integrate the Qt framework with SFML, using cmake, hopefully in VS2022. Currently I have SFML already in my repository, and the cmake looks like this:

cmake_minimum_required(VERSION 3.16)
project(CMakeSFMLProject LANGUAGES CXX)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)

include(FetchContent)
FetchContent_Declare(SFML
    GIT_REPOSITORY https://github.com/SFML/SFML.git
    GIT_TAG 2.6.x)
FetchContent_MakeAvailable(SFML)

add_executable(CMakeSFMLProject src/main.cpp)
target_link_libraries(CMakeSFMLProject PRIVATE sfml-graphics)
target_compile_features(CMakeSFMLProject PRIVATE cxx_std_17)

if(WIN32)
    add_custom_command(
        TARGET CMakeSFMLProject
        COMMENT "Copy OpenAL DLL"
        PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${SFML_SOURCE_DIR}/extlibs/bin/$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,x86>/openal32.dll $<TARGET_FILE_DIR:CMakeSFMLProject>
        VERBATIM)
endif()

install(TARGETS CMakeSFMLProject)

So in to this, I want to somehow add the Qt library.

I also want to program in VS, for now, I just open the folder where this repository is, and VS works just fine with it. I have already installed Qt for VS, and it works, but I don't know how to integrate the two frameworks together, and also I am not sure how to use them after I put them together.

Currently after update I have the following:

cmake_minimum_required(VERSION 3.16)
project(PathFinder VERSION 1.0.0 LANGUAGES CXX)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)

find_package(Qt6 REQUIRED COMPONENTS Core)

include(FetchContent)
FetchContent_Declare(SFML
    GIT_REPOSITORY https://github.com/SFML/SFML.git
    GIT_TAG 2.6.x)
FetchContent_MakeAvailable(SFML)

add_executable(PathFinder src/main.cpp)
target_link_libraries(PathFinder PRIVATE
    Qt6::Core
    Qt6::Widgets
    sfml-graphics
)
target_compile_features(PathFinder PRIVATE cxx_std_17)

if(WIN32)
    add_custom_command(
        TARGET PathFinder
        COMMENT "Copy OpenAL DLL"
        PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${SFML_SOURCE_DIR}/extlibs/bin/$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,x86>/openal32.dll $<TARGET_FILE_DIR:CMakeSFMLProject>
        VERBATIM)
endif()

install(TARGETS PathFinder)

but for some reason I get

  By not providing "FindQt6.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "Qt6", but
  CMake did not find one.

  Could not find a package configuration file provided by "Qt6" with any of
  the following names:

    Qt6Config.cmake
    qt6-config.cmake

  Add the installation prefix of "Qt6" to CMAKE_PREFIX_PATH or set "Qt6_DIR"
  to a directory containing one of the above files.  If "Qt6" provides a
  separate development package or SDK, be sure it has been installed.   PathFinder  C:\Users\nhorv\Desktop\proba\CMakeLists.txt 7   

but I want to include Qt locally, so the user doesn't have to manually set the PATH variable. I want to install Qt as a dependency, and not installing it system-wide. Is this possible with the git repo of Qt?


Solution

  • This is my CMakeLists.txt file:

    cmake_minimum_required(VERSION 3.5)
    
    project(SFMLQt VERSION 0.1 LANGUAGES CXX)
    
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
    find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
    
    # Find SFML
    find_package(SFML 2.5 COMPONENTS graphics REQUIRED)
    
    set(PROJECT_SOURCES
            main.cpp
            mainwindow.cpp
            mainwindow.h
            mainwindow.ui
    )
    
    if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
        qt_add_executable(SFMLQt
            MANUAL_FINALIZATION
            ${PROJECT_SOURCES}
        )
    else()
        if(ANDROID)
            add_library(SFMLQt SHARED
                ${PROJECT_SOURCES}
            )
        else()
            add_executable(SFMLQt
                ${PROJECT_SOURCES}
            )
        endif()
    endif()
    
    target_link_libraries(SFMLQt PRIVATE Qt${QT_VERSION_MAJOR}::Widgets sfml-graphics)
    
    # Set target properties
    if(${QT_VERSION} VERSION_LESS 6.1.0)
        set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.SFMLQt)
    endif()
    set_target_properties(SFMLQt PROPERTIES
        ${BUNDLE_ID_OPTION}
        MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
        MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
        MACOSX_BUNDLE TRUE
        WIN32_EXECUTABLE TRUE
    )
    
    include(GNUInstallDirs)
    install(TARGETS SFMLQt
        BUNDLE DESTINATION .
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )
    
    if(QT_VERSION_MAJOR EQUAL 6)
        qt_finalize_executable(SFMLQt)
    endif()
    
    

    And this is minimal example:

    #include <SFML/Graphics.hpp>
    
    int  main()
    {
        sf::RenderWindow  window(sf::VideoMode(800, 600), "SFML Example");
    
        sf::CircleShape  shape(50.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;
    }
    
    

    Output:

    enter image description here

    But the point is that my OS is Ubuntu 22.04, for Windows, you need to do it the same way. Meaning something like this:

    cmake_minimum_required(VERSION 3.16)
    project(CMakeSFMLProject LANGUAGES CXX)
    
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
    
    # Find Qt
    find_package(Qt5 COMPONENTS Widgets REQUIRED)
    
    include(FetchContent)
    FetchContent_Declare(SFML
        GIT_REPOSITORY https://github.com/SFML/SFML.git
        GIT_TAG 2.6.x)
    FetchContent_MakeAvailable(SFML)
    
    add_executable(CMakeSFMLProject src/main.cpp)
    target_link_libraries(CMakeSFMLProject PRIVATE sfml-graphics Qt5::Widgets)
    target_compile_features(CMakeSFMLProject PRIVATE cxx_std_17)
    
    if(WIN32)
        add_custom_command(
            TARGET CMakeSFMLProject
            COMMENT "Copy OpenAL DLL"
            PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${SFML_SOURCE_DIR}/extlibs/bin/$<IF:$<EQUAL:${CMAKE_SIZEOF_VOID_P},8>,x64,x86>/openal32.dll $<TARGET_FILE_DIR:CMakeSFMLProject>
            VERBATIM)
    endif()
    
    install(TARGETS CMakeSFMLProject)