Commit 823782df authored by Felix Morgner's avatar Felix Morgner
Browse files

week10: remove old code and slides

parent 159bc0f6
# Exercise 10 - Threading and Asynchronous IO
In this exercise...
* ... you get familiar with the thread API of C++
* ... you implement basic asynchronous communication using ASIO
* ... you realize the communication logic in an existing application
# 1. Basic Threading
***Note:*** On Linux you might need to add the `pthread` library to link the projects correctly: `Project Properties -> C++ General -> Paths & Symbols -> Libraries -> Add -> "pthread"`
## a) Thread IDs
Create a simple application that starts three threads:
* One thread shall be created with a functor
* One thread shall be created with a free function
* One thread shall be created with a lambda
Each thread prints its ID (`std::this_thread::get_id()`) on `std::cout`.
Since it is discouraged to use `std::cout` directly in your functor, function and lambda, each should have a `std::ostream & out` parameter. If you want to pass `std::cout` through the `std::thread` constructor, you have to wrap the argument in an `std::ref` on the call-site.
## b) Measure Speedup
In the template you have an implementation of a program that counts the prime numbers in a given range (`countPrimes` function). Parallelize the computation using multiple threads in `countPrimesParallel`.
***Note:*** Be aware, that each thread must only access his entry of the `results` array and that the `main`thread must only access those results after the threads have been joined.
What speedup can you achieve?
# 2. Standalone Asynchronous IO (Chat Client)
We have prepared projects using ASIO to implement a chat client-server application. It is the example ASIO chat client-server application from [here](https://think-async.com/Asio/asio-1.12.2/doc/asio/examples/cpp11_examples.html)
Preparation:
* You need to download the ASIO library from [here](https://think-async.com/Asio/). You won't need to compile and install the library, but you need to add the include path of the extracted location to your project: `<asio-directory>/include`
***Note:*** If you are on Windows you need library dependencies that depend on the Windows platform! The follwing libraries are required for this exercise: `ws2_32` and `wsock32`.
Get the project compiled. Besides the library dependencies you need to be aware, that there are two `main` functions in the project. We have created two build configurations: `Debug (Server)` and `Debug (Client)` which each have the other source file excluded.
It is easier to follow the message flow if you don't run all executables from the IDE. You can run them in separate terminal windows. The server will not feature any output at all. The client's messages will be distributed among all connected clients.
If you wan't the details about the source code, you can browse the API reference of [ASIO Documentation](https://think-async.com/asio/asio-1.12.2/doc/).
# 3. Connect Four Game with SFML
Your task is to finish the implementation task for the Connect Four Game's `ServerPeer`, see `peer/ServerPeer.h` for detailed instructions.
The idea is that both a client and a server each run their game instance and communicate asynchronously using the ASIO Library. The UI is created using the SFML library (see [SFML](https://www.sfml-dev.org/)) and runs in the main thread, while the socket communication is done in a separate thread.
When running the game one side will wait for the other to make a move and update their state accordingly and then do their turn while the other waits.
The server waits and accepts incoming clients on the provided port and the hosts address.
The client to connect to the provided endpoint (server-address and port) and starts the game on success.
## Building the project
Cevelop: Use the appropiate build configuration for you platform `Debug (Linux)` and `Debug (Windows)` that will link the correct libraries needed for the game to work.
***Note:*** Make sure that you have also opened (and on Linux built) the `SFML` project (found under `week10/exercise_libs/SFML/`) to allow the linking to succeed.
The following libraries are needed and must be present for the linking to succeed.
* Windows: `opengl32`, `winmm`, `gdi32`, `freetype`, `ws2_32`, `wsock32` and `z`
* Linux: `freetype`, `X11`, `GL`, `udev` and `Xrandr`.
Further the different SFML libraries are needed for both platforms, see the SFML Libraries section. ASIO (no boost required) is used as a header only library and already included, see the ASIO Library section.
## ASIO Library
The asio library is already part of the template inside the `include` folder.
## SFML Libraries
The prepared project contains prebuild SFML libraries for Windows. Those SFML libraries have been build with MinGW from [STL](https://nuwen.net/mingw.html), i.e. GCC version 8.2. This distribution contains all the required dependencies. On other platforms get the SFML libraries via your package manager.
Alternatively, you can build the libraries on your own: See the included script file (Linux). It is also possible to get the sources for [SFML](https://www.sfml-dev.org/) and build the libraries yourself. It requires `cmake` and `make`. This should work on all plattforms. However, we suggest you build the static debug versions of the libraries.
## How to play
To play the game the executable can be run in different modes depending ont the passed arguments.
* Zero arguments: A local game is started. You can play both sides in the same window locally.
* One arguments (port): This starts the game in the server mode listening on the specified port.
* Two arguments (server-address port): This starts the game in the client mode, which will attempt to connect to the given ip and port.
In either client or server mode the game waits for the other side to join it. You can also run both locally by specifing the same port and using `localhost` or `127.0.0.1` as the server address.
***Note:*** You can use different `Run Configurations` to launch the different modes directly (see `Run Configurations...` -> `Arguments`).
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SFML</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
This diff is collapsed.
# Contribution Guidelines
You would like to see a feature implemented or a bug fixed in SFML? Great! Contributions to SFML are highly appreciated, be it in the form of general ideas, concrete suggestions or code patches.
[A few guiding rules have been set up on the SFML website](https://www.sfml-dev.org/contribute.php) that you should be aware of before opening an Issue or Pull Request. They will help you focus on the important stuff and prevent you from losing (y)our time with requests that are out of SFML's scope, known issues, and so on.
Those rules cover the general scope defined for this project, a coding style, and a precise procedure to report bugs or suggest new features.
#!/usr/bin/env bash
mkdir -p build && cd build && cmake .. -DCMAKE_BUILD_TYPE="Debug" -DBUILD_SHARED_LIBS=False -DSFML_USE_STATIC_STD_LIBS=True && cmake --build .
This diff is collapsed.
# detect the OS
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(SFML_OS_WINDOWS 1)
# don't use the OpenGL ES implementation on Windows
set(OPENGL_ES 0)
# detect the architecture (note: this test won't work for cross-compilation)
include(CheckTypeSize)
check_type_size(void* SIZEOF_VOID_PTR)
if(${SIZEOF_VOID_PTR} STREQUAL "4")
set(ARCH_32BITS 1)
elseif(${SIZEOF_VOID_PTR} STREQUAL "8")
set(ARCH_64BITS 1)
else()
message(FATAL_ERROR "Unsupported architecture")
return()
endif()
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(SFML_OS_UNIX 1)
if(ANDROID)
set(SFML_OS_ANDROID 1)
# use the OpenGL ES implementation on Android
set(OPENGL_ES 1)
else()
set(SFML_OS_LINUX 1)
# don't use the OpenGL ES implementation on Linux
set(OPENGL_ES 0)
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "^k?FreeBSD$")
set(SFML_OS_FREEBSD 1)
# don't use the OpenGL ES implementation on FreeBSD
set(OPENGL_ES 0)
elseif(CMAKE_SYSTEM_NAME MATCHES "^OpenBSD$")
set(SFML_OS_OPENBSD 1)
# don't use the OpenGL ES implementation on OpenBSD
set(OPENGL_ES 0)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
if(IOS)
set(SFML_OS_IOS 1)
# use the OpenGL ES implementation on iOS
set(OPENGL_ES 1)
else()
set(SFML_OS_MACOSX 1)
# don't use the OpenGL ES implementation on Mac OS X
set(OPENGL_ES 0)
# detect OS X version. (use '/usr/bin/sw_vers -productVersion' to extract V from '10.V.x'.)
EXEC_PROGRAM(/usr/bin/sw_vers ARGS -productVersion OUTPUT_VARIABLE MACOSX_VERSION_RAW)
STRING(REGEX REPLACE "10\\.([0-9]+).*" "\\1" MACOSX_VERSION "${MACOSX_VERSION_RAW}")
if(${MACOSX_VERSION} LESS 7)
message(FATAL_ERROR "Unsupported version of OS X: ${MACOSX_VERSION_RAW}")
return()
endif()
endif()
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android")
set(SFML_OS_ANDROID 1)
# use the OpenGL ES implementation on Android
set(OPENGL_ES 1)
# comparing CMAKE_SYSTEM_NAME with "CYGWIN" generates a false warning depending on the CMake version
# let's avoid it so the actual error is more visible
elseif(${CYGWIN})
message(FATAL_ERROR "Unfortunately SFML doesn't support Cygwin's 'hybrid' status between both Windows and Linux derivatives.\nIf you insist on using the GCC, please use a standalone build of MinGW without the Cygwin environment instead.")
else()
message(FATAL_ERROR "Unsupported operating system or environment")
return()
endif()
# set pkgconfig install directory
# this could be e.g. macports on mac or msys2 on windows etc.
set(SFML_PKGCONFIG_DIR "/lib${LIB_SUFFIX}/pkgconfig")
if(SFML_OS_FREEBSD OR SFML_OS_OPENBSD)
set(SFML_PKGCONFIG_DIR "/libdata/pkgconfig")
endif()
# detect the compiler and its version
# Note: on some platforms (OS X), CMAKE_COMPILER_IS_GNUCXX is true
# even when CLANG is used, therefore the Clang test is done first
if(CMAKE_CXX_COMPILER MATCHES "clang[+][+]" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# CMAKE_CXX_COMPILER_ID is an internal CMake variable subject to change,
# but there is no other way to detect CLang at the moment
set(SFML_COMPILER_CLANG 1)
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "--version" OUTPUT_VARIABLE CLANG_VERSION_OUTPUT)
string(REGEX REPLACE ".*clang version ([0-9]+\\.[0-9]+).*" "\\1" SFML_CLANG_VERSION "${CLANG_VERSION_OUTPUT}")
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(SFML_COMPILER_GCC 1)
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "-dumpversion" OUTPUT_VARIABLE GCC_VERSION_OUTPUT)
string(REGEX REPLACE "([0-9]+\\.[0-9]+).*" "\\1" SFML_GCC_VERSION "${GCC_VERSION_OUTPUT}")
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "--version" OUTPUT_VARIABLE GCC_COMPILER_VERSION)
string(REGEX MATCHALL ".*(tdm[64]*-[1-9]).*" SFML_COMPILER_GCC_TDM "${GCC_COMPILER_VERSION}")
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "-dumpmachine" OUTPUT_VARIABLE GCC_MACHINE)
string(STRIP "${GCC_MACHINE}" GCC_MACHINE)
if(GCC_MACHINE MATCHES ".*w64.*")
set(SFML_COMPILER_GCC_W64 1)
endif()
elseif(MSVC)
set(SFML_COMPILER_MSVC 1)
if(MSVC_VERSION EQUAL 1400)
set(SFML_MSVC_VERSION 8)
elseif(MSVC_VERSION EQUAL 1500)
set(SFML_MSVC_VERSION 9)
elseif(MSVC_VERSION EQUAL 1600)
set(SFML_MSVC_VERSION 10)
elseif(MSVC_VERSION EQUAL 1700)
set(SFML_MSVC_VERSION 11)
elseif(MSVC_VERSION EQUAL 1800)
set(SFML_MSVC_VERSION 12)
elseif(MSVC_VERSION EQUAL 1900)
set(SFML_MSVC_VERSION 14)
endif()
else()
message(FATAL_ERROR "Unsupported compiler")
return()
endif()
include(CMakeParseArguments)
# This little macro lets you set any Xcode specific property
macro (sfml_set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
endmacro ()
# set the appropriate standard library on each platform for the given target
# example: sfml_set_stdlib(sfml-system)
function(sfml_set_stdlib target)
# for gcc >= 4.0 on Windows, apply the SFML_USE_STATIC_STD_LIBS option if it is enabled
if(SFML_OS_WINDOWS AND SFML_COMPILER_GCC AND NOT SFML_GCC_VERSION VERSION_LESS "4")
if(SFML_USE_STATIC_STD_LIBS AND NOT SFML_COMPILER_GCC_TDM)
target_link_libraries(${target} PRIVATE "-static-libgcc" "-static-libstdc++")
elseif(NOT SFML_USE_STATIC_STD_LIBS AND SFML_COMPILER_GCC_TDM)
target_link_libraries(${target} PRIVATE "-shared-libgcc" "-shared-libstdc++")
endif()
endif()
if (SFML_OS_MACOSX)
if (${CMAKE_GENERATOR} MATCHES "Xcode")
sfml_set_xcode_property(${target} CLANG_CXX_LIBRARY "libc++")
else()
target_compile_options(${target} PRIVATE "-stdlib=libc++")
target_link_libraries(${target} PRIVATE "-stdlib=libc++")
endif()
endif()
endfunction()
# add a new target which is a SFML library
# example: sfml_add_library(sfml-graphics
# SOURCES sprite.cpp image.cpp ...
# [STATIC]) # Always create a static library and ignore BUILD_SHARED_LIBS
macro(sfml_add_library target)
# parse the arguments
cmake_parse_arguments(THIS "STATIC" "" "SOURCES" ${ARGN})
if (NOT "${THIS_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Extra unparsed arguments when calling sfml_add_library: ${THIS_UNPARSED_ARGUMENTS}")
endif()
# create the target
if (THIS_STATIC)
add_library(${target} STATIC ${THIS_SOURCES})
else()
add_library(${target} ${THIS_SOURCES})
endif()
# define the export symbol of the module
string(REPLACE "-" "_" NAME_UPPER "${target}")
string(TOUPPER "${NAME_UPPER}" NAME_UPPER)
set_target_properties(${target} PROPERTIES DEFINE_SYMBOL ${NAME_UPPER}_EXPORTS)
# adjust the output file prefix/suffix to match our conventions
if(BUILD_SHARED_LIBS AND NOT THIS_STATIC)
if(SFML_OS_WINDOWS)
# include the major version number in Windows shared library names (but not import library names)
set_target_properties(${target} PROPERTIES DEBUG_POSTFIX -d)
set_target_properties(${target} PROPERTIES SUFFIX "-${VERSION_MAJOR}${CMAKE_SHARED_LIBRARY_SUFFIX}")
else()
set_target_properties(${target} PROPERTIES DEBUG_POSTFIX -d)
endif()
if (SFML_OS_WINDOWS AND SFML_COMPILER_GCC)
# on Windows/gcc get rid of "lib" prefix for shared libraries,
# and transform the ".dll.a" suffix into ".a" for import libraries
set_target_properties(${target} PROPERTIES PREFIX "")
set_target_properties(${target} PROPERTIES IMPORT_SUFFIX ".a")
endif()
else()
set_target_properties(${target} PROPERTIES DEBUG_POSTFIX -s-d)
set_target_properties(${target} PROPERTIES RELEASE_POSTFIX -s)
set_target_properties(${target} PROPERTIES MINSIZEREL_POSTFIX -s)
set_target_properties(${target} PROPERTIES RELWITHDEBINFO_POSTFIX -s)
endif()
# set the version and soversion of the target (for compatible systems -- mostly Linuxes)
# except for Android which strips soversion suffixes
if(NOT SFML_OS_ANDROID)
set_target_properties(${target} PROPERTIES SOVERSION ${VERSION_MAJOR}.${VERSION_MINOR})
set_target_properties(${target} PROPERTIES VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
endif()
# set the target's folder (for IDEs that support it, e.g. Visual Studio)
set_target_properties(${target} PROPERTIES FOLDER "SFML")
# set the target flags to use the appropriate C++ standard library
sfml_set_stdlib(${target})
# For Visual Studio on Windows, export debug symbols (PDB files) to lib directory
if(SFML_GENERATE_PDB)
# PDB files are only generated in Debug and RelWithDebInfo configurations, find out which one
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
set(SFML_PDB_POSTFIX "-d")
else()
set(SFML_PDB_POSTFIX "")
endif()
if(BUILD_SHARED_LIBS AND NOT THIS_STATIC)
# DLLs export debug symbols in the linker PDB (the compiler PDB is an intermediate file)
set_target_properties(${target} PROPERTIES
PDB_NAME "${target}${SFML_PDB_POSTFIX}"
PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
else()
# Static libraries have no linker PDBs, thus the compiler PDBs are relevant
set_target_properties(${target} PROPERTIES
COMPILE_PDB_NAME "${target}-s${SFML_PDB_POSTFIX}"
COMPILE_PDB_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
endif()
endif()
# if using gcc >= 4.0 or clang >= 3.0 on a non-Windows platform, we must hide public symbols by default
# (exported ones are explicitly marked)
if(NOT SFML_OS_WINDOWS AND ((SFML_COMPILER_GCC AND NOT SFML_GCC_VERSION VERSION_LESS "4") OR (SFML_COMPILER_CLANG AND NOT SFML_CLANG_VERSION VERSION_LESS "3")))
set_target_properties(${target} PROPERTIES COMPILE_FLAGS -fvisibility=hidden)
endif()
# build frameworks or dylibs
if(SFML_OS_MACOSX AND BUILD_SHARED_LIBS AND NOT THIS_STATIC)
if(SFML_BUILD_FRAMEWORKS)
# adapt target to build frameworks instead of dylibs
set_target_properties(${target} PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
MACOSX_FRAMEWORK_IDENTIFIER org.sfml-dev.${target}
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
MACOSX_FRAMEWORK_BUNDLE_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
endif()
# adapt install directory to allow distributing dylibs/frameworks in user's frameworks/application bundle
# but only if cmake rpath options aren't set
if(NOT CMAKE_SKIP_RPATH AND NOT CMAKE_SKIP_INSTALL_RPATH AND NOT CMAKE_INSTALL_RPATH AND NOT CMAKE_INSTALL_RPATH_USE_LINK_PATH AND NOT CMAKE_INSTALL_NAME_DIR)
set_target_properties(${target} PROPERTIES INSTALL_NAME_DIR "@rpath")
if(NOT CMAKE_SKIP_BUILD_RPATH)
if (CMAKE_VERSION VERSION_LESS 3.9)
set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
else()
set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_NAME_DIR TRUE)
endif()
endif()
endif()
endif()
# enable automatic reference counting on iOS
if (SFML_OS_IOS)
set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
endif()
# sfml-activity library is our bootstrap activity and must not depend on stlport_shared
# (otherwise Android will fail to load it)
if (SFML_OS_ANDROID)
if (${target} MATCHES "sfml-activity")
set_target_properties(${target} PROPERTIES COMPILE_FLAGS -fpermissive)
set_target_properties(${target} PROPERTIES LINK_FLAGS "-landroid -llog")
set(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY_WITHOUT_STL})
else()
set(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY_WITH_STL})
endif()
endif()
# add the install rule
install(TARGETS ${target} EXPORT SFMLConfigExport
RUNTIME DESTINATION bin COMPONENT bin
LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT bin
ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT devel
FRAMEWORK DESTINATION "." COMPONENT bin)
# add <project>/include as public include directory
target_include_directories(${target}
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
PRIVATE ${PROJECT_SOURCE_DIR}/src)
if (SFML_BUILD_FRAMEWORKS)
target_include_directories(${target} INTERFACE $<INSTALL_INTERFACE:SFML.framework>)
else()
target_include_directories(${target} INTERFACE $<INSTALL_INTERFACE:include>)
endif()
# define SFML_STATIC if the build type is not set to 'shared'
if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(${target} PUBLIC "SFML_STATIC")
endif()
endmacro()
# add a new target which is a SFML example
# example: sfml_add_example(ftp
# SOURCES ftp.cpp ...
# BUNDLE_RESOURCES MainMenu.nib ... # Files to be added in target but not installed next to the executable
# DEPENDS sfml-network
# RESOURCES_DIR resources) # A directory to install next to the executable and sources
macro(sfml_add_example target)
# parse the arguments
cmake_parse_arguments(THIS "GUI_APP" "RESOURCES_DIR" "SOURCES;BUNDLE_RESOURCES;DEPENDS" ${ARGN})
# set a source group for the source files
source_group("" FILES ${THIS_SOURCES})
# check whether resources must be added in target
set(target_input ${THIS_SOURCES})
if(THIS_BUNDLE_RESOURCES)
set(target_input ${target_input} ${THIS_BUNDLE_RESOURCES})
endif()
# create the target
if(THIS_GUI_APP AND SFML_OS_WINDOWS AND NOT DEFINED CMAKE_CONFIGURATION_TYPES AND ${CMAKE_BUILD_TYPE} STREQUAL "Release")
add_executable(${target} WIN32 ${target_input})
target_link_libraries(${target} PRIVATE sfml-main)
elseif(THIS_GUI_APP AND SFML_OS_IOS)
add_executable(${target} MACOSX_BUNDLE ${target_input})
target_link_libraries(${target} PRIVATE sfml-main)
else()
add_executable(${target} ${target_input})
endif()
# set the debug suffix
set_target_properties(${target} PROPERTIES DEBUG_POSTFIX -d)
# set the target's folder (for IDEs that support it, e.g. Visual Studio)
set_target_properties(${target} PROPERTIES FOLDER "Examples")
# set the target flags to use the appropriate C++ standard library
sfml_set_stdlib(${target})
# set the Visual Studio startup path for debugging
set_target_properties(${target} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# link the target to its SFML dependencies
if(THIS_DEPENDS)
target_link_libraries(${target} PRIVATE ${THIS_DEPENDS})
endif()
# add the install rule
install(TARGETS ${target}
RUNTIME DESTINATION ${SFML_MISC_INSTALL_PREFIX}/examples/${target} COMPONENT examples
BUNDLE DESTINATION ${SFML_MISC_INSTALL_PREFIX}/examples/${target} COMPONENT examples)
# install the example's source code
install(FILES ${THIS_SOURCES}
DESTINATION ${SFML_MISC_INSTALL_PREFIX}/examples/${target}
COMPONENT examples)
if (THIS_RESOURCES_DIR)
# install the example's resources as well
get_filename_component(THIS_RESOURCES_DIR "${THIS_RESOURCES_DIR}" ABSOLUTE)
if(NOT EXISTS "${THIS_RESOURCES_DIR}")
message(FATAL_ERROR "Given resources directory to install does not exist: ${THIS_RESOURCES_DIR}")
endif()
install(DIRECTORY ${THIS_RESOURCES_DIR}
DESTINATION ${SFML_MISC_INSTALL_PREFIX}/examples/${target}
COMPONENT examples)
endif()
endmacro()
# Find the requested package and make an INTERFACE library from it
# Usage: sfml_find_package(wanted_target_name
# [INCLUDE "OPENGL_INCLUDE_DIR"]
# [LINK "OPENGL_gl_LIBRARY"])
function(sfml_find_package)
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules/")
list(GET ARGN 0 target)
list(REMOVE_AT ARGN 0)
if (TARGET ${target})
message(FATAL_ERROR "Target '${target}' is already defined")
endif()
cmake_parse_arguments(THIS "" "" "INCLUDE;LINK" ${ARGN})
if (THIS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown arguments when calling sfml_import_library: ${THIS_UNPARSED_ARGUMENTS}")
endif()
if (SFML_OS_IOS)
find_host_package(${target} REQUIRED)
else()
find_package(${target} REQUIRED)
endif()
add_library(${target} INTERFACE)
if (THIS_INCLUDE)
foreach(include_dir IN LISTS "${THIS_INCLUDE}")
if (NOT include_dir)
message(FATAL_ERROR "No path given for include dir ${THIS_INCLUDE}")
endif()
target_include_directories(${target} INTERFACE "$<BUILD_INTERFACE:${include_dir}>")
endforeach()
endif()
if (THIS_LINK)
foreach(link_item IN LISTS ${THIS_LINK})
if (NOT link_item)
message(FATAL_ERROR "Missing item in ${THIS_LINK}")
endif()
target_link_libraries(${target} INTERFACE "$<BUILD_INTERFACE:${link_item}>")
endforeach()
endif()
install(TARGETS ${target} EXPORT SFMLConfigExport)
endfunction()
# Generate a SFMLConfig.cmake file (and associated files) from the targets registered against
# the EXPORT name "SFMLConfigExport" (EXPORT parameter of install(TARGETS))
function(sfml_export_targets)
# CMAKE_CURRENT_LIST_DIR or CMAKE_CURRENT_SOURCE_DIR not usable for files that are to be included like this one
set(CURRENT_DIR "${PROJECT_SOURCE_DIR}/cmake")
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/SFMLConfigVersion.cmake"
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}
COMPATIBILITY SameMajorVersion)
if (BUILD_SHARED_LIBS)
set(config_name "Shared")
else()
set(config_name "Static")
endif()
set(targets_config_filename "SFML${config_name}Targets.cmake")
export(EXPORT SFMLConfigExport
FILE "${CMAKE_CURRENT_BINARY_DIR}/${targets_config_filename}")
if (SFML_BUILD_FRAMEWORKS)
set(config_package_location "SFML.framework/Resources/CMake")
else()
set(config_package_location lib${LIB_SUFFIX}/cmake/SFML)
endif()
configure_package_config_file("${CURRENT_DIR}/SFMLConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/SFMLConfig.cmake"
INSTALL_DESTINATION "${config_package_location}")
configure_package_config_file("${CURRENT_DIR}/SFMLConfigDependencies.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/SFMLConfigDependencies.cmake"
INSTALL_DESTINATION "${config_package_location}")
install(EXPORT SFMLConfigExport
FILE ${targets_config_filename}
DESTINATION ${config_package_location})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/SFMLConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/SFMLConfigDependencies.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/SFMLConfigVersion.cmake"
DESTINATION ${config_package_location}
COMPONENT devel)
endfunction()
#
# Try to find EGL library and include path.
# Once done this will define
#
# EGL_FOUND
# EGL_INCLUDE_PATH
# EGL_LIBRARY
#
find_path(EGL_INCLUDE_DIR EGL/egl.h)
find_library(EGL_LIBRARY NAMES