#!/usr/bin/cmake cmake_minimum_required (VERSION 3.15) # ------------------------------------------------------------------------------------------------- project( SFML VERSION 2.5.1 DESCRIPTION "Platform abstraction layer for graphical realtime applications" ) # ------------------------------------------------------------------------------------------------- # Contains compiler options, compiler tag for output directory, etc. include("../../BuildSystem/cmake/cplusplus.cmake") # The Unix build pipeline doesn't automatically include threading, so search for # the pthreads library in order to link against it later on. # https://en.wikipedia.org/wiki/Pthreads find_package(Threads REQUIRED) # OpenGL for rendering find_package(OpenGL REQUIRED) # On Linux systems, X11 is required to create windows and interact # with the GUI for event polling and message translation if(NOT WIN32) find_package(X11 REQUIRED) endif() # SFML uses STB (single header versions of common libraries such as libpng for # image loading amongst other things) if(NOT (TARGET STB)) add_subdirectory(${PROJECT_SOURCE_DIR}/../stb ${CMAKE_BINARY_DIR}/stb) endif() # SFML uses FreeType (popular library to decode font files and either extract # their curves or render them onto bitmaps) if(NOT (TARGET FreeType)) add_subdirectory(${PROJECT_SOURCE_DIR}/../freetype ${CMAKE_BINARY_DIR}/freetype) endif() # SFML uses OpenAL (a cross-platform spatial audio library that can use different # audio APIs like WASAPI on Windows and ALSA on Linux systems) if(NOT (TARGET OpenAL)) add_subdirectory(${PROJECT_SOURCE_DIR}/../openal-soft ${CMAKE_BINARY_DIR}/openal-soft) endif() # SFML suports streaming Vorbis-encoded audio through libVorbis if(NOT (TARGET Vorbis)) add_subdirectory(${PROJECT_SOURCE_DIR}/../vorbis ${CMAKE_BINARY_DIR}/vorbis) endif() # SFML lets you play back FLAC audio, mostly useful for short SFX if(NOT (TARGET FLAC)) add_subdirectory(${PROJECT_SOURCE_DIR}/../flac ${CMAKE_BINARY_DIR}/flac) endif() # Both Vorbis and FLAC can be stored in an OGG container if(NOT (TARGET OGG)) add_subdirectory(${PROJECT_SOURCE_DIR}/../ogg ${CMAKE_BINARY_DIR}/ogg) endif() # ------------------------------------------------------------------------------------------------- if(NOT EXISTS ${PROJECT_SOURCE_DIR}/downloads/2.5.1.tar.gz) message(STATUS "Downloading SFML sources") file( DOWNLOAD https://github.com/SFML/SFML/archive/refs/tags/2.5.1.tar.gz ${PROJECT_SOURCE_DIR}/downloads/2.5.1.tar.gz SHOW_PROGRESS EXPECTED_HASH SHA256=438c91a917cc8aa19e82c6f59f8714da353c488584a007d401efac8368e1c785 STATUS DOWNLOAD_STATUS ) if(NOT DOWNLOAD_STATUS EQUAL 0) file(REMOVE ${PROJECT_SOURCE_DIR}/downloads/2.5.1.tar.gz) message(FATAL_ERROR "Download failed, stopping build (error ${DOWNLOAD_STATUS})") endif() endif() # ------------------------------------------------------------------------------------------------- if(NOT EXISTS ${PROJECT_SOURCE_DIR}/build) message(STATUS "Extracting SFML sources") file( ARCHIVE_EXTRACT INPUT ${PROJECT_SOURCE_DIR}/downloads/2.5.1.tar.gz DESTINATION ${CMAKE_BINARY_DIR}/extract ) file( RENAME ${CMAKE_BINARY_DIR}/extract/SFML-2.5.1 ${PROJECT_SOURCE_DIR}/build ) endif() # Install fix required to compile EglContext on current Linux systems file( COPY "${PROJECT_SOURCE_DIR}/EglContext.hpp" DESTINATION "${PROJECT_SOURCE_DIR}/build/src/SFML/Window/" ) file( COPY "${PROJECT_SOURCE_DIR}/Config.hpp" DESTINATION "${PROJECT_SOURCE_DIR}/build/include/SFML/" ) # ------------------------------------------------------------------------------------------------- set( sourceFiles "build/src/SFML/Audio/ALCheck.cpp" "build/src/SFML/Audio/AlResource.cpp" "build/src/SFML/Audio/AudioDevice.cpp" "build/src/SFML/Audio/InputSoundFile.cpp" "build/src/SFML/Audio/Listener.cpp" "build/src/SFML/Audio/Music.cpp" "build/src/SFML/Audio/OutputSoundFile.cpp" "build/src/SFML/Audio/Sound.cpp" "build/src/SFML/Audio/SoundBuffer.cpp" "build/src/SFML/Audio/SoundBufferRecorder.cpp" "build/src/SFML/Audio/SoundFileFactory.cpp" "build/src/SFML/Audio/SoundFileReaderFlac.cpp" "build/src/SFML/Audio/SoundFileReaderOgg.cpp" "build/src/SFML/Audio/SoundFileReaderWav.cpp" "build/src/SFML/Audio/SoundFileWriterFlac.cpp" "build/src/SFML/Audio/SoundFileWriterOgg.cpp" "build/src/SFML/Audio/SoundFileWriterWav.cpp" "build/src/SFML/Audio/SoundRecorder.cpp" "build/src/SFML/Audio/SoundSource.cpp" "build/src/SFML/Audio/SoundStream.cpp" "build/src/SFML/Graphics/RectangleShape.cpp" "build/src/SFML/Graphics/BlendMode.cpp" "build/src/SFML/Graphics/CircleShape.cpp" "build/src/SFML/Graphics/Color.cpp" "build/src/SFML/Graphics/ConvexShape.cpp" "build/src/SFML/Graphics/Font.cpp" "build/src/SFML/Graphics/GLCheck.cpp" "build/src/SFML/Graphics/GLExtensions.cpp" "build/src/SFML/Graphics/GLLoader.cpp" "build/src/SFML/Graphics/Glsl.cpp" "build/src/SFML/Graphics/Image.cpp" "build/src/SFML/Graphics/ImageLoader.cpp" "build/src/SFML/Graphics/RenderStates.cpp" "build/src/SFML/Graphics/RenderTarget.cpp" "build/src/SFML/Graphics/RenderTexture.cpp" "build/src/SFML/Graphics/RenderTextureImpl.cpp" "build/src/SFML/Graphics/RenderTextureImplDefault.cpp" "build/src/SFML/Graphics/RenderTextureImplFBO.cpp" "build/src/SFML/Graphics/RenderWindow.cpp" "build/src/SFML/Graphics/Shader.cpp" "build/src/SFML/Graphics/Shape.cpp" "build/src/SFML/Graphics/Sprite.cpp" "build/src/SFML/Graphics/Text.cpp" "build/src/SFML/Graphics/Texture.cpp" "build/src/SFML/Graphics/TextureSaver.cpp" "build/src/SFML/Graphics/Transform.cpp" "build/src/SFML/Graphics/Transformable.cpp" "build/src/SFML/Graphics/Vertex.cpp" "build/src/SFML/Graphics/VertexArray.cpp" "build/src/SFML/Graphics/VertexBuffer.cpp" "build/src/SFML/Graphics/View.cpp" "build/src/SFML/Network/Ftp.cpp" "build/src/SFML/Network/Http.cpp" "build/src/SFML/Network/IpAddress.cpp" "build/src/SFML/Network/Packet.cpp" "build/src/SFML/Network/Socket.cpp" "build/src/SFML/Network/SocketSelector.cpp" "build/src/SFML/Network/TcpListener.cpp" "build/src/SFML/Network/TcpSocket.cpp" "build/src/SFML/Network/UdpSocket.cpp" "build/src/SFML/System/Clock.cpp" "build/src/SFML/System/Err.cpp" "build/src/SFML/System/FileInputStream.cpp" "build/src/SFML/System/Lock.cpp" "build/src/SFML/System/MemoryInputStream.cpp" "build/src/SFML/System/Mutex.cpp" "build/src/SFML/System/Sleep.cpp" "build/src/SFML/System/String.cpp" "build/src/SFML/System/Thread.cpp" "build/src/SFML/System/ThreadLocal.cpp" "build/src/SFML/System/Time.cpp" "build/src/SFML/Window/JoystickManager.cpp" "build/src/SFML/Window/Clipboard.cpp" "build/src/SFML/Window/Context.cpp" "build/src/SFML/Window/Cursor.cpp" "build/src/SFML/Window/GlContext.cpp" "build/src/SFML/Window/GlResource.cpp" "build/src/SFML/Window/Joystick.cpp" "build/src/SFML/Window/Keyboard.cpp" "build/src/SFML/Window/Mouse.cpp" "build/src/SFML/Window/Sensor.cpp" "build/src/SFML/Window/SensorManager.cpp" "build/src/SFML/Window/Touch.cpp" "build/src/SFML/Window/VideoMode.cpp" "build/src/SFML/Window/Window.cpp" "build/src/SFML/Window/WindowImpl.cpp" ) set( linuxSourceFiles "build/src/SFML/Network/Unix/SocketImpl.cpp" "build/src/SFML/System/Unix/ClockImpl.cpp" "build/src/SFML/System/Unix/MutexImpl.cpp" "build/src/SFML/System/Unix/SleepImpl.cpp" "build/src/SFML/System/Unix/ThreadImpl.cpp" "build/src/SFML/System/Unix/ThreadLocalImpl.cpp" "build/src/SFML/Window/Unix/ClipboardImpl.cpp" "build/src/SFML/Window/Unix/CursorImpl.cpp" "build/src/SFML/Window/Unix/Display.cpp" "build/src/SFML/Window/Unix/GlxContext.cpp" "build/src/SFML/Window/Unix/GlxExtensions.cpp" "build/src/SFML/Window/Unix/InputImpl.cpp" "build/src/SFML/Window/Unix/JoystickImpl.cpp" "build/src/SFML/Window/Unix/SensorImpl.cpp" "build/src/SFML/Window/Unix/VideoModeImpl.cpp" "build/src/SFML/Window/Unix/WindowImplX11.cpp" "build/src/SFML/Window/EGLCheck.cpp" "build/src/SFML/Window/EglContext.cpp" ) # "build/src/SFML/Main/MainWin32.cpp" set( windowsSourceFiles "build/src/SFML/Network/Win32/SocketImpl.cpp" "build/src/SFML/System/Win32/ClockImpl.cpp" "build/src/SFML/System/Win32/MutexImpl.cpp" "build/src/SFML/System/Win32/SleepImpl.cpp" "build/src/SFML/System/Win32/ThreadImpl.cpp" "build/src/SFML/System/Win32/ThreadLocalImpl.cpp" "build/src/SFML/Window/Win32/ClipboardImpl.cpp" "build/src/SFML/Window/Win32/CursorImpl.cpp" "build/src/SFML/Window/Win32/InputImpl.cpp" "build/src/SFML/Window/Win32/JoystickImpl.cpp" "build/src/SFML/Window/Win32/SensorImpl.cpp" "build/src/SFML/Window/Win32/VideoModeImpl.cpp" "build/src/SFML/Window/Win32/WglContext.cpp" "build/src/SFML/Window/Win32/WglExtensions.cpp" "build/src/SFML/Window/Win32/WindowImplWin32.cpp" ) file( GLOB_RECURSE headerFiles CONFIGURE_DEPENDS "build/include/*.h" ) # ------------------------------------------------------------------------------------------------- # Shared library that can be linked to other projects add_library(SFML SHARED) add_library(SFML::Dynamic ALIAS SFML) # Enable compiler warnings only if this library is compiled on its own. # If it's used as a sub-project, the including project's developers aren't # interested in seeing warnings from a project they're not maintaining. if(${CMAKE_PROJECT_NAME} STREQUAL "SFML") enable_target_compiler_warnings(SFML) else() disable_target_compiler_warnings(SFML) endif() target_compile_definitions( SFML PRIVATE SFML_AUDIO_EXPORTS PRIVATE SFML_GRAPHICS_EXPORTS PRIVATE SFML_NETWORK_EXPORTS PRIVATE SFML_SYSTEM_EXPORTS PRIVATE SFML_WINDOW_EXPORTS ) if(WIN32) target_compile_definitions( SFML PRIVATE UNICODE PRIVATE _UNICODE ) endif() # Add directory with public headers to include path target_include_directories( SFML PUBLIC "build/include/" PRIVATE "build/src/" ) # Add public headers and sources to compilation list # (headers, too, in case CMake is used to generate an IDE project) target_sources( SFML PUBLIC ${headerFiles} PRIVATE ${sourceFiles} ) if(WIN32) target_sources( SFML PRIVATE ${windowsSourceFiles} ) else() target_sources( SFML PRIVATE ${linuxSourceFiles} ) endif() # Link against PThreads and the embedded libraries SFML uses target_link_libraries( SFML PRIVATE Threads::Threads PRIVATE OpenAL::Shared PRIVATE OGG::Static PRIVATE Vorbis::Static PRIVATE FLAC::Static PRIVATE FreeType::Static PRIVATE STB::Static PRIVATE ${OPENGL_LIBRARY} ) if(WIN32) target_link_libraries( SFML PRIVATE wsock32 PRIVATE ws2_32 PRIVATE winmm ) else() target_link_libraries( SFML PRIVATE ${X11_LIBRARIES} PRIVATE ${X11_Xrandr_LIB} PRIVATE ${OPENGL_egl_LIBRARY} PRIVATE udev ) endif() # Make sure the build fails if the shared library is missing any symbols # (otherwise this would only be detected when building the final executable) if(NOT WIN32) # Supposedly, there is a portable way to specify these but since it's # CMake, the documentation doesn't give an example and is wrong as well: # https://cmake.org/cmake/help/latest/command/add_link_options.html message(STATUS "Using symbolic link to catch unresolved symbols") # Detect unresolved symbols in shared object set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs") # Prevent replacement on shared object syms set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Bsymbolic") endif() # We want the shared library to be named libsfml.o or sfml.dll set_target_properties(SFML PROPERTIES OUTPUT_NAME "sfml") # ------------------------------------------------------------------------------------------------- # Install the shared library into a subdirectory of this CMakeLists.txt file # under ./bin/linux-gcc9.3-amd64-debug/ (the second-level directory is called # "compiler tag" and dynamically formed -- it ensures that when linking # a pre-compiled shared library, the correct library is used). install( TARGETS SFML ARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/bin/${NUCLEX_COMPILER_TAG} LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/bin/${NUCLEX_COMPILER_TAG} RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/bin/${NUCLEX_COMPILER_TAG} ) # Do the same for OpenAL-Soft. Since we depend on this library and have set # the rpath accordingly, it only needs to be in the same directory. install( TARGETS OpenAL ARCHIVE DESTINATION ${PROJECT_SOURCE_DIR}/bin/${NUCLEX_COMPILER_TAG} LIBRARY DESTINATION ${PROJECT_SOURCE_DIR}/bin/${NUCLEX_COMPILER_TAG} RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/bin/${NUCLEX_COMPILER_TAG} ) # Install .pdb files on Windows platforms. # # CMake forgets installing .pdb files for debug builds. These are needed by # Microsoft compilers when debugging to associate machine code locations to # source files and line numbers. install_debug_symbols(SFML) install_debug_symbols(OpenAL) # ------------------------------------------------------------------------------------------------- file( WRITE "${PROJECT_SOURCE_DIR}/SFMLConfig.cmake" "#!/usr/bin/cmake # Configuration to include SFML in a CMake-based project. If you want to # reference SFML as an externally compiled static library, do this: # # set(SFML_DIR \"../sfml\") # find_package(SFML REQUIRED CONFIG) # # target_link_libraries( # MyAwesomeProject # PRIVATE SFML::Dynamic # ) # # Alternatively, if you want to build SFML together with your project, # use the normal CMakeLists.txt with CMake's add_subdirectory() command: # # add_subdirectory( # \"\${PROJECT_SOURCE_DIR}/../sfml\" # \"\${CMAKE_BINARY_DIR}/sfml\" # ) # # target_link_libraries( # MyAwesomeProject # PRIVATE SFML # ) # # ------------------------------------------------------------------------------------------------- if(NOT DEFINED NUCLEX_COMPILER_TAG) message( FATAL_ERROR \"NUCLEX_COMPILER_TAG not defined! Include cplusplus.cmake before importing this package \\ in order to generate a tag identifying the platform/compiler/architecture/variant!\" ) endif() # ------------------------------------------------------------------------------------------------- if(NOT EXISTS \"\${CMAKE_CURRENT_LIST_DIR}/bin/\${NUCLEX_COMPILER_TAG}\") # TODO: Warn and link release build when compiling in debug mode # TODO: Warn and link build for older compiler version if found message( FATAL_ERROR \"Directory '\${CMAKE_CURRENT_LIST_DIR}/bin/\${NUCLEX_COMPILER_TAG}' not found. \\ Please either build and install this project before importing it via \\ find_package() or use this project's main CMakeFiles.txt via add_subdirectory()!\" ) endif() # ------------------------------------------------------------------------------------------------- add_library(SFML::Dynamic SHARED IMPORTED) # This may cause warnings on recent GCC versions (10.0.0+?) with LTO because GCC detects # that the headers used during build (residing in build/) are not the same used when # linking the library (copies resising in Include/). # # CMake doesn't run the install step during build, so the only way to get the headers # in place before building would be by copying them rather than installing them. set_target_properties( SFML::Dynamic PROPERTIES INTERFACE_INCLUDE_DIRECTORIES \"\${CMAKE_CURRENT_LIST_DIR}/Include\" IMPORTED_LINK_INTERFACE_LANGUAGES \"C\" ) if(WIN32) set_target_properties( SFML::Dynamic PROPERTIES IMPORTED_LOCATION \"\${CMAKE_CURRENT_LIST_DIR}/bin/\${NUCLEX_COMPILER_TAG}/SFML.lib\" ) else() set_target_properties( SFML::Dynamic PROPERTIES IMPORTED_LOCATION \"\${CMAKE_CURRENT_LIST_DIR}/bin/\${NUCLEX_COMPILER_TAG}/libSFML.so\" ) endif() message(STATUS \"Imported SFML targets with binaries in '\${CMAKE_CURRENT_LIST_DIR}'\")" ) # -------------------------------------------------------------------------------------------------