diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..fba552ee35 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# See https://editorconfig.org/ for more info :) + +[*] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.py] +indent_size = 4 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2b313d6c7a..0901721340 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,12 @@ if(CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) endif(CCACHE_FOUND) +option(USE_SYSTEM_ASSIMP "Use system Assimp instead of a bundled submodule" OFF) +option(USE_SYSTEM_EIGEN "Use system Eigen instead of a bundled submodule" OFF) +option(USE_SYSTEM_MAGNUM "Use system Magnum instead of a bundled submodule" OFF) +option(USE_SYSTEM_PYBIND11 "Use system Pybind11 instead of a bundled submodule" OFF) +option(USE_SYSTEM_RAPIDJSON "Use system RapidJSON instead of a bundled submodule" OFF) + set(BUILD_GUI_VIEWERS OFF CACHE BOOL "BUILD_GUI_VIEWERS") # set(CMAKE_BUILD_TYPE Debug) diff --git a/src/cmake/FindCorrade.cmake b/src/cmake/FindCorrade.cmake new file mode 100644 index 0000000000..52562bf306 --- /dev/null +++ b/src/cmake/FindCorrade.cmake @@ -0,0 +1,513 @@ +#.rst: +# Find Corrade +# ------------ +# +# Finds the Corrade library. Basic usage:: +# +# find_package(Corrade REQUIRED) +# +# This module tries to find the base Corrade library and then defines the +# following: +# +# Corrade_FOUND - Whether the base library was found +# CORRADE_LIB_SUFFIX_MODULE - Path to CorradeLibSuffix.cmake module +# +# This command will try to find only the base library, not the optional +# components, which are: +# +# Containers - Containers library +# PluginManager - PluginManager library +# TestSuite - TestSuite library +# Utility - Utility library +# rc - corrade-rc executable +# +# Example usage with specifying additional components is:: +# +# find_package(Corrade REQUIRED Utility TestSuite) +# +# For each component is then defined: +# +# Corrade_*_FOUND - Whether the component was found +# Corrade::* - Component imported target +# +# The package is found if either debug or release version of each library is +# found. If both debug and release libraries are found, proper version is +# chosen based on actual build configuration of the project (i.e. Debug build +# is linked to debug libraries, Release build to release libraries). +# +# Corrade conditionally defines ``CORRADE_IS_DEBUG_BUILD`` preprocessor +# variable in case build configuration is ``Debug`` (not Corrade itself, but +# build configuration of the project using it). Useful e.g. for selecting +# proper plugin directory. +# +# Corrade defines the following custom target properties: +# +# CORRADE_CXX_STANDARD - C++ standard to require when compiling given +# target. Does nothing if :variable:`CMAKE_CXX_FLAGS` already contains +# particular standard setting flag or if given target contains +# :prop_tgt:`CMAKE_CXX_STANDARD` property. Allowed value is 11, 14 or 17. +# INTERFACE_CORRADE_CXX_STANDARD - C++ standard to require when using given +# target. Does nothing if :variable:`CMAKE_CXX_FLAGS` already contains +# particular standard setting flag or if given target contains +# :prop_tgt:`CMAKE_CXX_STANDARD` property. Allowed value is 11, 14 or 17. +# CORRADE_USE_PEDANTIC_FLAGS - Enable additional compiler/linker flags. +# Boolean. +# +# These properties are inherited from directory properties, meaning that if you +# set them on directories, they get implicitly set on all targets in given +# directory (with a possibility to do target-specific overrides). All Corrade +# libraries have the :prop_tgt:`INTERFACE_CORRADE_CXX_STANDARD` property set to +# 11, meaning that you will always have at least C++11 enabled once you link to +# any Corrade library. +# +# Features of found Corrade library are exposed in these variables: +# +# CORRADE_MSVC2017_COMPATIBILITY - Defined if compiled with compatibility +# mode for MSVC 2017 +# CORRADE_MSVC2015_COMPATIBILITY - Defined if compiled with compatibility +# mode for MSVC 2015 +# CORRADE_BUILD_DEPRECATED - Defined if compiled with deprecated APIs +# included +# CORRADE_BUILD_STATIC - Defined if compiled as static libraries. +# Default are shared libraries. +# CORRADE_TARGET_UNIX - Defined if compiled for some Unix flavor +# (Linux, BSD, macOS) +# CORRADE_TARGET_APPLE - Defined if compiled for Apple platforms +# CORRADE_TARGET_IOS - Defined if compiled for iOS (device or +# simulator) +# CORRADE_TARGET_IOS_SIMULATOR - Defined if compiled for iOS Simulator +# CORRADE_TARGET_WINDOWS - Defined if compiled for Windows +# CORRADE_TARGET_WINDOWS_RT - Defined if compiled for Windows RT +# CORRADE_TARGET_EMSCRIPTEN - Defined if compiled for Emscripten +# CORRADE_TARGET_ANDROID - Defined if compiled for Android +# CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT - Defined if PluginManager +# doesn't support dynamic plugin loading due to platform limitations +# CORRADE_TESTSUITE_TARGET_XCTEST - Defined if TestSuite is targetting Xcode +# XCTest +# CORRADE_UTILITY_USE_ANSI_COLORS - Defined if ANSI escape sequences are used +# for colored output with Utility::Debug on Windows +# +# Additionally these variables are defined for internal usage: +# +# CORRADE_INCLUDE_DIR - Root include dir +# CORRADE_*_LIBRARY_DEBUG - Debug version of given library, if found +# CORRADE_*_LIBRARY_RELEASE - Release version of given library, if found +# CORRADE_*_EXECUTABLE - Location of given executable, if found +# CORRADE_USE_MODULE - Path to UseCorrade.cmake module (included +# automatically) +# CORRADE_TESTSUITE_XCTEST_RUNNER - Path to XCTestRunner.mm.in file +# CORRADE_TESTSUITE_ADB_RUNNER - Path to AdbRunner.sh file +# CORRADE_PEDANTIC_COMPILER_OPTIONS - List of pedantic compiler options used +# for targets with :prop_tgt:`CORRADE_USE_PEDANTIC_FLAGS` enabled +# CORRADE_PEDANTIC_COMPILER_DEFINITIONS - List of pedantic compiler +# definitions used for targets with :prop_tgt:`CORRADE_USE_PEDANTIC_FLAGS` +# enabled +# +# Workflows without :prop_tgt:`IMPORTED` targets are deprecated and the +# following variables are included just for backwards compatibility and only if +# :variable:`CORRADE_BUILD_DEPRECATED` is enabled: +# +# CORRADE_CXX_FLAGS - Pedantic compile flags. Use +# :prop_tgt:`CORRADE_USE_PEDANTIC_FLAGS` property or +# :variable:`CORRADE_PEDANTIC_COMPILER_DEFINITIONS` / +# :variable:`CORRADE_PEDANTIC_COMPILER_OPTIONS` list variables instead. +# +# Corrade provides these macros and functions: +# +# .. command:: corrade_add_test +# +# Add unit test using Corrade's TestSuite:: +# +# corrade_add_test( +# ... +# [LIBRARIES ...] +# [FILES ...] +# [ARGUMENTS ...]) +# +# Test name is also executable name. You can use ``LIBRARIES`` to specify +# libraries to link with instead of using :command:`target_link_libraries()`. +# The ``Corrade::TestSuite`` target is linked automatically to each test. Note +# that the :command:`enable_testing()` function must be called explicitly. +# Arguments passed after ``ARGUMENTS`` will be appended to the test +# command line. ``ARGUMENTS`` are supported everywhere except when +# ``CORRADE_TESTSUITE_TARGET_XCTEST`` is enabled. +# +# You can list files needed by the test in the ``FILES`` section. If given +# filename is relative, it is treated relatively to `CMAKE_CURRENT_SOURCE_DIR`. +# The files are added to the :prop_test:`REQUIRED_FILES` target property. On +# Emscripten they are bundled to the executable and available in the virtual +# filesystem root. On Android they are copied along the executable to the +# target. In case of Emscripten and Android, if the file is absolute or +# contains ``..``, only the leaf name is used. Alternatively you can have a +# filename formatted as ``@``, in which case the ```` is +# treated as local filesystem location and ```` as remote/virtual +# filesystem location. The remote location can't be absolute or contain ``..`` +# / ``@`` characters. +# +# Unless :variable:`CORRADE_TESTSUITE_TARGET_XCTEST` is set, test cases on iOS +# targets are created as bundles with bundle identifier set to CMake project +# name by default. Use the cache variable :variable:`CORRADE_TESTSUITE_BUNDLE_IDENTIFIER_PREFIX` +# to change it to something else. +# +# .. command:: corrade_add_resource +# +# Compile data resources into application binary:: +# +# corrade_add_resource( ) +# +# Depends on ``Corrade::rc``, which is part of Corrade utilities. This command +# generates resource data using given configuration file in current build +# directory. Argument name is name under which the resources can be explicitly +# loaded. Variable ```` contains compiled resource filename, which is +# then used for compiling library / executable. On CMake >= 3.1 the +# `resources.conf` file can contain UTF-8-encoded filenames. Example usage:: +# +# corrade_add_resource(app_resources resources.conf) +# add_executable(app source1 source2 ... ${app_resources}) +# +# .. command:: corrade_add_plugin +# +# Add dynamic plugin:: +# +# corrade_add_plugin( +# ";" +# ";" +# +# ...) +# +# The macro adds preprocessor directive ``CORRADE_DYNAMIC_PLUGIN``. Additional +# libraries can be linked in via :command:`target_link_libraries(plugin_name ...) `. +# On DLL platforms, the plugin DLLs and metadata files are put into +# ````/```` and the +# ``*.lib`` files into ````/````. +# On non-DLL platforms everything is put into ````/ +# ````. +# +# corrade_add_plugin( +# +# +# +# ...) +# +# Unline the above version this puts everything into ```` on +# both DLL and non-DLL platforms. If ```` is set to +# :variable:`CMAKE_CURRENT_BINARY_DIR` (e.g. for testing purposes), the files +# are copied directly, without the need to perform install step. Note that the +# files are actually put into configuration-based subdirectory, i.e. +# ``${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}``. See documentation of +# :variable:`CMAKE_CFG_INTDIR` variable for more information. +# +# .. command:: corrade_add_static_plugin +# +# Add static plugin:: +# +# corrade_add_static_plugin( +# ";" +# +# ...) +# +# The macro adds preprocessor directive ``CORRADE_STATIC_PLUGIN``. Additional +# libraries can be linked in via :command:`target_link_libraries(plugin_name ...) `. +# The ```` is ignored and included just for compatibility +# with the :command:`corrade_add_plugin` command, everything is installed into +# ````. Note that plugins built in debug configuration +# (e.g. with :variable:`CMAKE_BUILD_TYPE` set to ``Debug``) have ``"-d"`` +# suffix to make it possible to have both debug and release plugins installed +# alongside each other. +# +# corrade_add_static_plugin( +# +# +# ...) +# +# Equivalent to the above with ```` set to ````. +# If ```` is set to :variable:`CMAKE_CURRENT_BINARY_DIR` (e.g. for +# testing purposes), no installation rules are added. +# +# .. command:: corrade_find_dlls_for_libs +# +# Find corresponding DLLs for library files:: +# +# corrade_find_dlls_for_libs( ...) +# +# Available only on Windows, for all ``*.lib`` files tries to find +# corresponding DLL file. Useful for bundling dependencies for e.g. WinRT +# packages. +# + +# +# This file is part of Corrade. +# +# Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, +# 2017, 2018, 2019 Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# Root include dir +find_path(CORRADE_INCLUDE_DIR + NAMES Corrade/Corrade.h) +mark_as_advanced(CORRADE_INCLUDE_DIR) + +# Configuration file +find_file(_CORRADE_CONFIGURE_FILE configure.h + HINTS ${CORRADE_INCLUDE_DIR}/Corrade/) +mark_as_advanced(_CORRADE_CONFIGURE_FILE) + +# We need to open configure.h file from CORRADE_INCLUDE_DIR before we check for +# the components. Bail out with proper error message if it wasn't found. The +# complete check with all components is further below. +if(NOT CORRADE_INCLUDE_DIR) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Corrade + REQUIRED_VARS CORRADE_INCLUDE_DIR _CORRADE_CONFIGURE_FILE) +endif() + +# Read flags from configuration +file(READ ${_CORRADE_CONFIGURE_FILE} _corradeConfigure) +set(_corradeFlags + # WARNING: CAREFUL HERE, the string(FIND) succeeds even if a subset is + # found -- so e.g. looking for TARGET_GL will match TARGET_GLES2 as well. + # So far that's not a problem, but might become an issue for new flags. + MSVC2015_COMPATIBILITY + MSVC2017_COMPATIBILITY + BUILD_DEPRECATED + BUILD_STATIC + TARGET_UNIX + TARGET_APPLE + TARGET_IOS + TARGET_IOS_SIMULATOR + TARGET_WINDOWS + TARGET_WINDOWS_RT + TARGET_EMSCRIPTEN + TARGET_ANDROID + PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT + TESTSUITE_TARGET_XCTEST + UTILITY_USE_ANSI_COLORS) +foreach(_corradeFlag ${_corradeFlags}) + string(FIND "${_corradeConfigure}" "#define CORRADE_${_corradeFlag}" _corrade_${_corradeFlag}) + if(NOT _corrade_${_corradeFlag} EQUAL -1) + set(CORRADE_${_corradeFlag} 1) + endif() +endforeach() + +# CMake module dir +find_path(_CORRADE_MODULE_DIR + NAMES UseCorrade.cmake CorradeLibSuffix.cmake + PATH_SUFFIXES share/cmake/Corrade) +mark_as_advanced(_CORRADE_MODULE_DIR) + +set(CORRADE_USE_MODULE ${_CORRADE_MODULE_DIR}/UseCorrade.cmake) +set(CORRADE_LIB_SUFFIX_MODULE ${_CORRADE_MODULE_DIR}/CorradeLibSuffix.cmake) + +# Ensure that all inter-component dependencies are specified as well +foreach(_component ${Corrade_FIND_COMPONENTS}) + string(TOUPPER ${_component} _COMPONENT) + + if(_component STREQUAL Containers) + set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility) + elseif(_component STREQUAL Interconnect) + set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility) + elseif(_component STREQUAL PluginManager) + set(_CORRADE_${_COMPONENT}_DEPENDENCIES Containers Utility rc) + elseif(_component STREQUAL TestSuite) + set(_CORRADE_${_COMPONENT}_DEPENDENCIES Utility) + elseif(_component STREQUAL Utility) + set(_CORRADE_${_COMPONENT}_DEPENDENCIES Containers rc) + endif() + + # Mark the dependencies as required if the component is also required + if(Corrade_FIND_REQUIRED_${_component}) + foreach(_dependency ${_CORRADE_${_COMPONENT}_DEPENDENCIES}) + set(Corrade_FIND_REQUIRED_${_dependency} TRUE) + endforeach() + endif() + + list(APPEND _CORRADE_ADDITIONAL_COMPONENTS ${_CORRADE_${_COMPONENT}_DEPENDENCIES}) +endforeach() + +# Join the lists, remove duplicate components +if(_CORRADE_ADDITIONAL_COMPONENTS) + list(INSERT Corrade_FIND_COMPONENTS 0 ${_CORRADE_ADDITIONAL_COMPONENTS}) +endif() +if(Corrade_FIND_COMPONENTS) + list(REMOVE_DUPLICATES Corrade_FIND_COMPONENTS) +endif() + +# Component distinction +set(_CORRADE_LIBRARY_COMPONENTS "^(Containers|Interconnect|PluginManager|TestSuite|Utility)$") +set(_CORRADE_HEADER_ONLY_COMPONENTS "^(Containers)$") +set(_CORRADE_EXECUTABLE_COMPONENTS "^(rc)$") + +# Find all components +foreach(_component ${Corrade_FIND_COMPONENTS}) + string(TOUPPER ${_component} _COMPONENT) + + # Create imported target in case the library is found. If the project is + # added as subproject to CMake, the target already exists and all the + # required setup is already done from the build tree. + if(TARGET Corrade::${_component}) + set(Corrade_${_component}_FOUND TRUE) + else() + # Library components + if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS} AND NOT _component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS}) + add_library(Corrade::${_component} UNKNOWN IMPORTED) + + # Try to find both debug and release version + find_library(CORRADE_${_COMPONENT}_LIBRARY_DEBUG Corrade${_component}-d) + find_library(CORRADE_${_COMPONENT}_LIBRARY_RELEASE Corrade${_component}) + mark_as_advanced(CORRADE_${_COMPONENT}_LIBRARY_DEBUG + CORRADE_${_COMPONENT}_LIBRARY_RELEASE) + + if(CORRADE_${_COMPONENT}_LIBRARY_RELEASE) + set_property(TARGET Corrade::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET Corrade::${_component} PROPERTY + IMPORTED_LOCATION_RELEASE ${CORRADE_${_COMPONENT}_LIBRARY_RELEASE}) + endif() + + if(CORRADE_${_COMPONENT}_LIBRARY_DEBUG) + set_property(TARGET Corrade::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET Corrade::${_component} PROPERTY + IMPORTED_LOCATION_DEBUG ${CORRADE_${_COMPONENT}_LIBRARY_DEBUG}) + endif() + endif() + + # Header-only library components + if(_component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS}) + add_library(Corrade::${_component} INTERFACE IMPORTED) + endif() + + # Executable components + if(_component MATCHES ${_CORRADE_EXECUTABLE_COMPONENTS}) + add_executable(Corrade::${_component} IMPORTED) + + find_program(CORRADE_${_COMPONENT}_EXECUTABLE corrade-${_component}) + mark_as_advanced(CORRADE_${_COMPONENT}_EXECUTABLE) + + if(CORRADE_${_COMPONENT}_EXECUTABLE) + set_property(TARGET Corrade::${_component} PROPERTY + IMPORTED_LOCATION ${CORRADE_${_COMPONENT}_EXECUTABLE}) + endif() + endif() + + # No special setup for Containers library + + # Interconnect library + if(_component STREQUAL Interconnect) + # Disable /OPT:ICF on MSVC, which merges functions with identical + # contents and thus breaks signal comparison + if(CORRADE_TARGET_WINDOWS AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + if(CMAKE_VERSION VERSION_LESS 3.13) + set_property(TARGET Corrade::${_component} PROPERTY + INTERFACE_LINK_LIBRARIES "-OPT:NOICF,REF") + else() + set_property(TARGET Corrade::${_component} PROPERTY + INTERFACE_LINK_OPTIONS "/OPT:NOICF,REF") + endif() + endif() + + # PluginManager library + elseif(_component STREQUAL PluginManager) + # At least static build needs this + if(CORRADE_TARGET_UNIX) + set_property(TARGET Corrade::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}) + endif() + + # TestSuite library has some additional files + elseif(_component STREQUAL TestSuite) + # XCTest runner file + if(CORRADE_TESTSUITE_TARGET_XCTEST) + find_file(CORRADE_TESTSUITE_XCTEST_RUNNER XCTestRunner.mm.in + PATH_SUFFIXES share/corrade/TestSuite) + set(CORRADE_TESTSUITE_XCTEST_RUNNER_NEEDED CORRADE_TESTSUITE_XCTEST_RUNNER) + + # ADB runner file + elseif(CORRADE_TARGET_ANDROID) + find_file(CORRADE_TESTSUITE_ADB_RUNNER AdbRunner.sh + PATH_SUFFIXES share/corrade/TestSuite) + set(CORRADE_TESTSUITE_ADB_RUNNER_NEEDED CORRADE_TESTSUITE_ADB_RUNNER) + + # Emscripten runner file + elseif(CORRADE_TARGET_EMSCRIPTEN) + find_file(CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER EmscriptenRunner.html.in + PATH_SUFFIXES share/corrade/TestSuite) + set(CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER_NEEDED CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER) + endif() + + # Utility library (contains all setup that is used by others) + elseif(_component STREQUAL Utility) + # Top-level include directory + set_property(TARGET Corrade::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${CORRADE_INCLUDE_DIR}) + + # Require (at least) C++11 for users + set_property(TARGET Corrade::${_component} PROPERTY + INTERFACE_CORRADE_CXX_STANDARD 11) + set_property(TARGET Corrade::${_component} APPEND PROPERTY + COMPATIBLE_INTERFACE_NUMBER_MAX CORRADE_CXX_STANDARD) + + # AndroidLogStreamBuffer class needs to be linked to log library + if(CORRADE_TARGET_ANDROID) + set_property(TARGET Corrade::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "log") + endif() + endif() + + # Find library includes + if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS}) + find_path(_CORRADE_${_COMPONENT}_INCLUDE_DIR + NAMES ${_component}.h + HINTS ${CORRADE_INCLUDE_DIR}/Corrade/${_component}) + mark_as_advanced(_CORRADE_${_COMPONENT}_INCLUDE_DIR) + endif() + + # Add inter-library dependencies + if(_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS} OR _component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS}) + foreach(_dependency ${_CORRADE_${_COMPONENT}_DEPENDENCIES}) + if(_dependency MATCHES ${_CORRADE_LIBRARY_COMPONENTS} OR _dependency MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS}) + set_property(TARGET Corrade::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Corrade::${_dependency}) + endif() + endforeach() + endif() + + # Decide if the component was found + if((_component MATCHES ${_CORRADE_LIBRARY_COMPONENTS} AND _CORRADE_${_COMPONENT}_INCLUDE_DIR AND (_component MATCHES ${_CORRADE_HEADER_ONLY_COMPONENTS} OR CORRADE_${_COMPONENT}_LIBRARY_RELEASE OR CORRADE_${_COMPONENT}_LIBRARY_DEBUG)) OR (_component MATCHES ${_CORRADE_EXECUTABLE_COMPONENTS} AND CORRADE_${_COMPONENT}_EXECUTABLE)) + set(Corrade_${_component}_FOUND TRUE) + else() + set(Corrade_${_component}_FOUND FALSE) + endif() + endif() +endforeach() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Corrade REQUIRED_VARS + CORRADE_INCLUDE_DIR + _CORRADE_MODULE_DIR + _CORRADE_CONFIGURE_FILE + ${CORRADE_TESTSUITE_XCTEST_RUNNER_NEEDED} + ${CORRADE_TESTSUITE_ADB_RUNNER_NEEDED} + ${CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER_NEEDED} + HANDLE_COMPONENTS) + +# Finalize the finding process +include(${CORRADE_USE_MODULE}) diff --git a/src/cmake/FindEGL.cmake b/src/cmake/FindEGL.cmake new file mode 100644 index 0000000000..5fbe6ad18a --- /dev/null +++ b/src/cmake/FindEGL.cmake @@ -0,0 +1,85 @@ +#.rst: +# Find EGL +# -------- +# +# Finds the EGL library. This module defines: +# +# EGL_FOUND - True if EGL library is found +# EGL::EGL - EGL imported target +# +# Additionally these variables are defined for internal usage: +# +# EGL_LIBRARY - EGL library +# EGL_INCLUDE_DIR - Include dir +# + +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# Library +if(NOT CORRADE_TARGET_EMSCRIPTEN) + find_library(EGL_LIBRARY NAMES + EGL + + # ANGLE (CMake doesn't search for lib prefix on Windows) + libEGL + + # On iOS a part of OpenGLES + OpenGLES) + set(EGL_LIBRARY_NEEDED EGL_LIBRARY) +endif() + +# Include dir +find_path(EGL_INCLUDE_DIR NAMES + EGL/egl.h + + # iOS + EAGL.h) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(EGL DEFAULT_MSG + ${EGL_LIBRARY_NEEDED} + EGL_INCLUDE_DIR) + +if(NOT TARGET EGL::EGL) + if(EGL_LIBRARY_NEEDED) + # Work around BUGGY framework support on macOS + # http://public.kitware.com/pipermail/cmake/2016-April/063179.html + if(APPLE AND ${EGL_LIBRARY} MATCHES "\\.framework$") + add_library(EGL::EGL INTERFACE IMPORTED) + set_property(TARGET EGL::EGL APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${EGL_LIBRARY}) + else() + add_library(EGL::EGL UNKNOWN IMPORTED) + set_property(TARGET EGL::EGL PROPERTY + IMPORTED_LOCATION ${EGL_LIBRARY}) + endif() + else() + add_library(EGL::EGL INTERFACE IMPORTED) + endif() + + set_target_properties(EGL::EGL PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${EGL_INCLUDE_DIR}) +endif() diff --git a/src/cmake/FindGLFW.cmake b/src/cmake/FindGLFW.cmake new file mode 100644 index 0000000000..2e67547a27 --- /dev/null +++ b/src/cmake/FindGLFW.cmake @@ -0,0 +1,94 @@ +#.rst: +# Find GLFW +# --------- +# +# Finds the GLFW library using its cmake config if that exists, otherwise +# falls back to finding it manually. This module defines: +# +# GLFW_FOUND - True if GLFW library is found +# GLFW::GLFW - GLFW imported target +# +# Additionally, in case the config was not found, these variables are defined +# for internal usage: +# +# GLFW_LIBRARY - GLFW library +# GLFW_INCLUDE_DIR - Root include dir +# + +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# Copyright © 2016 Jonathan Hale +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# GLFW installs cmake package config files to shared/ folder which handles +# dependencies in case GLFW is built statically. Try to find first, quietly, so +# it doesn't print loud messages when it's not found, since that's okay. +find_package(glfw3 CONFIG QUIET) + +if(TARGET glfw) + if(NOT TARGET GLFW::GLFW) + # Aliases of (global) targets are only supported in CMake 3.11, so we + # work around it by this. This is easier than fetching all possible + # properties (which are impossible to track of) and then attempting to + # rebuild them into a new target. + add_library(GLFW::GLFW INTERFACE IMPORTED) + set_target_properties(GLFW::GLFW PROPERTIES INTERFACE_LINK_LIBRARIES glfw) + endif() + + # Just to make FPHSA print some meaningful location, nothing else + get_target_property(_GLFW_INTERFACE_INCLUDE_DIRECTORIES glfw INTERFACE_INCLUDE_DIRECTORIES) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args("GLFW" DEFAULT_MSG + _GLFW_INTERFACE_INCLUDE_DIRECTORIES) + return() +endif() + +# In case no config file was found, try manually finding the library. +find_library(GLFW_LIBRARY NAMES glfw glfw3) + +# Include dir +find_path(GLFW_INCLUDE_DIR + NAMES GLFW/glfw3.h) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args("GLFW" DEFAULT_MSG + GLFW_LIBRARY + GLFW_INCLUDE_DIR) + +if(NOT TARGET GLFW::GLFW) + add_library(GLFW::GLFW UNKNOWN IMPORTED) + + # Work around BUGGY framework support on macOS + # https://cmake.org/Bug/view.php?id=14105 + if(CORRADE_TARGET_APPLE AND ${GLFW_LIBRARY} MATCHES "\\.framework$") + set_property(TARGET GLFW::GLFW PROPERTY IMPORTED_LOCATION ${GLFW_LIBRARY}/GLFW) + else() + set_property(TARGET GLFW::GLFW PROPERTY IMPORTED_LOCATION ${GLFW_LIBRARY}) + endif() + + set_property(TARGET GLFW::GLFW PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${GLFW_INCLUDE_DIR}) +endif() + +mark_as_advanced(GLFW_LIBRARY GLFW_INCLUDE_DIR) diff --git a/src/cmake/FindMagnum.cmake b/src/cmake/FindMagnum.cmake new file mode 100644 index 0000000000..f8da1e6076 --- /dev/null +++ b/src/cmake/FindMagnum.cmake @@ -0,0 +1,1137 @@ +#.rst: +# Find Magnum +# ----------- +# +# Finds the Magnum library. Basic usage:: +# +# find_package(Magnum REQUIRED) +# +# This module tries to find the base Magnum library and then defines the +# following: +# +# Magnum_FOUND - Whether the base library was found +# MAGNUM_DEPLOY_PREFIX - Prefix where to put final application +# executables, defaults to ``.``. If a relative path is used, it's relative +# to :variable:`CMAKE_INSTALL_PREFIX`. +# MAGNUM_INCLUDE_INSTALL_PREFIX - Prefix where to put platform-independent +# include and other files, defaults to ``.``. If a relative path is used, +# it's relative to :variable:`CMAKE_INSTALL_PREFIX`. +# MAGNUM_PLUGINS_DEBUG_DIR - Base directory with dynamic plugins for +# debug builds, defaults to magnum-d/ subdirectory of dir where Magnum +# library was found +# MAGNUM_PLUGINS_RELEASE_DIR - Base directory with dynamic plugins for +# release builds, defaults to magnum/ subdirectory of dir where Magnum +# library was found +# MAGNUM_PLUGINS_DIR - Base directory with dynamic plugins, defaults +# to :variable:`MAGNUM_PLUGINS_RELEASE_DIR` in release builds and +# multi-configuration builds or to :variable:`MAGNUM_PLUGINS_DEBUG_DIR` in +# debug builds. You can modify all three variables (e.g. set them to ``.`` +# when deploying on Windows with plugins stored relatively to the +# executable), the following ``MAGNUM_PLUGINS_*_DIR`` variables depend on it. +# MAGNUM_PLUGINS_FONT[|_DEBUG|_RELEASE]_DIR - Directory with dynamic font +# plugins +# MAGNUM_PLUGINS_FONTCONVERTER[|_DEBUG|_RELEASE]_DIR - Directory with dynamic +# font converter plugins +# MAGNUM_PLUGINS_IMAGECONVERTER[|_DEBUG|_RELEASE]_DIR - Directory with dynamic +# image converter plugins +# MAGNUM_PLUGINS_IMPORTER[|_DEBUG|_RELEASE]_DIR - Directory with dynamic +# importer plugins +# MAGNUM_PLUGINS_AUDIOIMPORTER[|_DEBUG|_RELEASE]_DIR - Directory with dynamic +# audio importer plugins +# +# If Magnum is built for Emscripten, the following variables contain paths to +# various support files: +# +# MAGNUM_EMSCRIPTENAPPLICATION_JS - Path to the EmscriptenApplication.js file +# MAGNUM_WINDOWLESSEMSCRIPTENAPPLICATION_JS - Path to the +# WindowlessEmscriptenApplication.js file +# MAGNUM_WEBAPPLICATION_CSS - Path to the WebApplication.css file +# +# This command will try to find only the base library, not the optional +# components. The base library depends on Corrade and OpenGL libraries (or +# OpenGL ES libraries). Additional dependencies are specified by the +# components. The optional components are: +# +# AnyAudioImporter - Any audio importer +# AnyImageConverter - Any image converter +# AnyImageImporter - Any image importer +# AnySceneImporter - Any scene importer +# Audio - Audio library +# DebugTools - DebugTools library +# GL - GL library +# MeshTools - MeshTools library +# Primitives - Primitives library +# SceneGraph - SceneGraph library +# Shaders - Shaders library +# Text - Text library +# TextureTools - TextureTools library +# Trade - Trade library +# Vk - Vk library +# GlfwApplication - GLFW application +# GlxApplication - GLX application +# Sdl2Application - SDL2 application +# XEglApplication - X/EGL application +# WindowlessCglApplication - Windowless CGL application +# WindowlessEglApplication - Windowless EGL application +# WindowlessGlxApplication - Windowless GLX application +# WindowlessIosApplication - Windowless iOS application +# WindowlessWglApplication - Windowless WGL application +# WindowlessWindowsEglApplication - Windowless Windows/EGL application +# CglContext - CGL context +# EglContext - EGL context +# GlxContext - GLX context +# WglContext - WGL context +# OpenGLTester - OpenGLTester class +# MagnumFont - Magnum bitmap font plugin +# MagnumFontConverter - Magnum bitmap font converter plugin +# ObjImporter - OBJ importer plugin +# TgaImageConverter - TGA image converter plugin +# TgaImporter - TGA importer plugin +# WavAudioImporter - WAV audio importer plugin +# distancefieldconverter - magnum-distancefieldconverter executable +# fontconverter - magnum-fontconverter executable +# imageconverter - magnum-imageconverter executable +# gl-info - magnum-gl-info executable +# al-info - magnum-al-info executable +# +# Example usage with specifying additional components is:: +# +# find_package(Magnum REQUIRED Trade MeshTools Primitives GlfwApplication) +# +# For each component is then defined: +# +# Magnum_*_FOUND - Whether the component was found +# Magnum::* - Component imported target +# +# If exactly one ``*Application`` or exactly one ``Windowless*Application`` +# component is requested and found, its target is available in convenience +# alias ``Magnum::Application`` / ``Magnum::WindowlessApplication`` to simplify +# porting. Similarly, if exactly one ``*Context`` component is requested and +# found, its target is available in convenience alias ``Magnum::GLContext``. +# +# The package is found if either debug or release version of each requested +# library (or plugin) is found. If both debug and release libraries (or +# plugins) are found, proper version is chosen based on actual build +# configuration of the project (i.e. Debug build is linked to debug libraries, +# Release build to release libraries). Note that this autodetection might fail +# for the :variable:`MAGNUM_PLUGINS_DIR` variable, especially on +# multi-configuration build systems. You can make use of +# ``CORRADE_IS_DEBUG_BUILD`` preprocessor variable along with +# ``MAGNUM_PLUGINS_*_DEBUG_DIR`` / ``MAGNUM_PLUGINS_*_RELEASE_DIR`` variables +# to decide in preprocessing step. +# +# Features of found Magnum library are exposed in these variables: +# +# MAGNUM_BUILD_DEPRECATED - Defined if compiled with deprecated APIs +# included +# MAGNUM_BUILD_STATIC - Defined if compiled as static libraries +# MAGNUM_BUILD_MULTITHREADED - Defined if compiled in a way that allows +# having multiple thread-local Magnum contexts +# MAGNUM_TARGET_GL - Defined if compiled with OpenGL interop +# MAGNUM_TARGET_GLES - Defined if compiled for OpenGL ES +# MAGNUM_TARGET_GLES2 - Defined if compiled for OpenGL ES 2.0 +# MAGNUM_TARGET_GLES3 - Defined if compiled for OpenGL ES 3.0 +# MAGNUM_TARGET_DESKTOP_GLES - Defined if compiled with OpenGL ES +# emulation on desktop OpenGL +# MAGNUM_TARGET_WEBGL - Defined if compiled for WebGL +# MAGNUM_TARGET_HEADLESS - Defined if compiled for headless machines +# MAGNUM_TARGET_VK - Defined if compiled with Vulkan interop +# +# Additionally these variables are defined for internal usage: +# +# MAGNUM_INCLUDE_DIR - Root include dir (w/o dependencies) +# MAGNUM_LIBRARY - Magnum library (w/o dependencies) +# MAGNUM_LIBRARY_DEBUG - Debug version of Magnum library, if found +# MAGNUM_LIBRARY_RELEASE - Release version of Magnum library, if found +# MAGNUM_*_LIBRARY - Component libraries (w/o dependencies) +# MAGNUM_*_LIBRARY_DEBUG - Debug version of given library, if found +# MAGNUM_*_LIBRARY_RELEASE - Release version of given library, if found +# MAGNUM_BINARY_INSTALL_DIR - Binary installation directory +# MAGNUM_LIBRARY_INSTALL_DIR - Library installation directory +# MAGNUM_DATA_INSTALL_DIR - Data installation directory +# MAGNUM_PLUGINS_[DEBUG|RELEASE]_BINARY_INSTALL_DIR - Plugin binary +# installation directory +# MAGNUM_PLUGINS_[DEBUG|RELEASE]_LIBRARY_INSTALL_DIR - Plugin library +# installation directory +# MAGNUM_PLUGINS_FONT_[DEBUG|RELEASE]_BINARY_INSTALL_DIR - Font plugin binary +# installation directory +# MAGNUM_PLUGINS_FONT_[DEBUG|RELEASE]_LIBRARY_INSTALL_DIR - Font plugin +# library installation directory +# MAGNUM_PLUGINS_FONTCONVERTER_[DEBUG|RELEASE]_BINARY_INSTALL_DIR - Font +# converter plugin binary installation directory +# MAGNUM_PLUGINS_FONTCONVERTER_[DEBUG|RELEASE]_LIBRARY_INSTALL_DIR - Font +# converter plugin library installation directory +# MAGNUM_PLUGINS_IMAGECONVERTER_[DEBUG|RELEASE]_BINARY_INSTALL_DIR - Image +# converter plugin binary installation directory +# MAGNUM_PLUGINS_IMAGECONVERTER_[DEBUG|RELEASE]_LIBRARY_INSTALL_DIR - Image +# converter plugin library installation directory +# MAGNUM_PLUGINS_IMPORTER_[DEBUG|RELEASE]_BINARY_INSTALL_DIR - Importer +# plugin binary installation directory +# MAGNUM_PLUGINS_IMPORTER_[DEBUG|RELEASE]_LIBRARY_INSTALL_DIR - Importer +# plugin library installation directory +# MAGNUM_PLUGINS_AUDIOIMPORTER_[DEBUG|RELEASE]_BINARY_INSTALL_DIR - Audio +# importer plugin binary installation directory +# MAGNUM_PLUGINS_AUDIOIMPORTER_[DEBUG|RELEASE]_LIBRARY_INSTALL_DIR - Audio +# importer plugin library installation directory +# MAGNUM_INCLUDE_INSTALL_DIR - Header installation directory +# MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR - Plugin header installation directory +# + +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# Corrade library dependencies +set(_MAGNUM_CORRADE_DEPENDENCIES ) +foreach(_component ${Magnum_FIND_COMPONENTS}) + string(TOUPPER ${_component} _COMPONENT) + + # Unrolling the transitive dependencies here so this doesn't need to be + # after resolving inter-component dependencies. Listing also all plugins. + if(_component MATCHES "^(Audio|DebugTools|MeshTools|Primitives|Text|TextureTools|Trade|.+Importer|.+ImageConverter|.+Font)$") + set(_MAGNUM_${_COMPONENT}_CORRADE_DEPENDENCIES PluginManager) + endif() + + list(APPEND _MAGNUM_CORRADE_DEPENDENCIES ${_MAGNUM_${_COMPONENT}_CORRADE_DEPENDENCIES}) +endforeach() +find_package(Corrade REQUIRED Utility ${_MAGNUM_CORRADE_DEPENDENCIES}) + +# Root include dir +find_path(MAGNUM_INCLUDE_DIR + NAMES Magnum/Magnum.h) +mark_as_advanced(MAGNUM_INCLUDE_DIR) + +# Configuration file +find_file(_MAGNUM_CONFIGURE_FILE configure.h + HINTS ${MAGNUM_INCLUDE_DIR}/Magnum/) +mark_as_advanced(_MAGNUM_CONFIGURE_FILE) + +# We need to open configure.h file from MAGNUM_INCLUDE_DIR before we check for +# the components. Bail out with proper error message if it wasn't found. The +# complete check with all components is further below. +if(NOT MAGNUM_INCLUDE_DIR) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Magnum + REQUIRED_VARS MAGNUM_INCLUDE_DIR _MAGNUM_CONFIGURE_FILE) +endif() + +# Read flags from configuration +file(READ ${_MAGNUM_CONFIGURE_FILE} _magnumConfigure) +set(_magnumFlags + # WARNING: CAREFUL HERE, the string(FIND) succeeds even if a subset is + # found -- so e.g. looking for TARGET_GL will match TARGET_GLES2 as well. + # So far that's not a problem, but might become an issue for new flags. + BUILD_DEPRECATED + BUILD_STATIC + BUILD_MULTITHREADED + TARGET_GL + TARGET_GLES + TARGET_GLES2 + TARGET_GLES3 + TARGET_DESKTOP_GLES + TARGET_WEBGL + TARGET_HEADLESS + TARGET_VK) +foreach(_magnumFlag ${_magnumFlags}) + string(FIND "${_magnumConfigure}" "#define MAGNUM_${_magnumFlag}" _magnum_${_magnumFlag}) + if(NOT _magnum_${_magnumFlag} EQUAL -1) + set(MAGNUM_${_magnumFlag} 1) + endif() +endforeach() + +# OpenGL library preference. Prefer to use GLVND, since that's the better +# approach nowadays, but allow the users to override it from outside in case +# it is broken for some reason (Nvidia drivers in Debian's testing (Buster) -- +# reported on 2019-04-09). +if(NOT CMAKE_VERSION VERSION_LESS 3.10 AND NOT OpenGL_GL_PREFERENCE) + set(OpenGL_GL_PREFERENCE GLVND) +endif() + +# Base Magnum library +if(NOT TARGET Magnum::Magnum) + add_library(Magnum::Magnum UNKNOWN IMPORTED) + + # Try to find both debug and release version + find_library(MAGNUM_LIBRARY_DEBUG Magnum-d) + find_library(MAGNUM_LIBRARY_RELEASE Magnum) + mark_as_advanced(MAGNUM_LIBRARY_DEBUG + MAGNUM_LIBRARY_RELEASE) + + # Set the MAGNUM_LIBRARY variable based on what was found, use that + # information to guess also build type of dynamic plugins + if(MAGNUM_LIBRARY_DEBUG AND MAGNUM_LIBRARY_RELEASE) + set(MAGNUM_LIBRARY ${MAGNUM_LIBRARY_RELEASE}) + get_filename_component(_MAGNUM_PLUGINS_DIR_PREFIX ${MAGNUM_LIBRARY_DEBUG} PATH) + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(_MAGNUM_PLUGINS_DIR_SUFFIX "-d") + endif() + elseif(MAGNUM_LIBRARY_DEBUG) + set(MAGNUM_LIBRARY ${MAGNUM_LIBRARY_DEBUG}) + get_filename_component(_MAGNUM_PLUGINS_DIR_PREFIX ${MAGNUM_LIBRARY_DEBUG} PATH) + set(_MAGNUM_PLUGINS_DIR_SUFFIX "-d") + elseif(MAGNUM_LIBRARY_RELEASE) + set(MAGNUM_LIBRARY ${MAGNUM_LIBRARY_RELEASE}) + get_filename_component(_MAGNUM_PLUGINS_DIR_PREFIX ${MAGNUM_LIBRARY_RELEASE} PATH) + endif() + + # On DLL platforms the plugins are stored in bin/ instead of lib/, modify + # _MAGNUM_PLUGINS_DIR_PREFIX accordingly + if(CORRADE_TARGET_WINDOWS) + get_filename_component(_MAGNUM_PLUGINS_DIR_PREFIX ${_MAGNUM_PLUGINS_DIR_PREFIX} PATH) + set(_MAGNUM_PLUGINS_DIR_PREFIX ${_MAGNUM_PLUGINS_DIR_PREFIX}/bin) + endif() + + if(MAGNUM_LIBRARY_RELEASE) + set_property(TARGET Magnum::Magnum APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET Magnum::Magnum PROPERTY + IMPORTED_LOCATION_RELEASE ${MAGNUM_LIBRARY_RELEASE}) + endif() + + if(MAGNUM_LIBRARY_DEBUG) + set_property(TARGET Magnum::Magnum APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET Magnum::Magnum PROPERTY + IMPORTED_LOCATION_DEBUG ${MAGNUM_LIBRARY_DEBUG}) + endif() + + # Include directories + set_property(TARGET Magnum::Magnum APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES + ${MAGNUM_INCLUDE_DIR}) + # Some deprecated APIs use headers (but not externally defined symbols) + # from the GL library, link those includes as well + if(MAGNUM_BUILD_DEPRECATED AND MAGNUM_TARGET_GL) + set_property(TARGET Magnum::Magnum APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${MAGNUM_INCLUDE_DIR}/MagnumExternal/OpenGL) + endif() + + # Dependent libraries + set_property(TARGET Magnum::Magnum APPEND PROPERTY INTERFACE_LINK_LIBRARIES + Corrade::Utility) +else() + set(MAGNUM_LIBRARY Magnum::Magnum) +endif() + +# Component distinction (listing them explicitly to avoid mistakes with finding +# components from other repositories) +set(_MAGNUM_LIBRARY_COMPONENT_LIST + Audio DebugTools GL MeshTools Primitives SceneGraph Shaders Text + TextureTools Trade Vk + AndroidApplication GlfwApplication GlxApplication Sdl2Application + XEglApplication WindowlessCglApplication WindowlessEglApplication + WindowlessGlxApplication WindowlessIosApplication WindowlessWglApplication + WindowlessWindowsEglApplication + CglContext EglContext GlxContext WglContext + OpenGLTester) +set(_MAGNUM_PLUGIN_COMPONENT_LIST + AnyAudioImporter AnyImageConverter AnyImageImporter AnySceneImporter + MagnumFont MagnumFontConverter ObjImporter TgaImageConverter TgaImporter + WavAudioImporter) +set(_MAGNUM_EXECUTABLE_COMPONENT_LIST + distancefieldconverter fontconverter imageconverter gl-info al-info) + +# Inter-component dependencies +set(_MAGNUM_Audio_DEPENDENCIES ) + +set(_MAGNUM_DebugTools_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + # MeshTools, Primitives, SceneGraph and Shaders are used only for GL + # renderers. All of this is optional, compiled in only if the base library + # was selected. + list(APPEND _MAGNUM_DebugTools_DEPENDENCIES MeshTools Primitives SceneGraph Shaders Trade GL) + set(_MAGNUM_DebugTools_MeshTools_DEPENDENCY_IS_OPTIONAL ON) + set(_MAGNUM_DebugTools_Primitives_DEPENDENCY_IS_OPTIONAL ON) + set(_MAGNUM_DebugTools_SceneGraph_DEPENDENCY_IS_OPTIONAL ON) + set(_MAGNUM_DebugTools_Shaders_DEPENDENCY_IS_OPTIONAL ON) + set(_MAGNUM_DebugTools_Trade_DEPENDENCY_IS_OPTIONAL ON) + set(_MAGNUM_DebugTools_GL_DEPENDENCY_IS_OPTIONAL ON) +endif() + +set(_MAGNUM_MeshTools_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + # Trade is used only in compile(), which needs GL as well + list(APPEND _MAGNUM_MeshTools_DEPENDENCIES Trade GL) +endif() + +set(_MAGNUM_OpenGLTester_DEPENDENCIES GL) +if(MAGNUM_TARGET_HEADLESS OR CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_ANDROID) + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessEglApplication) +elseif(CORRADE_TARGET_IOS) + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessIosApplication) +elseif(CORRADE_TARGET_APPLE) + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessCglApplication) +elseif(CORRADE_TARGET_UNIX) + if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES) + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessEglApplication) + else() + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessGlxApplication) + endif() +elseif(CORRADE_TARGET_WINDOWS) + if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES) + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessWglApplication) + else() + list(APPEND _MAGNUM_OpenGLTester_DEPENDENCIES WindowlessWindowsEglApplication) + endif() +endif() + +set(_MAGNUM_Primitives_DEPENDENCIES Trade) +set(_MAGNUM_SceneGraph_DEPENDENCIES ) +set(_MAGNUM_Shaders_DEPENDENCIES GL) +set(_MAGNUM_Text_DEPENDENCIES TextureTools) +if(MAGNUM_TARGET_GL) + list(APPEND _MAGNUM_Text_DEPENDENCIES GL) +endif() + +set(_MAGNUM_TextureTools_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + list(APPEND _MAGNUM_TextureTools_DEPENDENCIES GL) +endif() + +set(_MAGNUM_Trade_DEPENDENCIES ) +set(_MAGNUM_AndroidApplication_DEPENDENCIES GL) + +set(_MAGNUM_GlfwApplication_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + list(APPEND _MAGNUM_GlfwApplication_DEPENDENCIES GL) +endif() + +set(_MAGNUM_GlxApplication_DEPENDENCIES GL) + +set(_MAGNUM_Sdl2Application_DEPENDENCIES ) +if(MAGNUM_TARGET_GL) + list(APPEND _MAGNUM_Sdl2Application_DEPENDENCIES GL) +endif() + +set(_MAGNUM_WindowlessCglApplication_DEPENDENCIES GL) +set(_MAGNUM_WindowlessEglApplication_DEPENDENCIES GL) +set(_MAGNUM_WindowlessGlxApplication_DEPENDENCIES GL) +set(_MAGNUM_WindowlessIosApplication_DEPENDENCIES GL) +set(_MAGNUM_WindowlessWglApplication_DEPENDENCIES GL) +set(_MAGNUM_WindowlessWindowsEglApplication_DEPENDENCIES GL) +set(_MAGNUM_XEglApplication_DEPENDENCIES GL) +set(_MAGNUM_CglContext_DEPENDENCIES GL) +set(_MAGNUM_EglContext_DEPENDENCIES GL) +set(_MAGNUM_GlxContext_DEPENDENCIES GL) +set(_MAGNUM_WglContext_DEPENDENCIES GL) + +set(_MAGNUM_MagnumFont_DEPENDENCIES Trade TgaImporter GL) # and below +set(_MAGNUM_MagnumFontConverter_DEPENDENCIES Trade TgaImageConverter) # and below +set(_MAGNUM_ObjImporter_DEPENDENCIES MeshTools) # and below +foreach(_component ${_MAGNUM_PLUGIN_COMPONENT_LIST}) + if(_component MATCHES ".+AudioImporter") + list(APPEND _MAGNUM_${_component}_DEPENDENCIES Audio) + elseif(_component MATCHES ".+(Importer|ImageConverter)") + list(APPEND _MAGNUM_${_component}_DEPENDENCIES Trade) + elseif(_component MATCHES ".+(Font|FontConverter)") + list(APPEND _MAGNUM_${_component}_DEPENDENCIES Text TextureTools) + endif() +endforeach() + +# Ensure that all inter-component dependencies are specified as well +set(_MAGNUM_ADDITIONAL_COMPONENTS ) +foreach(_component ${Magnum_FIND_COMPONENTS}) + # Mark the dependencies as required if the component is also required, but + # only if they themselves are not optional (for example parts of DebugTools + # are present only if their respective base library is compiled) + if(Magnum_FIND_REQUIRED_${_component}) + foreach(_dependency ${_MAGNUM_${_component}_DEPENDENCIES}) + if(NOT _MAGNUM_${_component}_${_dependency}_DEPENDENCY_IS_OPTIONAL) + set(Magnum_FIND_REQUIRED_${_dependency} TRUE) + endif() + endforeach() + endif() + + list(APPEND _MAGNUM_ADDITIONAL_COMPONENTS ${_MAGNUM_${_component}_DEPENDENCIES}) +endforeach() + +# Join the lists, remove duplicate components +if(_MAGNUM_ADDITIONAL_COMPONENTS) + list(INSERT Magnum_FIND_COMPONENTS 0 ${_MAGNUM_ADDITIONAL_COMPONENTS}) +endif() +if(Magnum_FIND_COMPONENTS) + list(REMOVE_DUPLICATES Magnum_FIND_COMPONENTS) +endif() + +# Convert components lists to regular expressions so I can use if(MATCHES). +# TODO: Drop this once CMake 3.3 and if(IN_LIST) can be used +foreach(_WHAT LIBRARY PLUGIN EXECUTABLE) + string(REPLACE ";" "|" _MAGNUM_${_WHAT}_COMPONENTS "${_MAGNUM_${_WHAT}_COMPONENT_LIST}") + set(_MAGNUM_${_WHAT}_COMPONENTS "^(${_MAGNUM_${_WHAT}_COMPONENTS})$") +endforeach() + +# Find all components. Maintain a list of components that'll need to have +# their optional dependencies checked. +set(_MAGNUM_OPTIONAL_DEPENDENCIES_TO_ADD ) +foreach(_component ${Magnum_FIND_COMPONENTS}) + string(TOUPPER ${_component} _COMPONENT) + + # Create imported target in case the library is found. If the project is + # added as subproject to CMake, the target already exists and all the + # required setup is already done from the build tree. + if(TARGET Magnum::${_component}) + set(Magnum_${_component}_FOUND TRUE) + else() + # Library components + if(_component MATCHES ${_MAGNUM_LIBRARY_COMPONENTS}) + add_library(Magnum::${_component} UNKNOWN IMPORTED) + + # Set library defaults, find the library + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/${_component}) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}.h) + + # Try to find both debug and release version + find_library(MAGNUM_${_COMPONENT}_LIBRARY_DEBUG Magnum${_component}-d) + find_library(MAGNUM_${_COMPONENT}_LIBRARY_RELEASE Magnum${_component}) + mark_as_advanced(MAGNUM_${_COMPONENT}_LIBRARY_DEBUG + MAGNUM_${_COMPONENT}_LIBRARY_RELEASE) + endif() + + # Plugin components + if(_component MATCHES ${_MAGNUM_PLUGIN_COMPONENTS}) + add_library(Magnum::${_component} UNKNOWN IMPORTED) + + # AudioImporter plugin specific name suffixes + if(_component MATCHES ".+AudioImporter$") + set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX audioimporters) + + # Audio importer class is Audio::*Importer, thus we need to + # convert *AudioImporter.h to *Importer.h + string(REPLACE "AudioImporter" "Importer" _MAGNUM_${_COMPONENT}_HEADER_NAME "${_component}") + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${_MAGNUM_${_COMPONENT}_HEADER_NAME}.h) + + # Importer plugin specific name suffixes + elseif(_component MATCHES ".+Importer$") + set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX importers) + + # Font plugin specific name suffixes + elseif(_component MATCHES ".+Font$") + set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX fonts) + + # ImageConverter plugin specific name suffixes + elseif(_component MATCHES ".+ImageConverter$") + set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX imageconverters) + + # FontConverter plugin specific name suffixes + elseif(_component MATCHES ".+FontConverter$") + set(_MAGNUM_${_COMPONENT}_PATH_SUFFIX fontconverters) + endif() + + # Don't override the exception for *AudioImporter plugins + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX MagnumPlugins/${_component}) + if(NOT _MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}.h) + endif() + + # Dynamic plugins don't have any prefix (e.g. `lib` on Linux), + # search with empty prefix and then reset that back so we don't + # accidentaly break something else + set(_tmp_prefixes "${CMAKE_FIND_LIBRARY_PREFIXES}") + set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES};") + + # Try to find both debug and release version. Dynamic and static + # debug libraries are in different places. Static debug plugins are + # in magnum/ with a -d suffix while dynamic debug plugins are in + # magnum-d/ with no suffix. Problem is that Vcpkg's library linking + # automagic needs the static libs to be in the root library + # directory along with everything else and so we need to search for + # the -d suffixed version *before* the unsuffixed so it doesn't + # pick the release library for both debug and release. + find_library(MAGNUM_${_COMPONENT}_LIBRARY_DEBUG ${_component}-d + PATH_SUFFIXES magnum/${_MAGNUM_${_COMPONENT}_PATH_SUFFIX}) + find_library(MAGNUM_${_COMPONENT}_LIBRARY_DEBUG ${_component} + PATH_SUFFIXES magnum-d/${_MAGNUM_${_COMPONENT}_PATH_SUFFIX}) + find_library(MAGNUM_${_COMPONENT}_LIBRARY_RELEASE ${_component} + PATH_SUFFIXES magnum/${_MAGNUM_${_COMPONENT}_PATH_SUFFIX}) + mark_as_advanced(MAGNUM_${_COMPONENT}_LIBRARY_DEBUG + MAGNUM_${_COMPONENT}_LIBRARY_RELEASE) + + # Reset back + set(CMAKE_FIND_LIBRARY_PREFIXES "${_tmp_prefixes}") + endif() + + # Library location for libraries/plugins + if(_component MATCHES ${_MAGNUM_LIBRARY_COMPONENTS} OR _component MATCHES ${_MAGNUM_PLUGIN_COMPONENTS}) + if(MAGNUM_${_COMPONENT}_LIBRARY_RELEASE) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET Magnum::${_component} PROPERTY + IMPORTED_LOCATION_RELEASE ${MAGNUM_${_COMPONENT}_LIBRARY_RELEASE}) + endif() + + if(MAGNUM_${_COMPONENT}_LIBRARY_DEBUG) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET Magnum::${_component} PROPERTY + IMPORTED_LOCATION_DEBUG ${MAGNUM_${_COMPONENT}_LIBRARY_DEBUG}) + endif() + endif() + + # Executables + if(_component MATCHES ${_MAGNUM_EXECUTABLE_COMPONENTS}) + add_executable(Magnum::${_component} IMPORTED) + + find_program(MAGNUM_${_COMPONENT}_EXECUTABLE magnum-${_component}) + mark_as_advanced(MAGNUM_${_COMPONENT}_EXECUTABLE) + + if(MAGNUM_${_COMPONENT}_EXECUTABLE) + set_property(TARGET Magnum::${_component} PROPERTY + IMPORTED_LOCATION ${MAGNUM_${_COMPONENT}_EXECUTABLE}) + endif() + endif() + + # Applications + if(_component MATCHES ".+Application") + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/Platform) + + # Android application dependencies + if(_component STREQUAL AndroidApplication) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES android EGL::EGL) + + # GLFW application dependencies + elseif(_component STREQUAL GlfwApplication) + find_package(GLFW) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES GLFW::GLFW) + # Use the Foundation framework on Apple to query the DPI awareness + if(CORRADE_TARGET_APPLE) + find_library(_MAGNUM_APPLE_FOUNDATION_FRAMEWORK_LIBRARY Foundation) + mark_as_advanced(_MAGNUM_APPLE_FOUNDATION_FRAMEWORK_LIBRARY) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${_MAGNUM_APPLE_FOUNDATION_FRAMEWORK_LIBRARY}) + # Needed for opt-in DPI queries + elseif(CORRADE_TARGET_UNIX) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}) + endif() + + # With GLVND (since CMake 3.11) we need to explicitly link to + # GLX/EGL because libOpenGL doesn't provide it. For EGL we have + # our own EGL find module, which makes things simpler. The + # upstream FindOpenGL is anything but simple. Also can't use + # OpenGL_OpenGL_FOUND, because that one is set also if GLVND is + # *not* found. WTF. Also can't just check for + # OPENGL_opengl_LIBRARY because that's set even if + # OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + if(MAGNUM_TARGET_GL) + if(CORRADE_TARGET_UNIX AND NOT CORRADE_TARGET_APPLE AND (NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)) + find_package(OpenGL) + if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) + set_property(TARGET Magnum::${_component} APPEND + PROPERTY INTERFACE_LINK_LIBRARIES OpenGL::GLX) + endif() + elseif(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES AND NOT CORRADE_TARGET_EMSCRIPTEN) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND + PROPERTY INTERFACE_LINK_LIBRARIES EGL::EGL) + endif() + endif() + + # SDL2 application dependencies + elseif(_component STREQUAL Sdl2Application) + find_package(SDL2) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES SDL2::SDL2) + # Use the Foundation framework on Apple to query the DPI awareness + if(CORRADE_TARGET_APPLE) + find_library(_MAGNUM_APPLE_FOUNDATION_FRAMEWORK_LIBRARY Foundation) + mark_as_advanced(_MAGNUM_APPLE_FOUNDATION_FRAMEWORK_LIBRARY) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${_MAGNUM_APPLE_FOUNDATION_FRAMEWORK_LIBRARY}) + # Needed for opt-in DPI queries + elseif(CORRADE_TARGET_UNIX) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}) + endif() + + # With GLVND (since CMake 3.11) we need to explicitly link to + # GLX/EGL because libOpenGL doesn't provide it. For EGL we have + # our own EGL find module, which makes things simpler. The + # upstream FindOpenGL is anything but simple. Also can't use + # OpenGL_OpenGL_FOUND, because that one is set also if GLVND is + # *not* found. WTF. Also can't just check for + # OPENGL_opengl_LIBRARY because that's set even if + # OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + if(MAGNUM_TARGET_GL) + if(CORRADE_TARGET_UNIX AND NOT CORRADE_TARGET_APPLE AND (NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)) + find_package(OpenGL) + if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) + set_property(TARGET Magnum::${_component} APPEND + PROPERTY INTERFACE_LINK_LIBRARIES OpenGL::GLX) + endif() + elseif(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES AND NOT CORRADE_TARGET_EMSCRIPTEN) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND + PROPERTY INTERFACE_LINK_LIBRARIES EGL::EGL) + endif() + endif() + + # (Windowless) GLX application dependencies + elseif(_component STREQUAL GlxApplication OR _component STREQUAL WindowlessGlxApplication) + find_package(X11) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${X11_INCLUDE_DIR}) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${X11_LIBRARIES}) + + # With GLVND (since CMake 3.11) we need to explicitly link to + # GLX because libOpenGL doesn't provide it. Also can't use + # OpenGL_OpenGL_FOUND, because that one is set also if GLVND is + # *not* found. WTF. Also can't just check for + # OPENGL_opengl_LIBRARY because that's set even if + # OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + find_package(OpenGL) + if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES OpenGL::GLX) + endif() + + # Windowless CGL application has no additional dependencies + + # Windowless EGL application dependencies + elseif(_component STREQUAL WindowlessEglApplication) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES EGL::EGL) + + # Windowless iOS application dependencies + elseif(_component STREQUAL WindowlessIosApplication) + # We need to link to Foundation framework to use ObjC + find_library(_MAGNUM_IOS_FOUNDATION_FRAMEWORK_LIBRARY Foundation) + mark_as_advanced(_MAGNUM_IOS_FOUNDATION_FRAMEWORK_LIBRARY) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES EGL::EGL ${_MAGNUM_IOS_FOUNDATION_FRAMEWORK_LIBRARY}) + + # Windowless WGL application has no additional dependencies + + # Windowless Windows/EGL application dependencies + elseif(_component STREQUAL WindowlessWindowsEglApplication) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES EGL::EGL) + + # X/EGL application dependencies + elseif(_component STREQUAL XEglApplication) + find_package(EGL) + find_package(X11) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${X11_INCLUDE_DIR}) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES EGL::EGL ${X11_LIBRARIES}) + endif() + + # Context libraries + elseif(_component MATCHES ".+Context") + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/Platform) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES GLContext.h) + + # GLX context dependencies + if(_component STREQUAL GlxContext) + # With GLVND (since CMake 3.11) we need to explicitly link to + # GLX because libOpenGL doesn't provide it. Also can't use + # OpenGL_OpenGL_FOUND, because that one is set also if GLVND is + # *not* found. If GLVND is not used, link to X11 instead. Also + # can't just check for OPENGL_opengl_LIBRARY because that's set + # even if OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + find_package(OpenGL) + if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES OpenGL::GLX) + else() + find_package(X11) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${X11_INCLUDE_DIR}) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${X11_LIBRARIES}) + endif() + + # EGL context dependencies + elseif(_component STREQUAL EglContext) + find_package(EGL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES EGL::EGL) + endif() + + # No additional dependencies for CGL context + # No additional dependencies for WGL context + + # Audio library + elseif(_component STREQUAL Audio) + find_package(OpenAL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${OPENAL_INCLUDE_DIR}) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${OPENAL_LIBRARY} Corrade::PluginManager) + + # No special setup for DebugTools library + + # GL library + elseif(_component STREQUAL GL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES ${MAGNUM_INCLUDE_DIR}/MagnumExternal/OpenGL) + + if(NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES) + # If the GLVND library (CMake 3.11+) was found, link to the + # imported target. Otherwise (and also on all systems except + # Linux) link to the classic libGL. Can't use + # OpenGL_OpenGL_FOUND, because that one is set also if GLVND is + # *not* found. WTF. Also can't just check for + # OPENGL_opengl_LIBRARY because that's set even if + # OpenGL_GL_PREFERENCE is explicitly set to LEGACY. + find_package(OpenGL REQUIRED) + if(OPENGL_opengl_LIBRARY AND OpenGL_GL_PREFERENCE STREQUAL GLVND) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES OpenGL::OpenGL) + else() + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${OPENGL_gl_LIBRARY}) + endif() + elseif(MAGNUM_TARGET_GLES2) + find_package(OpenGLES2 REQUIRED) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES OpenGLES2::OpenGLES2) + elseif(MAGNUM_TARGET_GLES3) + find_package(OpenGLES3 REQUIRED) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES OpenGLES3::OpenGLES3) + endif() + + # MeshTools library + elseif(_component STREQUAL MeshTools) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES CompressIndices.h) + + # OpenGLTester library + elseif(_component STREQUAL OpenGLTester) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/GL) + + # Primitives library + elseif(_component STREQUAL Primitives) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Cube.h) + + # No special setup for SceneGraph library + # No special setup for Shaders library + + # Text library + elseif(_component STREQUAL Text) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Corrade::PluginManager) + + # TextureTools library + elseif(_component STREQUAL TextureTools) + set(_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES Atlas.h) + + # Trade library + elseif(_component STREQUAL Trade) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Corrade::PluginManager) + + # Vk library + elseif(_component STREQUAL Vk) + set(Vulkan_INCLUDE_DIR ${MAGNUM_INCLUDE_DIR}/MagnumExternal/Vulkan) + find_package(Vulkan REQUIRED) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Vulkan::Vulkan) + endif() + + # No special setup for AnyAudioImporter plugin + # No special setup for AnyImageConverter plugin + # No special setup for AnyImageImporter plugin + # No special setup for AnySceneImporter plugin + # No special setup for MagnumFont plugin + # No special setup for MagnumFontConverter plugin + # No special setup for ObjImporter plugin + # No special setup for TgaImageConverter plugin + # No special setup for TgaImporter plugin + # No special setup for WavAudioImporter plugin + + # Find library/plugin includes + if(_component MATCHES ${_MAGNUM_LIBRARY_COMPONENTS} OR _component MATCHES ${_MAGNUM_PLUGIN_COMPONENTS}) + find_path(_MAGNUM_${_COMPONENT}_INCLUDE_DIR + NAMES ${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_NAMES} + HINTS ${MAGNUM_INCLUDE_DIR}/${_MAGNUM_${_COMPONENT}_INCLUDE_PATH_SUFFIX}) + mark_as_advanced(_MAGNUM_${_COMPONENT}_INCLUDE_DIR) + endif() + + # Automatic import of static plugins. Skip in case the include dir was + # not found -- that'll fail later with a proper message. + if(_component MATCHES ${_MAGNUM_PLUGIN_COMPONENTS} AND _MAGNUM_${_COMPONENT}_INCLUDE_DIR) + # Automatic import of static plugins + file(READ ${_MAGNUM_${_COMPONENT}_INCLUDE_DIR}/configure.h _magnum${_component}Configure) + string(FIND "${_magnum${_component}Configure}" "#define MAGNUM_${_COMPONENT}_BUILD_STATIC" _magnum${_component}_BUILD_STATIC) + if(NOT _magnum${_component}_BUILD_STATIC EQUAL -1) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_SOURCES ${_MAGNUM_${_COMPONENT}_INCLUDE_DIR}/importStaticPlugin.cpp) + endif() + endif() + + # Link to core Magnum library, add inter-library dependencies. If there + # are optional dependencies, defer adding them to later once we know if + # they were found or not. + if(_component MATCHES ${_MAGNUM_LIBRARY_COMPONENTS} OR _component MATCHES ${_MAGNUM_PLUGIN_COMPONENTS}) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::Magnum) + set(_MAGNUM_${component}_OPTIONAL_DEPENDENCIES_TO_ADD ) + foreach(_dependency ${_MAGNUM_${_component}_DEPENDENCIES}) + if(NOT _MAGNUM_${_component}_${_dependency}_DEPENDENCY_IS_OPTIONAL) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::${_dependency}) + else() + list(APPEND _MAGNUM_${_component}_OPTIONAL_DEPENDENCIES_TO_ADD + ${_dependency}) + endif() + endforeach() + if(_MAGNUM_${_component}_OPTIONAL_DEPENDENCIES_TO_ADD) + list(APPEND _MAGNUM_OPTIONAL_DEPENDENCIES_TO_ADD ${_component}) + endif() + endif() + + # Decide if the library was found + if(((_component MATCHES ${_MAGNUM_LIBRARY_COMPONENTS} OR _component MATCHES ${_MAGNUM_PLUGIN_COMPONENTS}) AND _MAGNUM_${_COMPONENT}_INCLUDE_DIR AND (MAGNUM_${_COMPONENT}_LIBRARY_DEBUG OR MAGNUM_${_COMPONENT}_LIBRARY_RELEASE)) OR (_component MATCHES ${_MAGNUM_EXECUTABLE_COMPONENTS} AND MAGNUM_${_COMPONENT}_EXECUTABLE)) + set(Magnum_${_component}_FOUND TRUE) + else() + set(Magnum_${_component}_FOUND FALSE) + endif() + endif() + + # Global aliases for Windowless*Application, *Application and *Context + # components. If already set, unset them to avoid ambiguity. + if(_component MATCHES "Windowless.+Application") + if(NOT DEFINED _MAGNUM_WINDOWLESSAPPLICATION_ALIAS) + set(_MAGNUM_WINDOWLESSAPPLICATION_ALIAS Magnum::${_component}) + else() + unset(_MAGNUM_WINDOWLESSAPPLICATION_ALIAS) + endif() + elseif(_component MATCHES ".+Application") + if(NOT DEFINED _MAGNUM_APPLICATION_ALIAS) + set(_MAGNUM_APPLICATION_ALIAS Magnum::${_component}) + else() + unset(_MAGNUM_APPLICATION_ALIAS) + endif() + elseif(_component MATCHES ".+Context") + if(NOT DEFINED _MAGNUM_GLCONTEXT_ALIAS) + set(_MAGNUM_GLCONTEXT_ALIAS Magnum::${_component}) + else() + unset(_MAGNUM_GLCONTEXT_ALIAS) + endif() + endif() +endforeach() + +# Emscripten-specific files and flags +if(CORRADE_TARGET_EMSCRIPTEN) + find_file(MAGNUM_EMSCRIPTENAPPLICATION_JS EmscriptenApplication.js + PATH_SUFFIXES share/magnum) + find_file(MAGNUM_WINDOWLESSEMSCRIPTENAPPLICATION_JS WindowlessEmscriptenApplication.js + PATH_SUFFIXES share/magnum) + find_file(MAGNUM_WEBAPPLICATION_CSS WebApplication.css + PATH_SUFFIXES share/magnum) + mark_as_advanced( + MAGNUM_EMSCRIPTENAPPLICATION_JS + MAGNUM_WINDOWLESSEMSCRIPTENAPPLICATION_JS + MAGNUM_WEBAPPLICATION_CSS) + set(MAGNUM_EXTRAS_NEEDED + MAGNUM_EMSCRIPTENAPPLICATION_JS + MAGNUM_WINDOWLESSEMSCRIPTENAPPLICATION_JS + MAGNUM_WEBAPPLICATION_CSS) + + # If we are on CMake 3.13 and up, `-s USE_WEBGL2=1` linker option is + # propagated from FindOpenGLES3.cmake already. If not (and the GL library + # is used), we need to modify the global CMAKE_EXE_LINKER_FLAGS. Do it here + # instead of in FindOpenGLES3.cmake so it works also for CMake subprojects + # (in which case find_package(OpenGLES3) is called in (and so + # CMAKE_EXE_LINKER_FLAGS would be modified in) Magnum's root CMakeLists.txt + # and thus can't affect the variable in the outer project). CMake supports + # IN_LIST as an operator since 3.1 (Emscripten needs at least 3.7), but + # it's behind a policy, so enable that one as well. + cmake_policy(SET CMP0057 NEW) + if(CMAKE_VERSION VERSION_LESS 3.13 AND GL IN_LIST Magnum_FIND_COMPONENTS AND NOT MAGNUM_TARGET_GLES2 AND NOT CMAKE_EXE_LINKER_FLAGS MATCHES "-s USE_WEBGL2=1") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_WEBGL2=1") + endif() +endif() + +# Complete the check with also all components +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Magnum + REQUIRED_VARS MAGNUM_INCLUDE_DIR MAGNUM_LIBRARY ${MAGNUM_EXTRAS_NEEDED} + HANDLE_COMPONENTS) + +# Components with optional dependencies -- add them once we know if they were +# found or not. +foreach(_component ${_MAGNUM_OPTIONAL_DEPENDENCIES_TO_ADD}) + foreach(_dependency ${_MAGNUM_${_component}_OPTIONAL_DEPENDENCIES_TO_ADD}) + if(Magnum_${_dependency}_FOUND) + set_property(TARGET Magnum::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::${_dependency}) + endif() + endforeach() +endforeach() + +# Create Windowless*Application, *Application and *Context aliases +# TODO: ugh why can't I make an alias of IMPORTED target? +if(_MAGNUM_WINDOWLESSAPPLICATION_ALIAS AND NOT TARGET Magnum::WindowlessApplication) + get_target_property(_MAGNUM_WINDOWLESSAPPLICATION_ALIASED_TARGET ${_MAGNUM_WINDOWLESSAPPLICATION_ALIAS} ALIASED_TARGET) + if(_MAGNUM_WINDOWLESSAPPLICATION_ALIASED_TARGET) + add_library(Magnum::WindowlessApplication ALIAS ${_MAGNUM_WINDOWLESSAPPLICATION_ALIASED_TARGET}) + else() + add_library(Magnum::WindowlessApplication UNKNOWN IMPORTED) + get_target_property(_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_CONFIGURATIONS ${_MAGNUM_WINDOWLESSAPPLICATION_ALIAS} IMPORTED_CONFIGURATIONS) + get_target_property(_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_LOCATION_RELEASE ${_MAGNUM_WINDOWLESSAPPLICATION_ALIAS} IMPORTED_LOCATION_RELEASE) + get_target_property(_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_LOCATION_DEBUG ${_MAGNUM_WINDOWLESSAPPLICATION_ALIAS} IMPORTED_LOCATION_DEBUG) + set_target_properties(Magnum::WindowlessApplication PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES $ + INTERFACE_COMPILE_DEFINITIONS $ + INTERFACE_COMPILE_OPTIONS $ + INTERFACE_LINK_LIBRARIES $ + IMPORTED_CONFIGURATIONS "${_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_CONFIGURATIONS}") + if(_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_LOCATION_RELEASE) + set_target_properties(Magnum::WindowlessApplication PROPERTIES + IMPORTED_LOCATION_RELEASE ${_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_LOCATION_RELEASE}) + endif() + if(_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_LOCATION_DEBUG) + set_target_properties(Magnum::WindowlessApplication PROPERTIES + IMPORTED_LOCATION_DEBUG ${_MAGNUM_WINDOWLESSAPPLICATION_IMPORTED_LOCATION_DEBUG}) + endif() + endif() + # Prevent creating the alias again + unset(_MAGNUM_WINDOWLESSAPPLICATION_ALIAS) +endif() +if(_MAGNUM_APPLICATION_ALIAS AND NOT TARGET Magnum::Application) + get_target_property(_MAGNUM_APPLICATION_ALIASED_TARGET ${_MAGNUM_APPLICATION_ALIAS} ALIASED_TARGET) + if(_MAGNUM_APPLICATION_ALIASED_TARGET) + add_library(Magnum::Application ALIAS ${_MAGNUM_APPLICATION_ALIASED_TARGET}) + else() + add_library(Magnum::Application UNKNOWN IMPORTED) + get_target_property(_MAGNUM_APPLICATION_IMPORTED_CONFIGURATIONS ${_MAGNUM_APPLICATION_ALIAS} IMPORTED_CONFIGURATIONS) + get_target_property(_MAGNUM_APPLICATION_IMPORTED_LOCATION_RELEASE ${_MAGNUM_APPLICATION_ALIAS} IMPORTED_LOCATION_RELEASE) + get_target_property(_MAGNUM_APPLICATION_IMPORTED_LOCATION_DEBUG ${_MAGNUM_APPLICATION_ALIAS} IMPORTED_LOCATION_DEBUG) + set_target_properties(Magnum::Application PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES $ + INTERFACE_COMPILE_DEFINITIONS $ + INTERFACE_COMPILE_OPTIONS $ + INTERFACE_LINK_LIBRARIES $ + IMPORTED_CONFIGURATIONS "${_MAGNUM_APPLICATION_IMPORTED_CONFIGURATIONS}") + if(_MAGNUM_APPLICATION_IMPORTED_LOCATION_RELEASE) + set_target_properties(Magnum::Application PROPERTIES + IMPORTED_LOCATION_RELEASE ${_MAGNUM_APPLICATION_IMPORTED_LOCATION_RELEASE}) + endif() + if(_MAGNUM_APPLICATION_IMPORTED_LOCATION_DEBUG) + set_target_properties(Magnum::Application PROPERTIES + IMPORTED_LOCATION_DEBUG ${_MAGNUM_APPLICATION_IMPORTED_LOCATION_DEBUG}) + endif() + endif() + # Prevent creating the alias again + unset(_MAGNUM_APPLICATION_ALIAS) +endif() +if(_MAGNUM_GLCONTEXT_ALIAS AND NOT TARGET Magnum::GLContext) + get_target_property(_MAGNUM_GLCONTEXT_ALIASED_TARGET ${_MAGNUM_GLCONTEXT_ALIAS} ALIASED_TARGET) + if(_MAGNUM_GLCONTEXT_ALIASED_TARGET) + add_library(Magnum::GLContext ALIAS ${_MAGNUM_GLCONTEXT_ALIASED_TARGET}) + else() + add_library(Magnum::GLContext UNKNOWN IMPORTED) + get_target_property(_MAGNUM_GLCONTEXT_IMPORTED_CONFIGURATIONS ${_MAGNUM_GLCONTEXT_ALIAS} IMPORTED_CONFIGURATIONS) + get_target_property(_MAGNUM_GLCONTEXT_IMPORTED_LOCATION_RELEASE ${_MAGNUM_GLCONTEXT_ALIAS} IMPORTED_LOCATION_RELEASE) + get_target_property(_MAGNUM_GLCONTEXT_IMPORTED_LOCATION_DEBUG ${_MAGNUM_GLCONTEXT_ALIAS} IMPORTED_LOCATION_DEBUG) + set_target_properties(Magnum::GLContext PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES $ + INTERFACE_COMPILE_DEFINITIONS $ + INTERFACE_COMPILE_OPTIONS $ + INTERFACE_LINK_LIBRARIES $ + IMPORTED_CONFIGURATIONS "${_MAGNUM_GLCONTEXT_IMPORTED_CONFIGURATIONS}") + if(_MAGNUM_GLCONTEXT_IMPORTED_LOCATION_RELEASE) + set_target_properties(Magnum::GLContext PROPERTIES + IMPORTED_LOCATION_RELEASE ${_MAGNUM_GLCONTEXT_IMPORTED_LOCATION_RELEASE}) + endif() + if(_MAGNUM_GLCONTEXT_IMPORTED_LOCATION_DEBUG) + set_target_properties(Magnum::GLContext PROPERTIES + IMPORTED_LOCATION_DEBUG ${_MAGNUM_GLCONTEXT_IMPORTED_LOCATION_DEBUG}) + endif() + endif() + # Prevent creating the alias again + unset(_MAGNUM_GLCONTEXT_ALIAS) +endif() + +# Installation and deploy dirs +set(MAGNUM_DEPLOY_PREFIX "." + CACHE STRING "Prefix where to put final application executables") +set(MAGNUM_INCLUDE_INSTALL_PREFIX "." + CACHE STRING "Prefix where to put platform-independent include and other files") + +include(${CORRADE_LIB_SUFFIX_MODULE}) +set(MAGNUM_BINARY_INSTALL_DIR bin) +set(MAGNUM_LIBRARY_INSTALL_DIR lib${LIB_SUFFIX}) +set(MAGNUM_DATA_INSTALL_DIR ${MAGNUM_INCLUDE_INSTALL_PREFIX}/share/magnum) +set(MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR ${MAGNUM_BINARY_INSTALL_DIR}/magnum-d) +set(MAGNUM_PLUGINS_DEBUG_LIBRARY_INSTALL_DIR ${MAGNUM_LIBRARY_INSTALL_DIR}/magnum-d) +set(MAGNUM_PLUGINS_RELEASE_BINARY_INSTALL_DIR ${MAGNUM_BINARY_INSTALL_DIR}/magnum) +set(MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_LIBRARY_INSTALL_DIR}/magnum) +set(MAGNUM_PLUGINS_FONT_DEBUG_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR}/fonts) +set(MAGNUM_PLUGINS_FONT_DEBUG_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_LIBRARY_INSTALL_DIR}/fonts) +set(MAGNUM_PLUGINS_FONT_RELEASE_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_BINARY_INSTALL_DIR}/fonts) +set(MAGNUM_PLUGINS_FONT_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR}/fonts) +set(MAGNUM_PLUGINS_FONTCONVERTER_DEBUG_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR}/fontconverters) +set(MAGNUM_PLUGINS_FONTCONVERTER_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR}/fontconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_DEBUG_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_DEBUG_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_LIBRARY_INSTALL_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_RELEASE_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_BINARY_INSTALL_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMPORTER_DEBUG_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR}/importers) +set(MAGNUM_PLUGINS_IMPORTER_DEBUG_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_LIBRARY_INSTALL_DIR}/importers) +set(MAGNUM_PLUGINS_IMPORTER_RELEASE_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_BINARY_INSTALL_DIR}/importers) +set(MAGNUM_PLUGINS_IMPORTER_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR}/importers) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_DEBUG_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_BINARY_INSTALL_DIR}/audioimporters) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_DEBUG_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_DEBUG_LIBRARY_INSTALL_DIR}/audioimporters) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_BINARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_BINARY_INSTALL_DIR}/audioimporters) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_LIBRARY_INSTALL_DIR ${MAGNUM_PLUGINS_RELEASE_LIBRARY_INSTALL_DIR}/audioimporters) +set(MAGNUM_INCLUDE_INSTALL_DIR ${MAGNUM_INCLUDE_INSTALL_PREFIX}/include/Magnum) +set(MAGNUM_EXTERNAL_INCLUDE_INSTALL_DIR ${MAGNUM_INCLUDE_INSTALL_PREFIX}/include/MagnumExternal) +set(MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR ${MAGNUM_INCLUDE_INSTALL_PREFIX}/include/MagnumPlugins) + +# Get base plugin directory from main library location. This is *not* PATH, +# because CMake always converts the path to an absolute location internally, +# making it impossible to specify relative paths there. Sorry in advance for +# not having the dir selection button in CMake GUI. +set(MAGNUM_PLUGINS_DEBUG_DIR ${_MAGNUM_PLUGINS_DIR_PREFIX}/magnum-d + CACHE STRING "Base directory where to look for Magnum plugins for debug builds") +set(MAGNUM_PLUGINS_RELEASE_DIR ${_MAGNUM_PLUGINS_DIR_PREFIX}/magnum + CACHE STRING "Base directory where to look for Magnum plugins for release builds") +set(MAGNUM_PLUGINS_DIR ${_MAGNUM_PLUGINS_DIR_PREFIX}/magnum${_MAGNUM_PLUGINS_DIR_SUFFIX} + CACHE STRING "Base directory where to look for Magnum plugins") + +# Plugin directories +set(MAGNUM_PLUGINS_FONT_DIR ${MAGNUM_PLUGINS_DIR}/fonts) +set(MAGNUM_PLUGINS_FONT_DEBUG_DIR ${MAGNUM_PLUGINS_DEBUG_DIR}/fonts) +set(MAGNUM_PLUGINS_FONT_RELEASE_DIR ${MAGNUM_PLUGINS_RELEASE_DIR}/fonts) +set(MAGNUM_PLUGINS_FONTCONVERTER_DIR ${MAGNUM_PLUGINS_DIR}/fontconverters) +set(MAGNUM_PLUGINS_FONTCONVERTER_DEBUG_DIR ${MAGNUM_PLUGINS_DEBUG_DIR}/fontconverters) +set(MAGNUM_PLUGINS_FONTCONVERTER_RELEASE_DIR ${MAGNUM_PLUGINS_RELEASE_DIR}/fontconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_DIR ${MAGNUM_PLUGINS_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_DEBUG_DIR ${MAGNUM_PLUGINS_DEBUG_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMAGECONVERTER_RELEASE_DIR ${MAGNUM_PLUGINS_RELEASE_DIR}/imageconverters) +set(MAGNUM_PLUGINS_IMPORTER_DIR ${MAGNUM_PLUGINS_DIR}/importers) +set(MAGNUM_PLUGINS_IMPORTER_DEBUG_DIR ${MAGNUM_PLUGINS_DEBUG_DIR}/importers) +set(MAGNUM_PLUGINS_IMPORTER_RELEASE_DIR ${MAGNUM_PLUGINS_RELEASE_DIR}/importers) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_DIR ${MAGNUM_PLUGINS_DIR}/audioimporters) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_DEBUG_DIR ${MAGNUM_PLUGINS_DEBUG_DIR}/audioimporters) +set(MAGNUM_PLUGINS_AUDIOIMPORTER_RELEASE_DIR ${MAGNUM_PLUGINS_RELEASE_DIR}/audioimporters) diff --git a/src/cmake/FindMagnumPlugins.cmake b/src/cmake/FindMagnumPlugins.cmake new file mode 100644 index 0000000000..c78825eced --- /dev/null +++ b/src/cmake/FindMagnumPlugins.cmake @@ -0,0 +1,435 @@ +#.rst: +# Find Magnum plugins +# ------------------- +# +# Finds the Magnum plugins library. Basic usage:: +# +# find_package(MagnumPlugins REQUIRED) +# +# This command tries to find Magnum plugins and then defines the following: +# +# MagnumPlugins_FOUND - Whether Magnum plugins were found +# +# This command will not try to find any actual plugin. The plugins are: +# +# AssimpImporter - Assimp importer +# DdsImporter - DDS importer +# DevIlImageImporter - Image importer using DevIL +# DrFlacAudioImporter - FLAC audio importer using dr_flac +# DrWavAudioImporter - WAV audio importer using dr_wav +# Faad2AudioImporter - AAC audio importer using FAAD2 +# FreeTypeFont - FreeType font +# HarfBuzzFont - HarfBuzz font +# JpegImageConverter - JPEG image converter +# JpegImporter - JPEG importer +# MiniExrImageConverter - OpenEXR image converter using miniexr +# OpenGexImporter - OpenGEX importer +# PngImageConverter - PNG image converter +# PngImporter - PNG importer +# StanfordImporter - Stanford PLY importer +# StbImageConverter - Image converter using stb_image_write +# StbImageImporter - Image importer using stb_image +# StbTrueTypeFont - TrueType font using stb_truetype +# StbVorbisAudioImporter - OGG audio importer using stb_vorbis +# TinyGltfImporter - GLTF importer using tiny_gltf +# +# Some plugins expose their internal state through separate libraries. The +# libraries are: +# +# OpenDdl - OpenDDL parser, used as a base for the +# OpenGexImporter plugin +# +# Example usage with specifying the plugins is:: +# +# find_package(MagnumPlugins REQUIRED FreeTypeFont PngImporter) +# +# For each plugin is then defined: +# +# MagnumPlugins_*_FOUND - Whether the plugin was found +# MagnumPlugins::* - Plugin imported target +# +# The package is found if either debug or release version of each requested +# plugin is found. If both debug and release plugins are found, proper version +# is chosen based on actual build configuration of the project (i.e. ``Debug`` +# build is linked to debug plugins, ``Release`` build to release plugins). See +# ``FindMagnum.cmake`` for more information about autodetection of +# ``MAGNUM_PLUGINS_DIR``. +# +# Additionally these variables are defined for internal usage: +# +# MAGNUMPLUGINS_INCLUDE_DIR - Magnum plugins include dir (w/o dependencies) +# MAGNUMPLUGINS_*_LIBRARY - Plugin library (w/o dependencies) +# MAGNUMPLUGINS_*_LIBRARY_DEBUG - Debug version of given library, if found +# MAGNUMPLUGINS_*_LIBRARY_RELEASE - Release version of given library, if found +# + +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 +# Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +# Magnum library dependencies +set(_MAGNUMPLUGINS_DEPENDENCIES ) +foreach(_component ${MagnumPlugins_FIND_COMPONENTS}) + if(_component MATCHES ".+AudioImporter$") + set(_MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES Audio) + elseif(_component MATCHES ".+(Importer|ImageConverter)") + set(_MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES Trade) + elseif(_component MATCHES ".+(Font|FontConverter)$") + set(_MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES Text) + endif() + + if(_component STREQUAL AssimpImporter) + list(APPEND _MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES AnyImageImporter) + elseif(_component STREQUAL OpenGexImporter) + list(APPEND _MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES AnyImageImporter) + elseif(_component STREQUAL TinyGltfImporter) + list(APPEND _MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES AnyImageImporter) + endif() + + list(APPEND _MAGNUMPLUGINS_DEPENDENCIES ${_MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES}) +endforeach() +find_package(Magnum REQUIRED ${_MAGNUMPLUGINS_DEPENDENCIES}) + +# Global plugin include dir +find_path(MAGNUMPLUGINS_INCLUDE_DIR MagnumPlugins + HINTS ${MAGNUM_INCLUDE_DIR}) +mark_as_advanced(MAGNUMPLUGINS_INCLUDE_DIR) + +# Component distinction (listing them explicitly to avoid mistakes with finding +# components from other repositories) +set(_MAGNUMPLUGINS_LIBRARY_COMPONENT_LIST OpenDdl) +set(_MAGNUMPLUGINS_PLUGIN_COMPONENT_LIST + AssimpImporter DdsImporter DevIlImageImporter + DrFlacAudioImporter DrWavAudioImporter Faad2AudioImporter FreeTypeFont + HarfBuzzFont JpegImageConverter JpegImporter MiniExrImageConverter + OpenGexImporter PngImageConverter PngImporter StanfordImporter + StbImageConverter StbImageImporter StbTrueTypeFont StbVorbisAudioImporter + TinyGltfImporter) + +# Inter-component dependencies +set(_MAGNUMPLUGINS_HarfBuzzFont_DEPENDENCIES FreeTypeFont) +set(_MAGNUMPLUGINS_OpenGexImporter_DEPENDENCIES OpenDdl) + +# Ensure that all inter-component dependencies are specified as well +set(_MAGNUMPLUGINS_ADDITIONAL_COMPONENTS ) +foreach(_component ${MagnumPlugins_FIND_COMPONENTS}) + # Mark the dependencies as required if the component is also required + if(MagnumPlugins_FIND_REQUIRED_${_component}) + foreach(_dependency ${_MAGNUMPLUGINS_${_component}_DEPENDENCIES}) + set(MagnumPlugins_FIND_REQUIRED_${_dependency} TRUE) + endforeach() + endif() + + list(APPEND _MAGNUMPLUGINS_ADDITIONAL_COMPONENTS ${_MAGNUMPLUGINS_${_component}_DEPENDENCIES}) +endforeach() + +# Join the lists, remove duplicate components +if(_MAGNUMPLUGINS_ADDITIONAL_COMPONENTS) + list(INSERT MagnumPlugins_FIND_COMPONENTS 0 ${_MAGNUMPLUGINS_ADDITIONAL_COMPONENTS}) +endif() +if(MagnumPlugins_FIND_COMPONENTS) + list(REMOVE_DUPLICATES MagnumPlugins_FIND_COMPONENTS) +endif() + +# Convert components lists to regular expressions so I can use if(MATCHES). +# TODO: Drop this once CMake 3.3 and if(IN_LIST) can be used +foreach(_WHAT LIBRARY PLUGIN) + string(REPLACE ";" "|" _MAGNUMPLUGINS_${_WHAT}_COMPONENTS "${_MAGNUMPLUGINS_${_WHAT}_COMPONENT_LIST}") + set(_MAGNUMPLUGINS_${_WHAT}_COMPONENTS "^(${_MAGNUMPLUGINS_${_WHAT}_COMPONENTS})$") +endforeach() + +# Find all components +foreach(_component ${MagnumPlugins_FIND_COMPONENTS}) + string(TOUPPER ${_component} _COMPONENT) + + # Create imported target in case the library is found. If the project is + # added as subproject to CMake, the target already exists and all the + # required setup is already done from the build tree. + if(TARGET MagnumPlugins::${_component}) + set(MagnumPlugins_${_component}_FOUND TRUE) + else() + # Library components + if(_component MATCHES ${_MAGNUMPLUGINS_LIBRARY_COMPONENTS}) + add_library(MagnumPlugins::${_component} UNKNOWN IMPORTED) + + # Set library defaults, find the library + set(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_SUFFIX Magnum/${_component}) + set(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}.h) + + # Try to find both debug and release version + find_library(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG Magnum${_component}-d) + find_library(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE Magnum${_component}) + mark_as_advanced(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG + MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE) + endif() + + # Plugin components + if(_component MATCHES ${_MAGNUMPLUGINS_PLUGIN_COMPONENTS}) + add_library(MagnumPlugins::${_component} UNKNOWN IMPORTED) + + # AudioImporter plugin specific name suffixes + if(_component MATCHES ".+AudioImporter$") + set(_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX audioimporters) + + # Audio importer class is Audio::*Importer, thus we need to + # convert *AudioImporter.h to *Importer.h + string(REPLACE "AudioImporter" "Importer" _MAGNUMPLUGINS_${_COMPONENT}_HEADER_NAME "${_component}") + set(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_NAMES ${_MAGNUMPLUGINS_${_COMPONENT}_HEADER_NAME}.h) + + # Importer plugin specific name suffixes + elseif(_component MATCHES ".+Importer$") + set(_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX importers) + + # Font plugin specific name suffixes + elseif(_component MATCHES ".+Font$") + set(_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX fonts) + + # ImageConverter plugin specific name suffixes + elseif(_component MATCHES ".+ImageConverter$") + set(_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX imageconverters) + + # FontConverter plugin specific name suffixes + elseif(_component MATCHES ".+FontConverter$") + set(_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX fontconverters) + endif() + + # Don't override the exception for *AudioImporter plugins + set(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_SUFFIX MagnumPlugins/${_component}) + if(NOT _MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_NAMES) + set(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_NAMES ${_component}.h) + endif() + + # Dynamic plugins don't have any prefix (e.g. `lib` on Linux), + # search with empty prefix and then reset that back so we don't + # accidentaly break something else + set(_tmp_prefixes "${CMAKE_FIND_LIBRARY_PREFIXES}") + set(CMAKE_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES};") + + # Try to find both debug and release version. Dynamic and static + # debug libraries are in different places. Static debug plugins are + # in magnum/ with a -d suffix while dynamic debug plugins are in + # magnum-d/ with no suffix. Problem is that Vcpkg's library linking + # automagic needs the static libs to be in the root library + # directory along with everything else and so we need to search for + # the -d suffixed version *before* the unsuffixed so it doesn't + # pick the release library for both debug and release. + find_library(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG ${_component}-d + PATH_SUFFIXES magnum/${_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX}) + find_library(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG ${_component} + PATH_SUFFIXES magnum-d/${_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX}) + find_library(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE ${_component} + PATH_SUFFIXES magnum/${_MAGNUMPLUGINS_${_COMPONENT}_PATH_SUFFIX}) + mark_as_advanced(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG + MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE) + + # Reset back + set(CMAKE_FIND_LIBRARY_PREFIXES "${_tmp_prefixes}") + endif() + + # Library location for plugins/libraries + if(_component MATCHES ${_MAGNUMPLUGINS_PLUGIN_COMPONENTS} OR _component MATCHES ${_MAGNUMPLUGINS_LIBRARY_COMPONENTS}) + if(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_property(TARGET MagnumPlugins::${_component} PROPERTY + IMPORTED_LOCATION_RELEASE ${MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE}) + endif() + + if(MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_property(TARGET MagnumPlugins::${_component} PROPERTY + IMPORTED_LOCATION_DEBUG ${MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG}) + endif() + endif() + + # AssimpImporter plugin dependencies + if(_component STREQUAL AssimpImporter) + find_package(Assimp) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Assimp::Assimp) + + # DdsImporter has no dependencies + + # DevIlImageImporter plugin dependencies + elseif(_component STREQUAL DevIlImageImporter) + find_package(DevIL) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${IL_LIBRARIES} ${ILU_LIBRARIES}) + + # DrFlacAudioImporter has no dependencies + # DrWavAudioImporter has no dependencies + + # Faad2AudioImporter plugin dependencies + elseif(_component STREQUAL Faad2AudioImporter) + find_package(FAAD2) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES FAAD2::FAAD2) + + # FreeTypeFont plugin dependencies + elseif(_component STREQUAL FreeTypeFont) + find_package(Freetype) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # FREETYPE_LIBRARIES), thus appending them one by one + if(FREETYPE_LIBRARY_DEBUG AND FREETYPE_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${FREETYPE_LIBRARY_RELEASE}>;$<$:${FREETYPE_LIBRARY_DEBUG}>") + else() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${FREETYPE_LIBRARIES}) + endif() + + # HarfBuzzFont plugin dependencies + elseif(_component STREQUAL HarfBuzzFont) + find_package(Freetype) + find_package(HarfBuzz) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # FREETYPE_LIBRARIES), thus appending them one by one + if(FREETYPE_LIBRARY_DEBUG AND FREETYPE_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${FREETYPE_LIBRARY_RELEASE}>;$<$:${FREETYPE_LIBRARY_DEBUG}>") + else() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${FREETYPE_LIBRARIES}) + endif() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES HarfBuzz::HarfBuzz) + + # JpegImageConverter plugin dependencies + elseif(_component STREQUAL JpegImageConverter) + find_package(JPEG) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # JPEG_LIBRARIES), thus appending them one by one + if(JPEG_LIBRARY_DEBUG AND JPEG_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${JPEG_LIBRARY_RELEASE}>;$<$:${JPEG_LIBRARY_DEBUG}>") + else() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${JPEG_LIBRARIES}) + endif() + + # JpegImporter plugin dependencies + elseif(_component STREQUAL JpegImporter) + find_package(JPEG) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # JPEG_LIBRARIES), thus appending them one by one + if(JPEG_LIBRARY_DEBUG AND JPEG_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${JPEG_LIBRARY_RELEASE}>;$<$:${JPEG_LIBRARY_DEBUG}>") + else() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${JPEG_LIBRARIES}) + endif() + + # MiniExrImageConverter has no dependencies + # No special setup for the OpenDdl library + # OpenGexImporter has no dependencies + + # PngImageConverter plugin dependencies + elseif(_component STREQUAL PngImageConverter) + find_package(PNG) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # PNG_LIBRARIES), thus appending them one by one + if(PNG_LIBRARY_DEBUG AND PNG_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${PNG_LIBRARY_RELEASE}>;$<$:${PNG_LIBRARY_DEBUG}>") + else() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${PNG_LIBRARIES}) + endif() + + # PngImporter plugin dependencies + elseif(_component STREQUAL PngImporter) + find_package(PNG) + # Need to handle special cases where both debug and release + # libraries are available (in form of debug;A;optimized;B in + # PNG_LIBRARIES), thus appending them one by one + if(PNG_LIBRARY_DEBUG AND PNG_LIBRARY_RELEASE) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES "$<$>:${PNG_LIBRARY_RELEASE}>;$<$:${PNG_LIBRARY_DEBUG}>") + else() + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES ${PNG_LIBRARIES}) + endif() + endif() + + # StanfordImporter has no dependencies + # StbImageConverter has no dependencies + # StbImageImporter has no dependencies + # StbTrueTypeFont has no dependencies + # StbVorbisAudioImporter has no dependencies + # TinyGltfImporter has no dependencies + + # Find plugin/library includes + if(_component MATCHES ${_MAGNUMPLUGINS_PLUGIN_COMPONENTS} OR _component MATCHES ${_MAGNUMPLUGINS_LIBRARY_COMPONENTS}) + find_path(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_DIR + NAMES ${_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_NAMES} + HINTS ${MAGNUMPLUGINS_INCLUDE_DIR}/${_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_PATH_SUFFIX}) + mark_as_advanced(_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_DIR) + endif() + + # Automatic import of static plugins + if(_component MATCHES ${_MAGNUMPLUGINS_PLUGIN_COMPONENTS}) + file(READ ${_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_DIR}/configure.h _magnumPlugins${_component}Configure) + string(FIND "${_magnumPlugins${_component}Configure}" "#define MAGNUM_${_COMPONENT}_BUILD_STATIC" _magnumPlugins${_component}_BUILD_STATIC) + if(NOT _magnumPlugins${_component}_BUILD_STATIC EQUAL -1) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_SOURCES ${_MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_DIR}/importStaticPlugin.cpp) + endif() + endif() + + if(_component MATCHES ${_MAGNUMPLUGINS_PLUGIN_COMPONENTS} OR _component MATCHES ${_MAGNUMPLUGINS_LIBRARY_COMPONENTS}) + # Link to core Magnum library, add other Magnum dependencies + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::Magnum) + foreach(_dependency ${_MAGNUMPLUGINS_${_component}_MAGNUM_DEPENDENCIES}) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES Magnum::${_dependency}) + endforeach() + + # Add inter-project dependencies + foreach(_dependency ${_MAGNUMPLUGINS_${_component}_DEPENDENCIES}) + set_property(TARGET MagnumPlugins::${_component} APPEND PROPERTY + INTERFACE_LINK_LIBRARIES MagnumPlugins::${_dependency}) + endforeach() + endif() + + # Decide if the plugin/library was found + if((_component MATCHES ${_MAGNUMPLUGINS_PLUGIN_COMPONENTS} OR _component MATCHES ${_MAGNUMPLUGINS_LIBRARY_COMPONENTS}) AND _MAGNUMPLUGINS_${_COMPONENT}_INCLUDE_DIR AND (MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_DEBUG OR MAGNUMPLUGINS_${_COMPONENT}_LIBRARY_RELEASE)) + set(MagnumPlugins_${_component}_FOUND TRUE) + else() + set(MagnumPlugins_${_component}_FOUND FALSE) + endif() + endif() +endforeach() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MagnumPlugins + REQUIRED_VARS MAGNUMPLUGINS_INCLUDE_DIR + HANDLE_COMPONENTS) diff --git a/src/cmake/dependencies.cmake b/src/cmake/dependencies.cmake index 709923bbcd..3f0778a8af 100644 --- a/src/cmake/dependencies.cmake +++ b/src/cmake/dependencies.cmake @@ -7,12 +7,18 @@ set(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/../deps") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}") find_package(OpenMP) -find_package(OpenGL REQUIRED) +# We don't find_package(OpenGL REQUIRED) here, but let Magnum do that instead +# as it sets up various things related to GLVND. include_directories("deps") -# eigen3 -include_directories(SYSTEM "${DEPS_DIR}/eigen-git-mirror") +# Eigen. Use a system package, if preferred. +if(USE_SYSTEM_EIGEN) + find_package(Eigen3 REQUIRED) + include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR}) +else() + include_directories(SYSTEM "${DEPS_DIR}/eigen-git-mirror") +endif() # sophus include_directories(SYSTEM "${DEPS_DIR}/Sophus") @@ -23,20 +29,28 @@ add_subdirectory("${DEPS_DIR}/glog") # tinyobjloader include_directories(SYSTEM "${DEPS_DIR}/tinyobjloader") -# rapidjson -include_directories(SYSTEM "${DEPS_DIR}/rapidjson/include") +# RapidJSON. Use a system package, if preferred. +if(USE_SYSTEM_RAPIDJSON) + find_package(RapidJSON CONFIG REQUIRED) + include_directories(SYSTEM ${RapidJSON_INCLUDE_DIR}) +else() + include_directories(SYSTEM "${DEPS_DIR}/rapidjson/include") +endif() # Why all the weird options in the set() calls below? # See https://stackoverflow.com/questions/3766740/overriding-a-default-option-value-in-cmake-from-a-parent-cmakelists-txt -# assimp -set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "ASSIMP_BUILD_ASSIMP_TOOLS" FORCE) -set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "ASSIMP_BUILD_TESTS" FORCE) -set(BUILD_SHARED_LIBS OFF CACHE BOOL "ASSIMP_BUILD_TESTS" FORCE) -add_subdirectory("${DEPS_DIR}/assimp") -# find_package(ASSIMP REQUIRED) -include_directories(SYSTEM "${DEPS_DIR}/assimp/include") -# message(STATUS "Found ASSIMP in ${ASSIMP_INCLUDE_DIR}") +# Assimp. Use a system package, if preferred. +if(USE_SYSTEM_ASSIMP) + find_package(ASSIMP REQUIRED) +else() + set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "ASSIMP_BUILD_ASSIMP_TOOLS" FORCE) + set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "ASSIMP_BUILD_TESTS" FORCE) + set(BUILD_SHARED_LIBS OFF CACHE BOOL "ASSIMP_BUILD_TESTS" FORCE) + add_subdirectory("${DEPS_DIR}/assimp") + include_directories(SYSTEM "${DEPS_DIR}/assimp/include") + # message(STATUS "Found ASSIMP in ${ASSIMP_INCLUDE_DIR}") +endif() # recast set(RECASTNAVIGATION_DEMO OFF CACHE BOOL "RECASTNAVIGATION_DEMO" FORCE) @@ -51,42 +65,42 @@ target_compile_definitions(Detour DT_VIRTUAL_QUERYFILTER) -# magnum -set(BUILD_PLUGINS_STATIC ON CACHE BOOL "BUILD_PLUGINS_STATIC" FORCE) -set(BUILD_STATIC ON CACHE BOOL "BUILD_STATIC" FORCE) -set(BUILD_STATIC_PIC ON CACHE BOOL "BUILD_STATIC_PIC" FORCE) -set(WITH_TRADE ON CACHE BOOL "WITH_TRADE" FORCE) -set(WITH_ANYSCENEIMPORTER ON CACHE BOOL "WITH_ANYSCENEIMPORTER" FORCE) -set(WITH_ASSIMPIMPORTER OFF CACHE BOOL "WITH_ASSIMPIMPORTER" FORCE) -set(WITH_TINYGLTFIMPORTER ON CACHE BOOL "WITH_TINYGLTFIMPORTER" FORCE) -set(WITH_ANYIMAGEIMPORTER ON CACHE BOOL "WITH_ANYIMAGEIMPORTER" FORCE) -set(WITH_STBIMAGEIMPORTER ON CACHE BOOL "WITH_STBIMAGEIMPORTER" FORCE) -set(WITH_STBIMAGECONVERTER ON CACHE BOOL "WITH_STBIMAGECONVERTER" FORCE) -set(WITH_SDL2APPLICATION OFF CACHE BOOL "WITH_SDL2APPLICATION" FORCE) -if(${BUILD_GUI_VIEWERS}) - add_subdirectory("${DEPS_DIR}/glfw") - set(WITH_GLFWAPPLICATION ON CACHE BOOL "WITH_GLFWAPPLICATION" FORCE) -else() - set(WITH_GLFWAPPLICATION OFF CACHE BOOL "WITH_GLFWAPPLICATION" FORCE) -endif() -if(APPLE) - set(WITH_WINDOWLESSCGLAPPLICATION ON CACHE BOOL "WITH_WINDOWLESSCGLAPPLICATION" FORCE) -elseif(WIN32) - set(WITH_WINDOWLESSWGLAPPLICATION ON CACHE BOOL "WITH_WINDOWLESSWGLAPPLICATION" FORCE) -elseif(UNIX) +# Magnum. Use a system package, if preferred. +if(NOT USE_SYSTEM_MAGNUM) + set(BUILD_PLUGINS_STATIC ON CACHE BOOL "BUILD_PLUGINS_STATIC" FORCE) + set(BUILD_STATIC ON CACHE BOOL "BUILD_STATIC" FORCE) + set(BUILD_STATIC_PIC ON CACHE BOOL "BUILD_STATIC_PIC" FORCE) + set(WITH_TRADE ON CACHE BOOL "WITH_TRADE" FORCE) + set(WITH_ANYSCENEIMPORTER ON CACHE BOOL "WITH_ANYSCENEIMPORTER" FORCE) + set(WITH_ASSIMPIMPORTER OFF CACHE BOOL "WITH_ASSIMPIMPORTER" FORCE) + set(WITH_TINYGLTFIMPORTER ON CACHE BOOL "WITH_TINYGLTFIMPORTER" FORCE) + set(WITH_ANYIMAGEIMPORTER ON CACHE BOOL "WITH_ANYIMAGEIMPORTER" FORCE) + set(WITH_STBIMAGEIMPORTER ON CACHE BOOL "WITH_STBIMAGEIMPORTER" FORCE) + set(WITH_STBIMAGECONVERTER ON CACHE BOOL "WITH_STBIMAGECONVERTER" FORCE) + set(WITH_SDL2APPLICATION OFF CACHE BOOL "WITH_SDL2APPLICATION" FORCE) if(${BUILD_GUI_VIEWERS}) - set(WITH_WINDOWLESSGLXAPPLICATION ON CACHE INTERNAL "WITH_WINDOWLESSGLXAPPLICATION" FORCE) - set(WITH_WINDOWLESSEGLAPPLICATION OFF CACHE INTERNAL "WITH_WINDOWLESSEGLAPPLICATION" FORCE) + add_subdirectory("${DEPS_DIR}/glfw") + set(WITH_GLFWAPPLICATION ON CACHE BOOL "WITH_GLFWAPPLICATION" FORCE) else() - set(WITH_WINDOWLESSGLXAPPLICATION OFF CACHE INTERNAL "WITH_WINDOWLESSGLXAPPLICATION" FORCE) - set(WITH_WINDOWLESSEGLAPPLICATION ON CACHE INTERNAL "WITH_WINDOWLESSEGLAPPLICATION" FORCE) + set(WITH_GLFWAPPLICATION OFF CACHE BOOL "WITH_GLFWAPPLICATION" FORCE) + endif() + if(APPLE) + set(WITH_WINDOWLESSCGLAPPLICATION ON CACHE BOOL "WITH_WINDOWLESSCGLAPPLICATION" FORCE) + elseif(WIN32) + set(WITH_WINDOWLESSWGLAPPLICATION ON CACHE BOOL "WITH_WINDOWLESSWGLAPPLICATION" FORCE) + elseif(UNIX) + if(${BUILD_GUI_VIEWERS}) + set(WITH_WINDOWLESSGLXAPPLICATION ON CACHE INTERNAL "WITH_WINDOWLESSGLXAPPLICATION" FORCE) + set(WITH_WINDOWLESSEGLAPPLICATION OFF CACHE INTERNAL "WITH_WINDOWLESSEGLAPPLICATION" FORCE) + else() + set(WITH_WINDOWLESSGLXAPPLICATION OFF CACHE INTERNAL "WITH_WINDOWLESSGLXAPPLICATION" FORCE) + set(WITH_WINDOWLESSEGLAPPLICATION ON CACHE INTERNAL "WITH_WINDOWLESSEGLAPPLICATION" FORCE) + endif() endif() + add_subdirectory("${DEPS_DIR}/corrade") + add_subdirectory("${DEPS_DIR}/magnum") + add_subdirectory("${DEPS_DIR}/magnum-plugins") endif() -add_subdirectory("${DEPS_DIR}/corrade") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${DEPS_DIR}/magnum/modules/") -add_subdirectory("${DEPS_DIR}/magnum") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${DEPS_DIR}/magnum-plugins/modules/") -add_subdirectory("${DEPS_DIR}/magnum-plugins") # python interpreter find_package(PythonInterp 3.6 REQUIRED) @@ -100,9 +114,12 @@ find_program(PYTHON_EXECUTABLE ) message(STATUS "Bindings being generated for python at ${PYTHON_EXECUTABLE}") -# pybind11 -add_subdirectory("${DEPS_DIR}/pybind11") -# find_package(pybind11 REQUIRED) +# Pybind11. Use a system package, if preferred. +if(USE_SYSTEM_PYBIND11) + find_package(pybind11 REQUIRED) +else() + add_subdirectory("${DEPS_DIR}/pybind11") +endif() # tinyply include_directories(SYSTEM "${DEPS_DIR}/tinyply/source") diff --git a/src/esp/bindings/OpaqueTypes.h b/src/esp/bindings/OpaqueTypes.h index 2be44f2d79..03b4e5cc68 100644 --- a/src/esp/bindings/OpaqueTypes.h +++ b/src/esp/bindings/OpaqueTypes.h @@ -15,6 +15,10 @@ #include "esp/core/esp.h" #include "esp/nav/ActionSpacePath.h" -PYBIND11_MAKE_OPAQUE(std::map); +// Support for types with commas is implemented since +// https://github.com/pybind/pybind11/commit/e88656ab45ae75df7dcb1fcdd2c89805b52e4665, +// which is not in any released version yet. Use a typedef until then. +typedef std::map map_string_string; +PYBIND11_MAKE_OPAQUE(map_string_string); PYBIND11_MAKE_OPAQUE(std::vector); diff --git a/src/esp/gfx/CMakeLists.txt b/src/esp/gfx/CMakeLists.txt index 2baa086989..11ca7a8b91 100644 --- a/src/esp/gfx/CMakeLists.txt +++ b/src/esp/gfx/CMakeLists.txt @@ -62,7 +62,8 @@ target_link_libraries(gfx # Link windowed application library if needed if(${BUILD_GUI_VIEWERS}) - target_link_libraries(gfx PUBLIC Magnum::Application) + find_package(Magnum REQUIRED GlfwApplication) + target_link_libraries(gfx PUBLIC Magnum::GlfwApplication) elseif(UNIX) target_compile_definitions(gfx PRIVATE __ESP_USE_EGL__) endif() diff --git a/src/esp/nav/PathFinder.h b/src/esp/nav/PathFinder.h index 6493a174e7..3747ecd58c 100644 --- a/src/esp/nav/PathFinder.h +++ b/src/esp/nav/PathFinder.h @@ -29,7 +29,7 @@ struct HitRecord { }; namespace impl { -class ActionSpaceGraph; +struct ActionSpaceGraph; class IslandSystem; } // namespace impl