875 lines
44 KiB
CMake
875 lines
44 KiB
CMake
|
|
# (the blank line is here so CMake doesn't generate documentation from it)
|
|
|
|
#
|
|
# This file is part of Corrade.
|
|
#
|
|
# Copyright © 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
|
|
# 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026
|
|
# Vladimír Vondruš <mosra@centrum.cz>
|
|
#
|
|
# 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.
|
|
#
|
|
|
|
# Already included, nothing to do
|
|
if(_CORRADE_USE_INCLUDED)
|
|
return()
|
|
endif()
|
|
|
|
# Compiler identification. Unlike other CORRADE_TARGET_* variables it's not
|
|
# saved/restored from configure.h as the compiler used to compile Corrade may
|
|
# differ from the compiler used to link to it.
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
set(CORRADE_TARGET_GCC 1)
|
|
endif()
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
set(CORRADE_TARGET_CLANG 1)
|
|
if(CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
|
|
set(CORRADE_TARGET_CLANG_CL 1)
|
|
set(CORRADE_TARGET_MSVC 1)
|
|
else()
|
|
set(CORRADE_TARGET_GCC 1)
|
|
endif()
|
|
endif()
|
|
# With older Emscripten (or CMake?) versions the compiler is detected as
|
|
# "unknown" instead of Clang. Force the compiler resolution in that case.
|
|
# TODO: figure out why
|
|
if(CORRADE_TARGET_EMSCRIPTEN)
|
|
set(CORRADE_TARGET_GCC 1)
|
|
set(CORRADE_TARGET_CLANG 1)
|
|
endif()
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
|
set(CORRADE_TARGET_GCC 1)
|
|
set(CORRADE_TARGET_CLANG 1)
|
|
set(CORRADE_TARGET_APPLE_CLANG 1)
|
|
endif()
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
set(CORRADE_TARGET_MSVC 1)
|
|
endif()
|
|
if(MINGW)
|
|
set(CORRADE_TARGET_MINGW 1)
|
|
endif()
|
|
|
|
# Check compiler version
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
# Don't allow to use compilers older than what compatibility mode allows
|
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.1")
|
|
message(FATAL_ERROR "Corrade cannot be used with GCC < 4.8.1. Sorry.")
|
|
endif()
|
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|
# Don't allow to use compilers older than what compatibility mode allows
|
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0")
|
|
message(FATAL_ERROR "Corrade cannot be used with MSVC < 2015. Sorry.")
|
|
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")
|
|
if(NOT CORRADE_MSVC2015_COMPATIBILITY)
|
|
message(FATAL_ERROR "To use Corrade with MSVC 2015, build it with CORRADE_MSVC2015_COMPATIBILITY enabled")
|
|
endif()
|
|
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.20")
|
|
if(NOT CORRADE_MSVC2017_COMPATIBILITY)
|
|
message(FATAL_ERROR "To use Corrade with MSVC 2017, build it with CORRADE_MSVC2017_COMPATIBILITY enabled")
|
|
endif()
|
|
endif()
|
|
|
|
# Don't allow to use compiler newer than what compatibility mode allows
|
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")
|
|
if(CORRADE_MSVC2015_COMPATIBILITY)
|
|
message(FATAL_ERROR "MSVC >= 2017 cannot be used if Corrade is built with CORRADE_MSVC2015_COMPATIBILITY")
|
|
endif()
|
|
elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.20")
|
|
if(CORRADE_MSVC2017_COMPATIBILITY)
|
|
message(FATAL_ERROR "MSVC >= 2019 cannot be used if Corrade is built with CORRADE_MSVC2017_COMPATIBILITY")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
# GCC/Clang-specific compiler flags
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang" AND NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") OR CORRADE_TARGET_EMSCRIPTEN)
|
|
set(CORRADE_PEDANTIC_COMPILER_OPTIONS
|
|
"-Wall" "-Wextra"
|
|
"$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-Wold-style-cast>"
|
|
"-Winit-self"
|
|
# -Werror=return-type doesn't work on nvcc, use it just for C and C++
|
|
"$<$<OR:$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>,$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>>:-Werror=return-type>"
|
|
"-Wmissing-declarations"
|
|
# -Wpedantic is since 4.8, until then only -pedantic (which doesn't
|
|
# have any -Wno-pedantic or a way to disable it for a particular line)
|
|
"-Wpedantic"
|
|
# Needs to have both, otherwise Clang's linker on macOS complains that
|
|
# "direct access in function [...] to global weak symbol [...] means the
|
|
# weak symbol cannot be overridden at runtime. This was likely caused
|
|
# by different translation units being compiled with different
|
|
# visibility settings." See also various google results for the above
|
|
# message.
|
|
"-fvisibility=hidden" "-fvisibility-inlines-hidden"
|
|
# A lot of functionality relies on aliased pointers, such as the whole
|
|
# StridedArrayView. Given numerous other libraries including stb_image
|
|
# *and the Linux kernel itself* disable this as well, I see no reason
|
|
# for needless suffering either. I don't remember strict aliasing to
|
|
# ever help with optimizing anything, plus it was disabled for the
|
|
# whole of Magnum since December 2013 already:
|
|
# https://github.com/mosra/magnum/commit/f373b6518e0b1fa3e4d0ffb19f77e80a8a56484c
|
|
# So let's just make it official and disable it for everything,
|
|
# everywhere, forever. Besides this place, which enables it for
|
|
# everyone that enables CORRADE_USE_PEDANTIC_FLAGS, it's also enabled
|
|
# for everyone who links to CorradeUtility in Utility/CMakeLists.txt
|
|
# and to Corrade::Utility in FindCorrade.cmake, so even people who
|
|
# don't enable pedantic flags (or can't due to too many warnings) get
|
|
# it and I don't need to deal with insane bugs and random breakages. On
|
|
# the other hand it's set here as well so even internal test code (that
|
|
# doesn't necessarily link to CorradeUtility) gets it implicitly too.
|
|
"-fno-strict-aliasing")
|
|
|
|
# Some flags are not yet supported everywhere
|
|
# TODO: do this with check_c_compiler_flags()
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
list(APPEND CORRADE_PEDANTIC_COMPILER_OPTIONS
|
|
"$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>:-Wzero-as-null-pointer-constant>"
|
|
|
|
# TODO: enable when this gets to Clang (not in 3.9, but in master
|
|
# since https://github.com/llvm-mirror/clang/commit/0a022661c797356e9c28e4999b6ec3881361371e)
|
|
"-Wdouble-promotion")
|
|
|
|
# GCC 4.8 doesn't like when structs are initialized using just {} and
|
|
# because we use that a lot, the output gets extremely noisy. Disable
|
|
# the warning altogether there.
|
|
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")
|
|
list(APPEND CORRADE_PEDANTIC_COMPILER_OPTIONS "-Wno-missing-field-initializers")
|
|
endif()
|
|
|
|
# Prints a warning in all cases of
|
|
# functionReturningATemporaryView()[i]
|
|
# i.e., basically all use cases of Utility::Json. Hopefully gets fixed
|
|
# better than what https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107532
|
|
# did so far.
|
|
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "13.0")
|
|
list(APPEND CORRADE_PEDANTIC_COMPILER_OPTIONS "-Wno-dangling-reference")
|
|
endif()
|
|
endif()
|
|
|
|
if(CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang" OR CORRADE_TARGET_EMSCRIPTEN)
|
|
list(APPEND CORRADE_PEDANTIC_COMPILER_OPTIONS
|
|
# Clang's -Wmissing-declarations does something else and the
|
|
# behavior we want is under -Wmissing-prototypes. See
|
|
# https://llvm.org/bugs/show_bug.cgi?id=16286.
|
|
"-Wmissing-prototypes"
|
|
|
|
# Fixing it in all places would add too much noise to the code.
|
|
"-Wno-shorten-64-to-32")
|
|
|
|
list(APPEND CORRADE_PEDANTIC_TEST_COMPILER_OPTIONS
|
|
# Unlike GCC, -Wunused-function (which is enabled through -Wall)
|
|
# doesn't fire for member functions, it's controlled separately
|
|
"-Wunused-member-function"
|
|
# This is implicitly enabled by the above and causes lots of
|
|
# warnings for e.g. move constructors, so disabling
|
|
"-Wno-unneeded-member-function")
|
|
endif()
|
|
|
|
# MSVC-specific compiler flags
|
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
|
|
set(CORRADE_PEDANTIC_COMPILER_OPTIONS
|
|
# Enable extra warnings (similar to -Wall)
|
|
"/W4"
|
|
|
|
# "conditional expression is constant", especially when a template
|
|
# argument is passed to an if, which happens mainly in tests but
|
|
# sometimes also in recursive constexpr functions. As I can't use if
|
|
# constexpr in C++11 code, there's not really much I can do.
|
|
"/wd4127"
|
|
|
|
# "needs to have dll-interface to be used by clients", as the fix for
|
|
# that would effectively prevent using STL completely.
|
|
"/wd4251"
|
|
|
|
# "conversion from '<bigger int type>' to '<smaller int type>'",
|
|
# "conversion from 'size_t' to '<smaller int type>', possible loss of
|
|
# data", fixing this would add too much noise. Equivalent to
|
|
# -Wshorten-64-to-32 on Clang.
|
|
"/wd4244"
|
|
"/wd4267"
|
|
|
|
# "structure was padded due to alignment specifier". YES. THAT'S
|
|
# EXACTLY AS INTENDED.
|
|
"/wd4324"
|
|
|
|
# "new behavior: elements of array will be default initialized".
|
|
# YES. YES I KNOW WHAT I'M DOING.
|
|
"/wd4351"
|
|
|
|
# "previous versions of the compiler did not override when parameters
|
|
# only differed by const/volatile qualifiers". Okay. So you had bugs.
|
|
# And?
|
|
"/wd4373"
|
|
|
|
# "declaration of 'foo' hides class member". I use this a lot in
|
|
# constructor arguments, `Class(int foo): foo{foo} {}` and adding some
|
|
# underscores to mitigate this would not be pretty. OTOH, "C4456:
|
|
# declaration of 'foo' hides previous local declaration" points to a
|
|
# valid issue that I should get rid of.
|
|
"/wd4458"
|
|
|
|
# "default constructor could not be generated/can never be
|
|
# instantiated". Apparently it can.
|
|
"/wd4510"
|
|
"/wd4610"
|
|
|
|
# "assignment operator could not be generated". Do I want one? NO I
|
|
# DON'T.
|
|
"/wd4512"
|
|
|
|
# "no suitable definition for explicit template instantiation". No. The
|
|
# problem is apparently that I'm having the definitions in *.cpp file
|
|
# and instantiating them explicitly. Common practice here.
|
|
"/wd4661"
|
|
|
|
# "unreachable code". *Every* assertion has return after std::abort().
|
|
# So?
|
|
"/wd4702"
|
|
|
|
# "assignment within conditional expression". It's not my problem that
|
|
# it doesn't get the hint with extra parentheses (`if((a = b))`).
|
|
"/wd4706"
|
|
|
|
# "forcing value to bool 'true' or 'false' (performance warning)". So
|
|
# what. I won't wrap everything in bool(). This is a _language feature_,
|
|
# dammit.
|
|
"/wd4800"
|
|
|
|
# "dllexport and extern are incompatible on an explicit instantiation".
|
|
# Why the error is emitted only on classes? Functions are okay with
|
|
# dllexport extern?!
|
|
"/wd4910")
|
|
set(CORRADE_PEDANTIC_COMPILER_DEFINITIONS
|
|
# Disabling warning for not using "secure-but-not-standard" STL algos
|
|
"_CRT_SECURE_NO_WARNINGS" "_SCL_SECURE_NO_WARNINGS")
|
|
endif()
|
|
|
|
if(CORRADE_TARGET_CLANG_CL)
|
|
list(APPEND CORRADE_PEDANTIC_COMPILER_OPTIONS
|
|
# See Utility::Path::libraryLocation() for details
|
|
"-Wno-microsoft-cast")
|
|
endif()
|
|
|
|
# Compiler flags to undo horrible crimes done by windows.h, common for both
|
|
# MSVC and MinGW
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC" OR MINGW)
|
|
list(APPEND CORRADE_PEDANTIC_COMPILER_DEFINITIONS
|
|
# Disabling all minmax nonsense macros coming from windows.h
|
|
"NOMINMAX"
|
|
|
|
# Disabling GDI and other mud in windows.h (which in turn fixes the
|
|
# dreaded #define interface struct UNLESS something includes the cursed
|
|
# headers such as shlwapi.h directly -- libjpeg does that, for
|
|
# instance).
|
|
"WIN32_LEAN_AND_MEAN")
|
|
endif()
|
|
|
|
define_property(TARGET PROPERTY CORRADE_CXX_STANDARD INHERITED
|
|
BRIEF_DOCS "C++ standard to require for given target"
|
|
FULL_DOCS "Sets compiler-specific flags to enable C++11 or later standard
|
|
when building given target or targets in given directory. Set in
|
|
combination with INTERFACE_CORRADE_CXX_STANDARD to force the standard
|
|
also on users of given target.")
|
|
define_property(TARGET PROPERTY INTERFACE_CORRADE_CXX_STANDARD INHERITED
|
|
BRIEF_DOCS "C++ standard to require for users of given target"
|
|
FULL_DOCS "Sets compiler-specific flags to enable C++11 or later standard
|
|
when using given target or targets in given directory.")
|
|
define_property(TARGET PROPERTY CORRADE_USE_PEDANTIC_FLAGS INHERITED
|
|
BRIEF_DOCS "Use pedantic compiler/linker flags"
|
|
FULL_DOCS "Enables additional pedantic C, C++ and linker flags on given
|
|
targets or directories.")
|
|
|
|
# Enable C++11/14/17/2a on GCC/Clang if CORRADE_CXX_STANDARD is set. Does
|
|
# nothing in case the user put "-std=" in CMAKE_CXX_FLAGS.
|
|
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang" AND NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") OR CORRADE_TARGET_EMSCRIPTEN) AND NOT CMAKE_CXX_FLAGS MATCHES "-std=")
|
|
set(CORRADE_CXX11_STANDARD_FLAG "-std=c++11")
|
|
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR ((CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?Clang" OR CORRADE_TARGET_EMSCRIPTEN) AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5))
|
|
set(CORRADE_CXX14_STANDARD_FLAG "-std=c++14")
|
|
else()
|
|
set(CORRADE_CXX14_STANDARD_FLAG "-std=c++1y")
|
|
endif()
|
|
# TODO: change to C++17 when compiler support is widespread enough
|
|
set(CORRADE_CXX17_STANDARD_FLAG "-std=c++1z")
|
|
set(CORRADE_CXX20_STANDARD_FLAG "-std=c++2a")
|
|
endif()
|
|
|
|
# Enable C++14/17/2a on MSVC if CORRADE_CXX_STANDARD is set. C++11 is present
|
|
# implicitly, 14, 17 and 20 has to be enabled through a flag. Does nothing in
|
|
# case the user put "/std:" or "-std:" in CMAKE_CXX_FLAGS.
|
|
if((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") AND NOT CMAKE_CXX_FLAGS MATCHES "[-/]std:")
|
|
set(CORRADE_CXX14_STANDARD_FLAG "/std:c++14")
|
|
set(CORRADE_CXX17_STANDARD_FLAG "/std:c++17")
|
|
# TODO: change to c++20? when such flag appears
|
|
# https://docs.microsoft.com/en-us/cpp/build/reference/std-specify-language-standard-version?view=vs-2019
|
|
set(CORRADE_CXX20_STANDARD_FLAG "/std:c++latest")
|
|
endif()
|
|
|
|
# Finally, in order to avoid clashes with builtin CMake features, we won't add
|
|
# the standard flag in case the CXX_STANDARD property is present. Additionally,
|
|
# since CMake 3.15, the cxx_std_14 compile feature doesn't result in any flag
|
|
# being added to compiler command-line if C++14 is a default on given compiler
|
|
# (such as GCC 6 and up). That unfortunately means ours default flag (-std=c++11)
|
|
# gets set, making it look like the COMPILE_FEATURES didn't work at all. To
|
|
# circumvent that, the CORRADE_CXX_STANDARD isn't set if anything from
|
|
# COMPILE_FEATURES is present either. It doesn't cover adding flags using
|
|
# target_compile_options(), though.
|
|
set(_CORRADE_CXX_STANDARD_ONLY_IF_NOT_ALREADY_SET
|
|
"$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,CXX>,$<NOT:$<BOOL:$<TARGET_PROPERTY:CXX_STANDARD>>>,$<NOT:$<BOOL:$<TARGET_PROPERTY:COMPILE_FEATURES>>>")
|
|
foreach(_standard 11 14 17 20)
|
|
if(CORRADE_CXX${_standard}_STANDARD_FLAG)
|
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS
|
|
"$<$<AND:${_CORRADE_CXX_STANDARD_ONLY_IF_NOT_ALREADY_SET},$<STREQUAL:$<TARGET_PROPERTY:CORRADE_CXX_STANDARD>,${_standard}>>:${CORRADE_CXX${_standard}_STANDARD_FLAG}>")
|
|
endif()
|
|
endforeach()
|
|
|
|
# On-demand pedantic compiler flags
|
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_OPTIONS "$<$<BOOL:$<TARGET_PROPERTY:CORRADE_USE_PEDANTIC_FLAGS>>:${CORRADE_PEDANTIC_COMPILER_OPTIONS}>")
|
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "$<$<BOOL:$<TARGET_PROPERTY:CORRADE_USE_PEDANTIC_FLAGS>>:${CORRADE_PEDANTIC_COMPILER_DEFINITIONS}>")
|
|
|
|
# Provide a way to distinguish between debug and release builds via
|
|
# preprocessor define
|
|
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS "$<$<CONFIG:Debug>:CORRADE_IS_DEBUG_BUILD>")
|
|
|
|
if(CORRADE_TESTSUITE_TARGET_XCTEST)
|
|
find_package(XCTest)
|
|
|
|
# Workaround for CMake iOS generator expression bug, see below
|
|
if(CORRADE_TARGET_IOS)
|
|
if(CMAKE_OSX_SYSROOT MATCHES "iPhoneOS")
|
|
set(_CORRADE_EFFECTIVE_PLATFORM_NAME "-iphoneos")
|
|
elseif(CMAKE_OSX_SYSROOT MATCHES "iPhoneSimulator")
|
|
set(_CORRADE_EFFECTIVE_PLATFORM_NAME "-iphonesimulator")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
if(CORRADE_TARGET_IOS AND NOT CORRADE_TESTSUITE_TARGET_XCTEST)
|
|
set(CORRADE_TESTSUITE_BUNDLE_IDENTIFIER_PREFIX ${PROJECT_NAME} CACHE STRING
|
|
"Bundle identifier prefix for tests ran on iOS device")
|
|
endif()
|
|
|
|
function(corrade_add_test test_name)
|
|
# See _CORRADE_USE_NO_TARGET_CHECKS in Corrade's root CMakeLists
|
|
if(NOT _CORRADE_USE_NO_TARGET_CHECKS AND (NOT TARGET Corrade::TestSuite OR NOT TARGET Corrade::Main))
|
|
message(FATAL_ERROR "The Corrade::TestSuite target, needed by corrade_add_test(), doesn't exist. Add the TestSuite component to your find_package() or enable CORRADE_WITH_TESTSUITE if you have Corrade as a CMake subproject.")
|
|
endif()
|
|
|
|
# If CORRADE_TESTSUITE_TEST_TARGET is set, tests aren't built by default
|
|
# (in the ALL target) but instead set as dependencies of a target named
|
|
# after the value of CORRADE_TESTSUITE_TEST_TARGET.
|
|
if(CORRADE_TESTSUITE_TEST_TARGET)
|
|
if(NOT TARGET ${CORRADE_TESTSUITE_TEST_TARGET})
|
|
add_custom_target(${CORRADE_TESTSUITE_TEST_TARGET})
|
|
endif()
|
|
set(EXCLUDE_FROM_ALL_IF_TEST_TARGET EXCLUDE_FROM_ALL)
|
|
endif()
|
|
|
|
set(_corrade_file_pair_match "^(.+)@([^@]+)$")
|
|
set(_corrade_file_pair_replace "\\1;\\2")
|
|
|
|
# TestSuite library to link to. Gets reset below if the tests already link
|
|
# to their own variant.
|
|
set(testsuite_library Corrade::TestSuite)
|
|
|
|
# Get DLL and path lists
|
|
foreach(arg ${ARGN})
|
|
if(arg STREQUAL LIBRARIES)
|
|
set(_DOING_LIBRARIES ON)
|
|
elseif(arg STREQUAL FILES)
|
|
set(_DOING_LIBRARIES OFF)
|
|
set(_DOING_FILES ON)
|
|
elseif(arg STREQUAL ARGUMENTS)
|
|
set(_DOING_LIBRARIES OFF)
|
|
set(_DOING_FILES OFF)
|
|
set(_DOING_ARGUMENTS ON)
|
|
else()
|
|
if(_DOING_LIBRARIES)
|
|
# If Corrade's own tests link their own variant of TestSuite,
|
|
# don't link the implicit one as well, as otherwise we'd end
|
|
# up with duplicated symbols.
|
|
if(arg STREQUAL CorradeTestSuiteTestLib)
|
|
set(testsuite_library )
|
|
endif()
|
|
list(APPEND libraries ${arg})
|
|
elseif(_DOING_FILES)
|
|
# If the file is already a pair of file and destination, just
|
|
# extract them
|
|
if(arg MATCHES ${_corrade_file_pair_match})
|
|
set(input_filename ${CMAKE_MATCH_1})
|
|
set(output_filename ${CMAKE_MATCH_2})
|
|
|
|
# Otherwise create the output filename from the input
|
|
else()
|
|
set(input_filename ${arg})
|
|
|
|
# Extract only the leaf component from absolute filename
|
|
# (applies also to paths with ..)
|
|
if(IS_ABSOLUTE ${arg} OR arg MATCHES "\\.\\.[\\\\/]")
|
|
get_filename_component(output_filename ${arg} NAME)
|
|
|
|
# Otherwise use the full relative path as output filename
|
|
else()
|
|
set(output_filename ${arg})
|
|
endif()
|
|
endif()
|
|
|
|
# Sanity checks
|
|
if(output_filename MATCHES "(\\.\\.[\\\\/]|@)" OR IS_ABSOLUTE ${output_filename})
|
|
message(SEND_ERROR "Names of files added to corrade_add_test() can't contain .., @ or be absolute")
|
|
endif()
|
|
|
|
# Convert input to absolute, concatenate the files back and
|
|
# add to the list
|
|
get_filename_component(input_filename ${input_filename} ABSOLUTE)
|
|
list(APPEND files ${input_filename}@${output_filename})
|
|
list(APPEND absolute_files ${input_filename})
|
|
elseif(_DOING_ARGUMENTS)
|
|
list(APPEND arguments ${arg})
|
|
else()
|
|
list(APPEND sources ${arg})
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
if(CORRADE_TESTSUITE_TARGET_XCTEST)
|
|
add_library(${test_name} SHARED ${EXCLUDE_FROM_ALL_IF_TEST_TARGET} ${sources})
|
|
set_target_properties(${test_name} PROPERTIES FRAMEWORK TRUE)
|
|
# This is never Windows, so no need to bother with Corrade::Main
|
|
target_link_libraries(${test_name} PRIVATE ${libraries} ${testsuite_library})
|
|
|
|
set(test_runner_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.mm)
|
|
configure_file(${CORRADE_TESTSUITE_XCTEST_RUNNER}
|
|
${test_runner_file})
|
|
xctest_add_bundle(${test_name}Runner ${test_name} ${test_runner_file})
|
|
if(CORRADE_TARGET_IOS)
|
|
# The EFFECTIVE_PLATFORM_NAME variable is not expanded when using
|
|
# TARGET_* generator expressions on iOS, we need to hardcode it
|
|
# manually. See https://cmake.org/pipermail/cmake/2016-March/063049.html
|
|
# In case we redirect the runtime output directory, use that (and
|
|
# assume there's no TARGET_* generator expression). This will of
|
|
# course break when someone sets the LIBRARY_OUTPUT_DIRECTORY
|
|
# property of the target, but that didn't work before either.
|
|
if(CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
|
add_test(NAME ${test_name} COMMAND ${XCTest_EXECUTABLE} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${test_name}Runner.xctest)
|
|
else()
|
|
add_test(NAME ${test_name} COMMAND ${XCTest_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>${_CORRADE_EFFECTIVE_PLATFORM_NAME}/${test_name}Runner.xctest)
|
|
endif()
|
|
else()
|
|
xctest_add_test(${test_name} ${test_name}Runner)
|
|
endif()
|
|
if(arguments)
|
|
message(WARNING "corrade_add_test() ARGUMENTS are not supported when CORRADE_TESTSUITE_TARGET_XCTEST is enabled")
|
|
endif()
|
|
else()
|
|
add_executable(${test_name} ${EXCLUDE_FROM_ALL_IF_TEST_TARGET} ${sources})
|
|
target_link_libraries(${test_name} PRIVATE ${libraries} ${testsuite_library} Corrade::Main)
|
|
|
|
# Run tests using Node.js on Emscripten
|
|
if(CORRADE_TARGET_EMSCRIPTEN)
|
|
# Emscripten needs to have exceptions enabled for TestSuite to work
|
|
# properly. See TestSuite CMakeLists for further information.
|
|
# TODO do directly on the TestSuite target and in FindCorrade via
|
|
# INTERFACE_COMPILE_OPTIONS and INTERFACE_LINK_OPTIONS and SHELL:
|
|
# once we require CMake 3.13 unconditionally
|
|
set_property(TARGET ${test_name} APPEND_STRING PROPERTY COMPILE_FLAGS " -s DISABLE_EXCEPTION_CATCHING=0")
|
|
set_property(TARGET ${test_name} APPEND_STRING PROPERTY LINK_FLAGS " -s DISABLE_EXCEPTION_CATCHING=0")
|
|
# FindNodeJs is installed to a subdirectory next to UseCorrade, to
|
|
# prevent it from being in CMAKE_MODULE_PATH always and clashing
|
|
# with modules of the same name from elsewhere. Add it to the
|
|
# CMAKE_MODULE_PATH just locally for this function. If the variable
|
|
# is not defined, we're running from within Corrade's own sources
|
|
# (and FindNodeJs is thus in CMAKE_MODULE_PATH already) or an old
|
|
# FindCorrade may be used, in which case we assume the user
|
|
# supplies it in a different way.
|
|
if(CORRADE_DEPENDENCY_MODULE_DIR)
|
|
set(CMAKE_MODULE_PATH "${CORRADE_DEPENDENCY_MODULE_DIR}" ${CMAKE_MODULE_PATH})
|
|
endif()
|
|
find_package(NodeJs REQUIRED)
|
|
# Node.js before version 17 needs --experimental-wasm-simd. Version
|
|
# 17 upgraded to V8 9.1, which has the option enabled by default:
|
|
# https://github.com/nodejs/node/commit/a7cbf19a82c75e9a65e90fb8ba4947e2fc52ef39
|
|
# Since the code defining these flags explicitly says "remove once
|
|
# they hit stable":
|
|
# https://github.com/v8/v8/blob/ba8ad5dd17ea85c856c09c2ff603641487d1f0ca/src/wasm/wasm-feature-flags.h#L101-L109
|
|
# even though it causes numerous issues such as:
|
|
# https://github.com/nodejs/node/issues/43592
|
|
# Not setting it for version 17+, the flag is removed in version
|
|
# 20. From the other side, the flag goes back to ancient version 6
|
|
# (2017), so it should be no problem to just pass it there always:
|
|
# https://github.com/v8/v8/commit/45618a9ab5cc98a5de200b0116670e8c272f0c5f
|
|
if(NodeJs_VERSION VERSION_LESS 17)
|
|
set(extra_flags --experimental-wasm-simd)
|
|
# Node.js 18 doesn't work with Emscripten before 3.1.13 unless the
|
|
# fetch functionality is disabled.
|
|
# https://github.com/emscripten-core/emscripten/pull/16917
|
|
# https://github.com/emscripten-core/emscripten/issues/16915
|
|
elseif(NodeJs_VERSION VERSION_GREATER_EQUAL 18.1.0 AND EMSCRIPTEN_VERSION VERSION_LESS 3.1.13)
|
|
set(extra_flags --no-experimental-fetch)
|
|
else()
|
|
set(extra_flags )
|
|
endif()
|
|
# Using NodeJs::NodeJs works only if CMAKE_CROSSCOMPILING_EMULATOR
|
|
# isn't set, as otherwise CMake mistakenly understands it as a
|
|
# project-local target that needs to be emulated (even though it's
|
|
# an IMPORTED target!), ultimately calling something like
|
|
# /usr/bin/node /usr/bin/node <test>
|
|
# This is likely a CMake bug, where it doesn't correctly check that
|
|
# the target is imported before prepending the emulator. Using the
|
|
# actual filename stops CMAKE_CROSSCOMPILING_EMULATOR from being
|
|
# added second time.
|
|
# TODO Use https://cmake.org/cmake/help/latest/prop_tgt/TEST_LAUNCHER.html
|
|
# since 3.29 to deduplicate the add_test() invocations for
|
|
# Emscripten/Android
|
|
add_test(NAME ${test_name} COMMAND $<TARGET_FILE:NodeJs::NodeJs> ${extra_flags} $<TARGET_FILE:${test_name}> ${arguments})
|
|
|
|
# Embed all files
|
|
foreach(file ${files})
|
|
string(REGEX REPLACE ${_corrade_file_pair_match} "${_corrade_file_pair_replace}" file_pair ${file})
|
|
list(GET file_pair 0 input_filename)
|
|
list(GET file_pair 1 output_filename)
|
|
|
|
# This is a verbatim copy of emscripten_embed_file() from
|
|
# UseEmscripten inside the toolchains submodule. It's not
|
|
# included in order to avoid a dependency on the toolchains and
|
|
# thus allow 3rd party toolchains to be used instead.
|
|
get_filename_component(absolute_file ${input_filename} ABSOLUTE)
|
|
get_target_property(${test_name}_LINK_FLAGS ${test_name} LINK_FLAGS)
|
|
if(NOT ${test_name}_LINK_FLAGS)
|
|
set(${test_name}_LINK_FLAGS )
|
|
endif()
|
|
set_target_properties(${test_name} PROPERTIES LINK_FLAGS "${${test_name}_LINK_FLAGS} --embed-file ${absolute_file}@/${output_filename}")
|
|
# TODO according to CMake docs, this only works with Makefile
|
|
# and Ninja generators, not for example VS or Xcode. Which
|
|
# should be mostly fine I guess?
|
|
set_property(TARGET ${test_name} APPEND PROPERTY LINK_DEPENDS ${input_filename})
|
|
endforeach()
|
|
|
|
# Generate the runner file, first replacing ${test_name} with
|
|
# configure_file() and then copying that into the final location.
|
|
# Two steps because file(GENERATE) can't replace variables while
|
|
# configure_file() can't have generator expressions in the path.
|
|
configure_file(${CORRADE_TESTSUITE_EMSCRIPTEN_RUNNER}
|
|
${CMAKE_CURRENT_BINARY_DIR}/${test_name}.html)
|
|
file(GENERATE OUTPUT $<TARGET_FILE_DIR:${test_name}>/${test_name}.html
|
|
INPUT ${CMAKE_CURRENT_BINARY_DIR}/${test_name}.html)
|
|
|
|
# Run tests using ADB on Android
|
|
elseif(CORRADE_TARGET_ANDROID)
|
|
# The executables need to be PIE
|
|
target_compile_options(${test_name} PRIVATE "-fPIE")
|
|
set_property(TARGET ${test_name} APPEND_STRING PROPERTY LINK_FLAGS "-fPIE -pie")
|
|
# All files will be copied to the target when the test is run. The
|
|
# arguments are passed together with the filename, at the moment it
|
|
# will fail for arguments with spaces
|
|
string(REPLACE ";" " " arguments_str "${arguments}")
|
|
# TODO Use https://cmake.org/cmake/help/latest/prop_tgt/TEST_LAUNCHER.html
|
|
# since 3.29 to deduplicate the add_test() invocations for
|
|
# Emscripten/Android
|
|
add_test(NAME ${test_name} COMMAND ${CORRADE_TESTSUITE_ADB_RUNNER} $<TARGET_FILE_DIR:${test_name}> "$<TARGET_FILE_NAME:${test_name}> ${arguments_str}" ${files})
|
|
|
|
# Run tests natively elsewhere
|
|
else()
|
|
add_test(NAME ${test_name} COMMAND ${test_name} ${arguments})
|
|
endif()
|
|
|
|
# iOS-specific
|
|
if(CORRADE_TARGET_IOS)
|
|
set_target_properties(${test_name} PROPERTIES
|
|
MACOSX_BUNDLE ON
|
|
MACOSX_BUNDLE_GUI_IDENTIFIER ${CORRADE_TESTSUITE_BUNDLE_IDENTIFIER_PREFIX}.${test_name}
|
|
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "YES")
|
|
endif()
|
|
endif()
|
|
|
|
# If a custom test target is used instead of ALL, add the test as a
|
|
# dependency of it so they can still be all built with a single command.
|
|
if(CORRADE_TESTSUITE_TEST_TARGET)
|
|
if(CORRADE_TESTSUITE_TARGET_XCTEST)
|
|
add_dependencies(${CORRADE_TESTSUITE_TEST_TARGET} ${test_name}Runner)
|
|
else()
|
|
add_dependencies(${CORRADE_TESTSUITE_TEST_TARGET} ${test_name})
|
|
endif()
|
|
endif()
|
|
|
|
set_property(TARGET ${test_name} APPEND PROPERTY COMPILE_OPTIONS "$<$<BOOL:$<TARGET_PROPERTY:CORRADE_USE_PEDANTIC_FLAGS>>:${CORRADE_PEDANTIC_TEST_COMPILER_OPTIONS}>")
|
|
|
|
# Add the file to list of required files for given test case
|
|
set_tests_properties(${test_name} PROPERTIES REQUIRED_FILES "${absolute_files}")
|
|
endfunction()
|
|
|
|
function(corrade_add_resource name input)
|
|
foreach(arg ${ARGN})
|
|
if(arg STREQUAL SINGLE)
|
|
set(single_file --single)
|
|
endif()
|
|
endforeach()
|
|
|
|
# See _CORRADE_USE_NO_TARGET_CHECKS in Corrade's root CMakeLists
|
|
if(NOT _CORRADE_USE_NO_TARGET_CHECKS AND NOT TARGET Corrade::rc)
|
|
if(CMAKE_CROSSCOMPILING)
|
|
message(FATAL_ERROR "The Corrade::rc target, needed by corrade_add_resource() and corrade_add_static_plugin(), doesn't exist. Either build a native version, make it available through PATH or pass its location to CMake using the CORRADE_RC_EXECUTABLE option, or specify CMAKE_CROSSCOMPILING_EMULATOR to have Corrade run a cross-compiled executable instead, and add the Utility / rc component to your find_package(Corrade).")
|
|
else()
|
|
message(FATAL_ERROR "The Corrade::rc target, needed by corrade_add_resource() and corrade_add_static_plugin(), doesn't exist. Add the Utility / rc component to your find_package(Corrade) or enable CORRADE_WITH_UTILITY / CORRADE_WITH_RC if you have Corrade as a CMake subproject.")
|
|
endif()
|
|
endif()
|
|
|
|
# Parse dependencies from the file, unless it's a single file
|
|
if(NOT single_file)
|
|
set(dependencies )
|
|
set(filenameRegex "^[ \t]*filename[ \t]*=(.+)$")
|
|
get_filename_component(configurationFilePath ${input} PATH)
|
|
|
|
file(STRINGS "${input}" filenames REGEX ${filenameRegex} ENCODING UTF-8)
|
|
foreach(filename ${filenames})
|
|
# Get the filename together with leading/trailing whitespace and quotes
|
|
# from the file line
|
|
string(REGEX REPLACE ${filenameRegex} "\\1" filename "${filename}")
|
|
# Strip leading/trailing whitespace
|
|
string(STRIP "${filename}" filename)
|
|
# If it's quoted (for example because the filename itself has spaces),
|
|
# remove the quotes
|
|
string(REGEX REPLACE "^\"([^\"]+)\"$" "\\1" filename "${filename}")
|
|
if(NOT IS_ABSOLUTE "${filename}" AND configurationFilePath)
|
|
set(filename "${configurationFilePath}/${filename}")
|
|
endif()
|
|
list(APPEND dependencies "${filename}")
|
|
endforeach()
|
|
|
|
# Force IDEs display also the resource files in project view
|
|
add_custom_target(${name}-dependencies SOURCES ${dependencies})
|
|
list(APPEND dependencies ${name}-dependencies)
|
|
endif()
|
|
|
|
# Output file name
|
|
set(out "${CMAKE_CURRENT_BINARY_DIR}/resource_${name}.cpp")
|
|
|
|
# Tell CMake to re-run and update the dependency list when the resource
|
|
# list file changes (otherwise it parses the file only during the explicit
|
|
# configure step and never again, thus additions/deletions are not
|
|
# recognized automatically)
|
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${input})
|
|
|
|
# Run command. If a non-native Corrade::rc was found and needs to be run
|
|
# through an emulator, we need to pass the actual executable path to it,
|
|
# not just the target.
|
|
if(CORRADE_RC_EXECUTABLE_EMULATOR)
|
|
set(command ${CORRADE_RC_EXECUTABLE_EMULATOR} $<TARGET_FILE:Corrade::rc>)
|
|
else()
|
|
set(command Corrade::rc)
|
|
endif()
|
|
add_custom_command(
|
|
OUTPUT "${out}"
|
|
COMMAND ${command} ${single_file} ${name} "${input}" "${out}"
|
|
DEPENDS Corrade::rc ${input} ${dependencies}
|
|
COMMENT "Compiling data resource file ${out}"
|
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
|
|
# Save output filename
|
|
set(${name} "${out}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(corrade_add_plugin plugin_name debug_install_dirs release_install_dirs metadata_file)
|
|
# See _CORRADE_USE_NO_TARGET_CHECKS in Corrade's root CMakeLists
|
|
if(NOT _CORRADE_USE_NO_TARGET_CHECKS AND NOT TARGET Corrade::PluginManager)
|
|
message(FATAL_ERROR "The Corrade::PluginManager target, needed by corrade_add_plugin(), doesn't exist. Add the PluginManager component to your find_package() or enable CORRADE_WITH_PLUGINMANAGER if you have Corrade as a CMake subproject.")
|
|
endif()
|
|
|
|
if(CORRADE_TARGET_EMSCRIPTEN OR CORRADE_TARGET_WINDOWS_RT OR CORRADE_TARGET_IOS)
|
|
message(SEND_ERROR "corrade_add_plugin(): dynamic plugins are not available on this platform, use corrade_add_static_plugin() instead")
|
|
endif()
|
|
|
|
# Populate {debug,release}_{binary,library,conf}_install_dir variables
|
|
if(NOT debug_install_dirs STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
|
list(LENGTH debug_install_dirs debug_install_dir_count)
|
|
list(LENGTH release_install_dirs release_install_dir_count)
|
|
if(NOT debug_install_dir_count EQUAL release_install_dir_count)
|
|
message(FATAL_ERROR "corrade_add_plugin(): either none or both install dirs must contain binary location")
|
|
elseif(debug_install_dir_count EQUAL 1)
|
|
set(debug_binary_install_dir ${debug_install_dirs})
|
|
set(debug_library_install_dir ${debug_install_dirs})
|
|
set(release_binary_install_dir ${release_install_dirs})
|
|
set(release_library_install_dir ${release_install_dirs})
|
|
elseif(debug_install_dir_count EQUAL 2)
|
|
list(GET debug_install_dirs 0 debug_binary_install_dir)
|
|
list(GET debug_install_dirs 1 debug_library_install_dir)
|
|
list(GET release_install_dirs 0 release_binary_install_dir)
|
|
list(GET release_install_dirs 1 release_library_install_dir)
|
|
else()
|
|
message(FATAL_ERROR "corrade_add_plugin(): install dirs must contain either just library location or both binary and library location")
|
|
endif()
|
|
|
|
if(CORRADE_TARGET_WINDOWS)
|
|
set(debug_conf_install_dir ${debug_binary_install_dir})
|
|
set(release_conf_install_dir ${release_binary_install_dir})
|
|
else()
|
|
set(debug_conf_install_dir ${debug_library_install_dir})
|
|
set(release_conf_install_dir ${release_library_install_dir})
|
|
endif()
|
|
endif()
|
|
|
|
# Create dynamic library and bring all needed options along. On Windows a
|
|
# DLL cannot have undefined references, so we need to link against all its
|
|
# dependencies *at compile time*, as opposed to runtime like in all sane
|
|
# systems. But when using add_library(MODULE), CMake disallows linking
|
|
# MODULEs to MODULEs (when dealing with inter-plugin dependencies, for
|
|
# example) -- probably because, on Windows, creating a MODULE doesn't
|
|
# create the corresponding import lib for it. So we work around that by
|
|
# using SHARED on Windows.
|
|
if(CORRADE_TARGET_WINDOWS)
|
|
add_library(${plugin_name} SHARED ${ARGN})
|
|
else()
|
|
add_library(${plugin_name} MODULE ${ARGN})
|
|
endif()
|
|
set_target_properties(${plugin_name} PROPERTIES CORRADE_CXX_STANDARD 11)
|
|
target_compile_definitions(${plugin_name} PRIVATE "CORRADE_DYNAMIC_PLUGIN")
|
|
target_include_directories(${plugin_name} PUBLIC $<TARGET_PROPERTY:Corrade::PluginManager,INTERFACE_INCLUDE_DIRECTORIES>)
|
|
|
|
# Plugins don't have any prefix (e.g. 'lib' on Linux)
|
|
set_target_properties(${plugin_name} PROPERTIES PREFIX "")
|
|
|
|
# On Apple platforms, it's by default not allowed to have plugins with
|
|
# undefined (i.e., runtime-resolved) symbols. This flag enables them,
|
|
# however when targeting macOS 12+ / iOS 15+, it produces
|
|
# ld: warning: -undefined dynamic_lookup may not work with chained fixups
|
|
# One solution would be to use the Windows-specific codepath on Apple as
|
|
# well, i.e. explicitly linking all dependencies, but that's just horrible.
|
|
# TODO Python has the same issue, so far (2024-11-11) with no solution yet,
|
|
# retry when they do: https://github.com/python/cpython/issues/97524
|
|
if(CORRADE_TARGET_APPLE)
|
|
set_target_properties(${plugin_name} PROPERTIES
|
|
LINK_FLAGS "-undefined dynamic_lookup")
|
|
endif()
|
|
|
|
if(metadata_file)
|
|
get_filename_component(metadata_file_suffix ${metadata_file} EXT)
|
|
# Force IDEs display also the resource files in project view
|
|
add_custom_target(${plugin_name}-metadata SOURCES ${metadata_file})
|
|
|
|
# Copy metadata next to the binary so tests and CMake subprojects can
|
|
# use it as well.
|
|
# TODO Ideally this would be done not just when the plugin is rebuilt,
|
|
# but also when the metadata file changes. Not sure how to do that,
|
|
# add_custom_command(TARGET) doesn't support the DEPENDS option.
|
|
add_custom_command(TARGET ${plugin_name} POST_BUILD
|
|
# This would be nice to Ninja, but BYPRODUCTS don't support generator
|
|
# expressions right now (last checked: CMake 3.16)
|
|
#BYPRODUCTS $<TARGET_FILE_DIR:${plugin_name}>/${plugin_name}${metadata_file_suffix}
|
|
COMMAND ${CMAKE_COMMAND} -E copy ${metadata_file} $<TARGET_FILE_DIR:${plugin_name}>/${plugin_name}${metadata_file_suffix}
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
endif()
|
|
|
|
# Install it somewhere, unless that's explicitly not wanted
|
|
if(NOT debug_install_dirs STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
|
# CONFIGURATIONS must be first in order to not be ignored when having
|
|
# multiple destinations.
|
|
# https://gitlab.kitware.com/cmake/cmake/issues/16361
|
|
install(TARGETS ${plugin_name}
|
|
CONFIGURATIONS Debug
|
|
RUNTIME DESTINATION ${debug_binary_install_dir}
|
|
LIBRARY DESTINATION ${debug_library_install_dir}
|
|
ARCHIVE DESTINATION ${debug_library_install_dir})
|
|
install(TARGETS ${plugin_name}
|
|
CONFIGURATIONS "" None Release RelWithDebInfo MinSizeRel
|
|
RUNTIME DESTINATION ${release_binary_install_dir}
|
|
LIBRARY DESTINATION ${release_library_install_dir}
|
|
ARCHIVE DESTINATION ${release_library_install_dir})
|
|
if(metadata_file)
|
|
install(FILES ${metadata_file} DESTINATION ${debug_conf_install_dir}
|
|
RENAME "${plugin_name}${metadata_file_suffix}"
|
|
CONFIGURATIONS Debug)
|
|
install(FILES ${metadata_file} DESTINATION ${release_conf_install_dir}
|
|
RENAME "${plugin_name}${metadata_file_suffix}"
|
|
CONFIGURATIONS "" None Release RelWithDebInfo MinSizeRel)
|
|
endif()
|
|
endif()
|
|
endfunction()
|
|
|
|
function(corrade_add_static_plugin plugin_name install_dirs metadata_file)
|
|
# See _CORRADE_USE_NO_TARGET_CHECKS in Corrade's root CMakeLists
|
|
if(NOT _CORRADE_USE_NO_TARGET_CHECKS AND NOT TARGET Corrade::PluginManager)
|
|
message(FATAL_ERROR "The Corrade::PluginManager target, needed by corrade_add_static_plugin(), doesn't exist. Add the PluginManager component to your find_package() or enable CORRADE_WITH_PLUGINMANAGER if you have Corrade as a CMake subproject.")
|
|
endif()
|
|
|
|
# Populate library_install_dir variable
|
|
list(LENGTH install_dirs install_dir_count)
|
|
if(install_dir_count EQUAL 1)
|
|
set(library_install_dir ${install_dirs})
|
|
elseif(install_dir_count EQUAL 2)
|
|
list(GET install_dirs 1 library_install_dir)
|
|
else()
|
|
message(FATAL_ERROR "corrade_add_static_plugin(): install dir must contain either just library location or both library and binary location")
|
|
endif()
|
|
|
|
# Compile resources. If the metadata file is disabled, the resource is
|
|
# empty. If a non-native Corrade::rc was found and needs to be run through
|
|
# an emulator, we need to pass the actual executable path to it, not just
|
|
# the target.
|
|
if(CORRADE_RC_EXECUTABLE_EMULATOR)
|
|
set(command ${CORRADE_RC_EXECUTABLE_EMULATOR} $<TARGET_FILE:Corrade::rc>)
|
|
else()
|
|
set(command Corrade::rc)
|
|
endif()
|
|
set(resource_out ${CMAKE_CURRENT_BINARY_DIR}/resource_${plugin_name}.cpp)
|
|
if(metadata_file)
|
|
add_custom_command(
|
|
OUTPUT ${resource_out}
|
|
COMMAND ${command} ${plugin_name} --single ${metadata_file} ${resource_out}
|
|
DEPENDS Corrade::rc ${metadata_file}
|
|
COMMENT "Compiling static plugin metadata file ${resource_out}"
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
else()
|
|
set(metadata_file ${CMAKE_CURRENT_BINARY_DIR}/${plugin_name}-empty.conf)
|
|
add_custom_command(
|
|
OUTPUT ${resource_out}
|
|
COMMAND ${CMAKE_COMMAND} -E touch ${metadata_file}
|
|
COMMAND ${command} ${plugin_name} --single ${metadata_file} ${resource_out}
|
|
DEPENDS Corrade::rc
|
|
COMMENT "Compiling static plugin metadata file ${resource_out}"
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
|
endif()
|
|
|
|
# Create static library and bring all needed options along
|
|
add_library(${plugin_name} STATIC ${ARGN} ${resource_out})
|
|
set_target_properties(${plugin_name} PROPERTIES CORRADE_CXX_STANDARD 11)
|
|
target_compile_definitions(${plugin_name} PRIVATE "CORRADE_STATIC_PLUGIN")
|
|
target_include_directories(${plugin_name} PUBLIC $<TARGET_PROPERTY:Corrade::PluginManager,INTERFACE_INCLUDE_DIRECTORIES>)
|
|
|
|
set_target_properties(${plugin_name} PROPERTIES DEBUG_POSTFIX "-d")
|
|
|
|
# Install, if not into the same place
|
|
if(NOT install_dirs STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
|
install(TARGETS ${plugin_name} DESTINATION ${library_install_dir})
|
|
endif()
|
|
endfunction()
|
|
|
|
if(CORRADE_TARGET_WINDOWS)
|
|
function(corrade_find_dlls_for_libs result)
|
|
set(dlls )
|
|
foreach(lib ${ARGN})
|
|
get_filename_component(lib_dir ${lib} DIRECTORY)
|
|
get_filename_component(lib_name ${lib} NAME_WE)
|
|
find_file(CORRADE_DLL_FOR_${lib_name} ${lib_name}.dll HINTS ${lib_dir}/../bin)
|
|
list(APPEND dlls ${CORRADE_DLL_FOR_${lib_name}})
|
|
endforeach()
|
|
set(${result} ${dlls} PARENT_SCOPE)
|
|
endfunction()
|
|
endif()
|
|
|
|
set(_CORRADE_USE_INCLUDED TRUE)
|