diff --git a/CMakeLists.txt b/CMakeLists.txt index b3b1dbe..5670308 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ include (GenerateExportHeader) option(BUILD_SHARED_LIBS "Build Shared Libraries" ON) option(INSTALL_EXAMPLES "Install source code and build system for examples" ON) -include(osvrStashMapConfig) +include(StashMapConfig) #----------------------------------------------------------------------------- # This looks for an osvrConfig.cmake file - most of the time it can be @@ -27,9 +27,9 @@ include(osvrStashMapConfig) # C:/Users/Ryan/Desktop/build/OSVR-Core-vc12 or # C:/Users/Ryan/Downloads/OSVR-Core-Snapshot-v0.1-406-gaa55515-build54-vs12-32bit # in the CMake GUI or command line -osvr_stash_common_map_config() +stash_common_map_config() find_package(osvr REQUIRED) -osvr_unstash_common_map_config() +stash_common_map_config() find_package(Eigen3 REQUIRED) find_package(JsonCpp REQUIRED) @@ -609,7 +609,7 @@ configure_file("cmake/osvrRenderManagerConfig.cmake" # Copy over the shared CMake modules for use in a build tree, # and install for an install tree. -foreach(HELPER CMakeBoostHelper FindSDL2 FindGLEW CopyImportedTarget osvrStashMapConfig) +foreach(HELPER CMakeBoostHelper FindSDL2 FindGLEW CopyImportedTarget StashMapConfig) configure_file("cmake/${HELPER}.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${HELPER}.cmake" COPYONLY) install(FILES "cmake/${HELPER}.cmake" diff --git a/cmake/FindJsonCpp.cmake b/cmake/FindJsonCpp.cmake index 2f66845..28fca2f 100644 --- a/cmake/FindJsonCpp.cmake +++ b/cmake/FindJsonCpp.cmake @@ -51,69 +51,136 @@ macro(_jsoncpp_check_for_real_jsoncpplib) set(__jsoncpp_have_jsoncpplib TRUE) endif() endif() + #message(STATUS "__jsoncpp_have_jsoncpplib ${__jsoncpp_have_jsoncpplib}") endmacro() include(FindPackageHandleStandardArgs) # Ensure that if this is TRUE later, it's because we set it. set(JSONCPP_FOUND FALSE) +set(__jsoncpp_have_jsoncpplib FALSE) -# See if we find a CMake config file. +# See if we find a CMake config file - there is no harm in calling this more than once, +# and we need to call it at least once every CMake invocation to create the original +# imported targets, since those don't stick around like cache variables. find_package(jsoncpp QUIET NO_MODULE) -# We will always try first to get a config file. -if(NOT JSONCPP_IMPORTED_LIBRARY) - if(jsoncpp_FOUND) - # OK, so we found something. - unset(JSONCPP_IMPORTED_LIBRARY_IS_SHARED) - _jsoncpp_check_for_real_jsoncpplib() - if(__jsoncpp_have_jsoncpplib AND TARGET jsoncpp_lib_static) - # A veritable cache of riches - we have both shared and static! - set(JSONCPP_IMPORTED_LIBRARY_SHARED jsoncpp_lib CACHE INTERNAL "" FORCE) - set(JSONCPP_IMPORTED_LIBRARY_STATIC jsoncpp_lib_static CACHE INTERNAL "" FORCE) - if(WIN32 OR CYGWIN OR MINGW) - # DLL platforms: static library should be default - set(JSONCPP_IMPORTED_LIBRARY ${JSONCPP_IMPORTED_LIBRARY_STATIC} CACHE INTERNAL "" FORCE) - set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED FALSE CACHE INTERNAL "" FORCE) - else() - # Other platforms - might require PIC to be linked into shared libraries, so safest to prefer shared. - set(JSONCPP_IMPORTED_LIBRARY ${JSONCPP_IMPORTED_LIBRARY_SHARED} CACHE INTERNAL "" FORCE) - set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED TRUE CACHE INTERNAL "" FORCE) - endif() - elseif(TARGET jsoncpp_lib_static) - # Well, only one variant, but we know for sure that it's static. - set(JSONCPP_IMPORTED_LIBRARY_STATIC jsoncpp_lib_static CACHE INTERNAL "" FORCE) - set(JSONCPP_IMPORTED_LIBRARY jsoncpp_lib_static CACHE INTERNAL "" FORCE) - set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED FALSE CACHE INTERNAL "" FORCE) - elseif(TARGET __jsoncpp_have_jsoncpplib) - # One variant, and we have no idea if this is just an old version or if - # this is shared based on the target name alone. Hmm. - # TODO figure out if this is shared or static? - set(JSONCPP_IMPORTED_LIBRARY jsoncpp_lib CACHE INTERNAL "" FORCE) - endif() +if(jsoncpp_FOUND) + # Build a string to help us figure out when to invalidate our cache variables. + # start with where we found jsoncpp + set(__jsoncpp_info_string "[${jsoncpp_DIR}]") - # Now, we need include directories. Can't just limit this to old CMakes, since - # new CMakes might be used to build projects designed to support older ones. - if(__jsoncpp_have_jsoncpplib) - get_property(__jsoncpp_interface_include_dirs TARGET jsoncpp_lib PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - if(__jsoncpp_interface_include_dirs) - set(JSONCPP_IMPORTED_INCLUDE_DIRS "${__jsoncpp_interface_include_dirs}" CACHE INTERNAL "" FORCE) - endif() + # part of the string to indicate if we found a real jsoncpp_lib (and what kind) + _jsoncpp_check_for_real_jsoncpplib() + + macro(_jsoncpp_apply_map_config target) + if(MSVC) + # Can't do this - different runtimes, incompatible ABI, etc. + set(_jsoncpp_debug_fallback) + else() + set(_jsoncpp_debug_fallback DEBUG) + #osvr_stash_map_config(DEBUG DEBUG RELWITHDEBINFO RELEASE MINSIZEREL NONE) endif() - if(TARGET jsoncpp_lib_static AND NOT JSONCPP_IMPORTED_INCLUDE_DIRS) - get_property(__jsoncpp_interface_include_dirs TARGET jsoncpp_lib_static PROPERTY INTERFACE_INCLUDE_DIRECTORIES) - if(__jsoncpp_interface_include_dirs) - set(JSONCPP_IMPORTED_INCLUDE_DIRS "${__jsoncpp_interface_include_dirs}" CACHE INTERNAL "" FORCE) - endif() + # Appending, just in case using project or upstream fixes this. + set_property(TARGET ${target} APPEND PROPERTY MAP_IMPORTED_CONFIG_RELEASE RELEASE RELWITHDEBINFO MINSIZEREL NONE ${_jsoncpp_debug_fallback}) + set_property(TARGET ${target} APPEND PROPERTY MAP_IMPORTED_CONFIG_RELWITHDEBINFO RELWITHDEBINFO RELEASE MINSIZEREL NONE ${_jsoncpp_debug_fallback}) + set_property(TARGET ${target} APPEND PROPERTY MAP_IMPORTED_CONFIG_MINSIZEREL MINSIZEREL RELEASE RELWITHDEBINFO NONE ${_jsoncpp_debug_fallback}) + set_property(TARGET ${target} APPEND PROPERTY MAP_IMPORTED_CONFIG_NONE RELEASE RELWITHDEBINFO MINSIZEREL ${_jsoncpp_debug_fallback}) + if(NOT MSVC) + set_property(TARGET ${target} APPEND PROPERTY MAP_IMPORTED_CONFIG_DEBUG DEBUG RELWITHDEBINFO RELEASE MINSIZEREL NONE) + endif() + endmacro() + if(__jsoncpp_have_jsoncpplib) + list(APPEND __jsoncpp_info_string "[${__jsoncpp_lib_type}]") + _jsoncpp_apply_map_config(jsoncpp_lib) + else() + list(APPEND __jsoncpp_info_string "[]") + endif() + # part of the string to indicate if we found jsoncpp_lib_static + if(TARGET jsoncpp_lib_static) + list(APPEND __jsoncpp_info_string "[T]") + _jsoncpp_apply_map_config(jsoncpp_lib_static) + else() + list(APPEND __jsoncpp_info_string "[]") + endif() +endif() + + +# If we found something, and it's not the exact same as what we've found before... +# NOTE: The contents of this "if" block update only (internal) cache variables! +# (since this will only get run the first CMake pass that finds jsoncpp or that finds a different/updated install) +if(jsoncpp_FOUND AND NOT __jsoncpp_info_string STREQUAL "${JSONCPP_CACHED_JSONCPP_DIR_DETAILS}") + #message("Updating jsoncpp cache variables! ${__jsoncpp_info_string}") + set(JSONCPP_CACHED_JSONCPP_DIR_DETAILS "${__jsoncpp_info_string}" CACHE INTERNAL "" FORCE) + unset(JSONCPP_IMPORTED_LIBRARY_SHARED) + unset(JSONCPP_IMPORTED_LIBRARY_STATIC) + unset(JSONCPP_IMPORTED_LIBRARY) + unset(JSONCPP_IMPORTED_INCLUDE_DIRS) + unset(JSONCPP_IMPORTED_LIBRARY_IS_SHARED) + + # if(__jsoncpp_have_jsoncpplib) is equivalent to if(TARGET jsoncpp_lib) except it excludes our + # "invented" jsoncpp_lib interface targets, made for convenience purposes after this block. + + if(__jsoncpp_have_jsoncpplib AND TARGET jsoncpp_lib_static) + + # A veritable cache of riches - we have both shared and static! + set(JSONCPP_IMPORTED_LIBRARY_SHARED jsoncpp_lib CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY_STATIC jsoncpp_lib_static CACHE INTERNAL "" FORCE) + if(WIN32 OR CYGWIN OR MINGW) + # DLL platforms: static library should be default + set(JSONCPP_IMPORTED_LIBRARY ${JSONCPP_IMPORTED_LIBRARY_STATIC} CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED FALSE CACHE INTERNAL "" FORCE) + else() + # Other platforms - might require PIC to be linked into shared libraries, so safest to prefer shared. + set(JSONCPP_IMPORTED_LIBRARY ${JSONCPP_IMPORTED_LIBRARY_SHARED} CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED TRUE CACHE INTERNAL "" FORCE) endif() - # As a convenience... - if(TARGET jsoncpp_lib_static AND NOT TARGET jsoncpp_lib) - add_library(jsoncpp_lib INTERFACE) - target_link_libraries(jsoncpp_lib INTERFACE jsoncpp_lib_static) + elseif(TARGET jsoncpp_lib_static) + # Well, only one variant, but we know for sure that it's static. + set(JSONCPP_IMPORTED_LIBRARY_STATIC jsoncpp_lib_static CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY jsoncpp_lib_static CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED FALSE CACHE INTERNAL "" FORCE) + + elseif(__jsoncpp_have_jsoncpplib AND __jsoncpp_lib_type STREQUAL "STATIC_LIBRARY") + # We were able to figure out the mystery library is static! + set(JSONCPP_IMPORTED_LIBRARY_STATIC jsoncpp_lib CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY jsoncpp_lib CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED FALSE CACHE INTERNAL "" FORCE) + + elseif(__jsoncpp_have_jsoncpplib AND __jsoncpp_lib_type STREQUAL "SHARED_LIBRARY") + # We were able to figure out the mystery library is shared! + set(JSONCPP_IMPORTED_LIBRARY_SHARED jsoncpp_lib CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY jsoncpp_lib CACHE INTERNAL "" FORCE) + set(JSONCPP_IMPORTED_LIBRARY_IS_SHARED TRUE CACHE INTERNAL "" FORCE) + + elseif(__jsoncpp_have_jsoncpplib) + # One variant, and we have no idea if this is just an old version or if + # this is shared based on the target name alone. Hmm. + set(JSONCPP_IMPORTED_LIBRARY jsoncpp_lib CACHE INTERNAL "" FORCE) + endif() + + # Now, we need include directories. Can't just limit this to old CMakes, since + # new CMakes might be used to build projects designed to support older ones. + if(__jsoncpp_have_jsoncpplib) + get_property(__jsoncpp_interface_include_dirs TARGET jsoncpp_lib PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + if(__jsoncpp_interface_include_dirs) + set(JSONCPP_IMPORTED_INCLUDE_DIRS "${__jsoncpp_interface_include_dirs}" CACHE INTERNAL "" FORCE) + endif() + endif() + if(TARGET jsoncpp_lib_static AND NOT JSONCPP_IMPORTED_INCLUDE_DIRS) + get_property(__jsoncpp_interface_include_dirs TARGET jsoncpp_lib_static PROPERTY INTERFACE_INCLUDE_DIRECTORIES) + if(__jsoncpp_interface_include_dirs) + set(JSONCPP_IMPORTED_INCLUDE_DIRS "${__jsoncpp_interface_include_dirs}" CACHE INTERNAL "" FORCE) endif() endif() endif() +# As a convenience... +if(TARGET jsoncpp_lib_static AND NOT TARGET jsoncpp_lib) + add_library(jsoncpp_lib INTERFACE) + target_link_libraries(jsoncpp_lib INTERFACE jsoncpp_lib_static) +endif() + if(JSONCPP_IMPORTED_LIBRARY) if(NOT JSONCPP_IMPORTED_INCLUDE_DIRS) # OK, so we couldn't get it from the target... maybe we can figure it out from jsoncpp_DIR. @@ -146,6 +213,7 @@ if(JSONCPP_IMPORTED_LIBRARY) find_package_handle_standard_args(JsonCpp DEFAULT_MSG + jsoncpp_DIR JSONCPP_IMPORTED_LIBRARY JSONCPP_IMPORTED_INCLUDE_DIRS) endif() @@ -173,6 +241,14 @@ if(JSONCPP_FOUND) INTERFACE_INCLUDE_DIRECTORIES "${JSONCPP_IMPORTED_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${JSONCPP_IMPORTED_LIBRARY_STATIC}") endif() + + # Hide the stuff we didn't, and no longer, need. + if(NOT JsonCpp_LIBRARY) + unset(JsonCpp_LIBRARY CACHE) + endif() + if(NOT JsonCpp_INCLUDE_DIR) + unset(JsonCpp_INCLUDE_DIR CACHE) + endif() endif() set(JSONCPP_LIBRARY ${JSONCPP_IMPORTED_LIBRARY}) @@ -308,10 +384,9 @@ if(NOT JSONCPP_FOUND) add_library(JsonCpp::JsonCpp ALIAS jsoncpp_interface) endif() endif() - mark_as_advanced(JsonCpp_INCLUDE_DIR JsonCpp_LIBRARY) endif() endif() if(JSONCPP_FOUND) - mark_as_advanced(jsoncpp_DIR) + mark_as_advanced(jsoncpp_DIR JsonCpp_INCLUDE_DIR JsonCpp_LIBRARY) endif() diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake index 9a35dbf..f69c68a 100644 --- a/cmake/FindSDL2.cmake +++ b/cmake/FindSDL2.cmake @@ -16,18 +16,25 @@ # Set up architectures (for windows) and prefixes (for mingw builds) if(WIN32) + if(MINGW) + include(MinGWSearchPathExtras OPTIONAL) + if(MINGWSEARCH_TARGET_TRIPLE) + set(SDL2_PREFIX ${MINGWSEARCH_TARGET_TRIPLE}) + endif() + endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8) set(SDL2_LIB_PATH_SUFFIX lib/x64) - if(NOT MSVC) + if(NOT MSVC AND NOT SDL2_PREFIX) set(SDL2_PREFIX x86_64-w64-mingw32) endif() else() set(SDL2_LIB_PATH_SUFFIX lib/x86) - if(NOT MSVC) + if(NOT MSVC AND NOT SDL2_PREFIX) set(SDL2_PREFIX i686-w64-mingw32) endif() endif() endif() + if(SDL2_PREFIX) set(SDL2_ORIGPREFIXPATH ${CMAKE_PREFIX_PATH}) if(SDL2_ROOT_DIR) @@ -38,6 +45,9 @@ if(SDL2_PREFIX) list(APPEND CMAKE_PREFIX_PATH "${_prefix}/${SDL2_PREFIX}") endforeach() endif() + if(MINGWSEARCH_PREFIXES) + list(APPEND CMAKE_PREFIX_PATH ${MINGWSEARCH_PREFIXES}) + endif() endif() # Invoke pkgconfig for hints @@ -182,15 +192,15 @@ if(SDL2_FOUND) ) endif() - if(APPLE) - # Need Cocoa here, is always a framework - find_library(SDL2_COCOA_LIBRARY Cocoa) - list(APPEND SDL2_EXTRA_REQUIRED SDL2_COCOA_LIBRARY) - if(SDL2_COCOA_LIBRARY) - set_target_properties(SDL2::SDL2 PROPERTIES - IMPORTED_LINK_INTERFACE_LIBRARIES ${SDL2_COCOA_LIBRARY}) - endif() - endif() + if(APPLE) + # Need Cocoa here, is always a framework + find_library(SDL2_COCOA_LIBRARY Cocoa) + list(APPEND SDL2_EXTRA_REQUIRED SDL2_COCOA_LIBRARY) + if(SDL2_COCOA_LIBRARY) + set_target_properties(SDL2::SDL2 PROPERTIES + IMPORTED_LINK_INTERFACE_LIBRARIES ${SDL2_COCOA_LIBRARY}) + endif() + endif() # Compute what to do with SDL2main @@ -201,7 +211,7 @@ if(SDL2_FOUND) set_target_properties(SDL2::SDL2main_real PROPERTIES IMPORTED_LOCATION "${SDL2_SDLMAIN_LIBRARY}") - list(APPEND SDL2MAIN_LIBRARIES SDL2::SDL2main_real) + set(SDL2MAIN_LIBRARIES SDL2::SDL2main_real ${SDL2MAIN_LIBRARIES}) endif() if(MINGW) # MinGW requires some additional libraries to appear earlier in the link line. diff --git a/cmake/FindWindowsSDK.cmake b/cmake/FindWindowsSDK.cmake index 17d9342..e136b89 100644 --- a/cmake/FindWindowsSDK.cmake +++ b/cmake/FindWindowsSDK.cmake @@ -30,9 +30,17 @@ # get_windowssdk_library_dirs( ) - Find the architecture-appropriate # library directories corresponding to the SDK directory you pass in (or NOTFOUND if none) # +# get_windowssdk_library_dirs_multiple( ...) - Find the architecture-appropriate +# library directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. +# Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. +# # get_windowssdk_include_dirs( ) - Find the # include directories corresponding to the SDK directory you pass in (or NOTFOUND if none) # +# get_windowssdk_include_dirs_multiple( ...) - Find the +# include directories corresponding to the SDK directories you pass in, in order, skipping those not found. NOTFOUND if none at all. +# Good for passing WINDOWSSDK_DIRS or WINDOWSSDK_DIRS to if you really just want a file and don't care where from. +# # Requires these CMake modules: # FindPackageHandleStandardArgs (known included with CMake >=2.6.2) # @@ -65,6 +73,7 @@ macro(_winsdk_announce) endmacro() set(_winsdk_win10vers + 10.0.14393.0 # Redstone aka Win10 1607 "Anniversary Update" 10.0.10586.0 # TH2 aka Win10 1511 10.0.10240.0 # Win10 RTM 10.0.10150.0 # just ucrt @@ -237,7 +246,8 @@ if(MSVC AND NOT _WINDOWSSDK_IGNOREMSVC) # OK, we're VC11 or newer and not using a backlevel or XP-compatible toolset. # These versions have no XP (and possibly Vista pre-SP1) support set(_winsdk_vistaonly_ok ON) - if(_WINDOWSSDK_ANNOUNCE AND NOT WINDOWSSDK_DIRS) + if(_WINDOWSSDK_ANNOUNCE AND NOT _WINDOWSSDK_VISTAONLY_PESTERED) + set(_WINDOWSSDK_VISTAONLY_PESTERED ON CACHE INTERNAL "" FORCE) message(STATUS "FindWindowsSDK: Detected Visual Studio 2012 or newer, not using the _xp toolset variant: including SDK versions that drop XP support in search!") endif() endif() @@ -498,7 +508,7 @@ if(WINDOWSSDK_FOUND) set(${_var} "NOTFOUND" PARENT_SCOPE) endfunction() function(get_windowssdk_library_dirs _winsdk_dir _var) - set(_result) + set(_dirs) set(_suffixes "lib${_winsdk_archbare}" # SDKs like 7.1A "lib/${_winsdk_arch}" # just because some SDKs have x86 dir and root dir @@ -532,6 +542,7 @@ if(WINDOWSSDK_FOUND) endif() endforeach() + # Look in each Win10+ SDK version for the components foreach(_win10ver ${_winsdk_win10vers}) foreach(_component um km ucrt mmos) list(APPEND _suffixes "lib/${_win10ver}/${_component}/${_winsdk_arch8}") @@ -542,18 +553,18 @@ if(WINDOWSSDK_FOUND) # Check to see if a library actually exists here. file(GLOB _libs "${_winsdk_dir}/${_suffix}/*.lib") if(_libs) - list(APPEND _result "${_winsdk_dir}/${_suffix}") + list(APPEND _dirs "${_winsdk_dir}/${_suffix}") endif() endforeach() - if(NOT _result) - set(_result NOTFOUND) + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) else() - list(REMOVE_DUPLICATES _result) + list(REMOVE_DUPLICATES _dirs) endif() - set(${_var} ${_result} PARENT_SCOPE) + set(${_var} ${_dirs} PARENT_SCOPE) endfunction() function(get_windowssdk_include_dirs _winsdk_dir _var) - set(_result) + set(_dirs) set(_subdirs shared um winrt km wdf mmos ucrt) set(_suffixes Include) @@ -572,14 +583,44 @@ if(WINDOWSSDK_FOUND) # Check to see if a header file actually exists here. file(GLOB _headers "${_winsdk_dir}/${_suffix}/*.h") if(_headers) - list(APPEND _result "${_winsdk_dir}/${_suffix}") + list(APPEND _dirs "${_winsdk_dir}/${_suffix}") + endif() + endforeach() + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) + else() + list(REMOVE_DUPLICATES _dirs) + endif() + set(${_var} ${_dirs} PARENT_SCOPE) + endfunction() + function(get_windowssdk_library_dirs_multiple _var) + set(_dirs) + foreach(_sdkdir ${ARGN}) + get_windowssdk_library_dirs("${_sdkdir}" _current_sdk_libdirs) + if(_current_sdk_libdirs) + list(APPEND _dirs ${_current_sdk_libdirs}) + endif() + endforeach() + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) + else() + list(REMOVE_DUPLICATES _dirs) + endif() + set(${_var} ${_dirs} PARENT_SCOPE) + endfunction() + function(get_windowssdk_include_dirs_multiple _var) + set(_dirs) + foreach(_sdkdir ${ARGN}) + get_windowssdk_include_dirs("${_sdkdir}" _current_sdk_incdirs) + if(_current_sdk_libdirs) + list(APPEND _dirs ${_current_sdk_incdirs}) endif() endforeach() - if(NOT _result) - set(_result NOTFOUND) + if("${_dirs}" STREQUAL "") + set(_dirs NOTFOUND) else() - list(REMOVE_DUPLICATES _result) + list(REMOVE_DUPLICATES _dirs) endif() - set(${_var} ${_result} PARENT_SCOPE) + set(${_var} ${_dirs} PARENT_SCOPE) endfunction() endif() diff --git a/cmake/InstallDebugSymbols.cmake b/cmake/InstallDebugSymbols.cmake new file mode 100644 index 0000000..25cd6ba --- /dev/null +++ b/cmake/InstallDebugSymbols.cmake @@ -0,0 +1,85 @@ +# Defines a function to install the symbols for a target +# +# install_debug_symbols(TARGETS [...] [DESTINATION ] +# [CONFIGURATIONS [...]] [PASSTHRU [...]]) +# +# DESTINATION is only optional if CMAKE_INSTALL_BINDIR and CMAKE_INSTALL_LIBDIR are set, +# then it will use CMAKE_INSTALL_BINDIR for executables (and DLLs) and CMAKE_INSTALL_LIBDIR +# for libraries (static libraries only on DLL platforms). +# +# CONFIGURATIONS are the config names for which symbols (PDB files) are expected - +# the default of RelWithDebInfo Debug is correct unless you've dramatically changed +# the set of configs. +# +# Anything after PASSTHRU is passed directly to the install( command after the arguments +# that the function generates. +# +# Currently a no-op if using CMake pre-3.2 (can't use generator expressions before then +# to get symbol location) or if not using MSVC (MSVC keeps its symbols separate in PDB files +# necessitating this function in the first place). +# +# Original Author: +# 2015, 2017 Ryan Pavlik +# http://ryanpavlik.com +# +# Copyright Sensics, Inc. 2015, 2017. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +if(MSVC AND NOT CMAKE_VERSION VERSION_LESS 3.2) + include(CMakeParseArguments) + # debug symbols for MSVC: supported on CMake 3.2 and up where there's a + # generator expression for a target's PDB file + function(install_debug_symbols) + set(options) + set(oneValueArgs DESTINATION) + set(multiValueArgs TARGETS CONFIGURATIONS PASSTHRU) + cmake_parse_arguments(INSTALLSYMS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT INSTALLSYMS_DESTINATION AND NOT CMAKE_INSTALL_BINDIR AND NOT CMAKE_INSTALL_LIBDIR) + message(SEND_ERROR "install_debug_symbols call missing required DESTINATION argument") + return() + endif() + if(NOT INSTALLSYMS_TARGETS) + message(SEND_ERROR "install_debug_symbols call missing required TARGETS argument") + return() + endif() + if(NOT INSTALLSYMS_CONFIGURATIONS) + set(INSTALLSYMS_CONFIGURATIONS RelWithDebInfo Debug) + endif() + + # Wrap each config in a generator expression + set(HAS_SYMBOLS_CONDITION) + foreach(_config ${INSTALLSYMS_CONFIGURATIONS}) + list(APPEND HAS_SYMBOLS_CONDITION "$") + endif() + # make list comma separated + string(REPLACE ";" "," HAS_SYMBOLS_CONDITION "${HAS_SYMBOLS_CONDITION}") + # Wrap in an "OR" generator expression + set(HAS_SYMBOLS_CONDITION "$") + + set(EXTRA_INSTALL_ARGS ${INSTALLSYMS_PASSTHRU} ${INSTALLSYMS_UNPARSED_ARGUMENTS}) + if(INSTALLSYMS_DESTINATION) + set(DEST ${INSTALLSYMS_DESTINATION}) + endif() + foreach(_target ${INSTALLSYMS_TARGETS}) + if(NOT INSTALLSYMS_DESTINATION) + get_target_property(_target_type ${_target} TYPE) + if("${_target_type}" STREQUAL "EXECUTABLE" OR "${_target_type}" STREQUAL "SHARED_LIBRARY") + # exe or dll: put it alongside the runtime component + set(DEST ${CMAKE_INSTALL_BINDIR}) + else() + set(DEST ${CMAKE_INSTALL_LIBDIR}) + endif() + endif() + install(FILES $<${HAS_SYMBOLS_CONDITION}:$> + DESTINATION ${DEST} + ${EXTRA_INSTALL_ARGS}) + endforeach() + endfunction() +else() + function(install_debug_symbols) + # do nothing if too old of CMake or not MSVC. + endfunction() +endif() diff --git a/cmake/StashMapConfig.cmake b/cmake/StashMapConfig.cmake new file mode 100644 index 0000000..d052028 --- /dev/null +++ b/cmake/StashMapConfig.cmake @@ -0,0 +1,86 @@ +# Manipulate CMAKE_MAP_IMPORTED_CONFIG_ cautiously and reversibly. +# +# In all usage docs, is a configuration name in all caps (RELEASE, DEBUG, +# RELWITHDEBINFO, MINSIZEREL, and NONE are the ones made by default - NONE is how +# targets are exported from single-config generators where CMAKE_BUILD_TYPE isn't set.) +# +# stash_map_config( ) and unstash_map_config() +# +# Saves+changes and restores the value (or unset-ness) of CMAKE_MAP_IMPORTED_CONFIG_${config}. +# Re-entrant calls OK - this does actually "push" and "pop" +# +# stash_common_map_config() and unstash_common_map_config() +# +# Calls stash_map_config/unstash_map_config for each configuration with sensible +# defaults based on the platform. +# +# Original Author: +# 2015, 2017 Ryan Pavlik +# http://ryanpavlik.com +# +# Copyright Sensics, Inc. 2015, 2017. +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +macro(stash_map_config config) + string(TOUPPER "${config}" smc_config) + string(TOUPPER "${ARGN}" smc_new) + # Re-entrancy protection - push an entry onto a list + list(APPEND smc_IN_MAP_CONFIG_STASH_${smc_config} yes) + list(LENGTH smc_IN_MAP_CONFIG_STASH_${smc_config} smc_IN_MAP_CONFIG_STASH_LEN) + + # Actually perform the saving and replacement of CMAKE_MAP_IMPORTED_CONFIG_${config} + set(smc_var smc_OLD_CMAKE_MAP_IMPORTED_CONFIG_${smc_config}_${smc_IN_MAP_CONFIG_STASH_LEN}) + message(STATUS "Stashing to ${smc_var}") + if(DEFINED CMAKE_MAP_IMPORTED_CONFIG_${smc_config}) + set(${smc_var} ${CMAKE_MAP_IMPORTED_CONFIG_${smc_config}}) + else() + unset(${smc_var}) + endif() + set(CMAKE_MAP_IMPORTED_CONFIG_${smc_config} ${smc_new}) +endmacro() + +macro(unstash_map_config config) + string(TOUPPER "${config}" smc_config) + if(NOT DEFINED smc_IN_MAP_CONFIG_STASH_${smc_config}) + # Nobody actually called the matching stash... + return() + endif() + # Get stack size so we know which entries to restore. + list(LENGTH smc_IN_MAP_CONFIG_STASH_${smc_config} smc_IN_MAP_CONFIG_STASH_LEN) + # Other half of re-entrancy protection - pop an entry off a list + list(REMOVE_AT smc_IN_MAP_CONFIG_STASH_${smc_config} -1) + + # Restoration of CMAKE_MAP_IMPORTED_CONFIG_${config} + set(smc_var smc_OLD_CMAKE_MAP_IMPORTED_CONFIG_${smc_config}_${smc_IN_MAP_CONFIG_STASH_LEN}) + if(DEFINED ${smc_var}) + set(CMAKE_MAP_IMPORTED_CONFIG_${smc_config} ${${smc_var}}) + unset(${smc_var}) + else() + unset(CMAKE_MAP_IMPORTED_CONFIG_${smc_config}) + endif() +endmacro() + +macro(stash_common_map_config) + if(MSVC) + # Can't do this - different runtimes, incompatible ABI, etc. + set(smc_DEBUG_FALLBACK) + stash_map_config(DEBUG DEBUG) + else() + set(smc_DEBUG_FALLBACK DEBUG) + stash_map_config(DEBUG DEBUG RELWITHDEBINFO RELEASE MINSIZEREL NONE) + endif() + stash_map_config(RELEASE RELEASE RELWITHDEBINFO MINSIZEREL NONE ${smc_DEBUG_FALLBACK}) + stash_map_config(RELWITHDEBINFO RELWITHDEBINFO RELEASE MINSIZEREL NONE ${smc_DEBUG_FALLBACK}) + stash_map_config(MINSIZEREL MINSIZEREL RELEASE RELWITHDEBINFO NONE ${smc_DEBUG_FALLBACK}) + stash_map_config(NONE NONE RELEASE RELWITHDEBINFO MINSIZEREL ${smc_DEBUG_FALLBACK}) +endmacro() + +macro(unstash_common_map_config) + unstash_map_config(DEBUG) + unstash_map_config(RELEASE) + unstash_map_config(RELWITHDEBINFO) + unstash_map_config(MINSIZEREL) + unstash_map_config(NONE) +endmacro() diff --git a/cmake/osvrRenderManagerConfig.cmake b/cmake/osvrRenderManagerConfig.cmake index 45673af..09de72d 100644 --- a/cmake/osvrRenderManagerConfig.cmake +++ b/cmake/osvrRenderManagerConfig.cmake @@ -18,19 +18,19 @@ set(OSVRRM_NEED_GLEW @OSVRRM_NEED_GLEW@) set(OSVRRM_PREV_CMAKE_MODULES ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" ${CMAKE_MODULE_PATH}) include("${CMAKE_CURRENT_LIST_DIR}/osvrRenderManagerConfigBuildTreeHints.cmake" OPTIONAL) -include(osvrStashMapConfig) +include(StashMapConfig) include(CMakeFindDependencyMacro) if(OSVRRM_NEED_SDL2) # TODO - #find_dependency(SDL2) + #find_dependency(SDL2) endif() if(OSVRRM_NEED_GLEW) # TODO - #find_dependency(GLEW) + #find_dependency(GLEW) endif() # Set up config mapping -osvr_stash_common_map_config() +stash_common_map_config() find_dependency(osvr) @@ -41,7 +41,7 @@ set(CMAKE_MODULE_PATH ${OSVRRM_PREV_CMAKE_MODULES}) include("${CMAKE_CURRENT_LIST_DIR}/osvrRenderManagerTargets.cmake") # Undo our changes for later consumers -osvr_unstash_common_map_config() +unstash_common_map_config() if(NOT TARGET osvrRenderManager::osvrRenderManagerCpp) add_library(osvrRenderManager::osvrRenderManagerCpp INTERFACE IMPORTED) diff --git a/cmake/osvrStashMapConfig.cmake b/cmake/osvrStashMapConfig.cmake deleted file mode 100644 index 3183fe9..0000000 --- a/cmake/osvrStashMapConfig.cmake +++ /dev/null @@ -1,61 +0,0 @@ -# Manipulate CMAKE_MAP_IMPORTED_CONFIG_ cautiously and reversibly. -macro(osvr_stash_map_config config) - # Re-entrancy protection - list(APPEND OSVR_IN_MAP_CONFIG_STASH_${config} yes) - list(LENGTH OSVR_IN_MAP_CONFIG_STASH_${config} OSVR_IN_MAP_CONFIG_STASH_LEN) - if(OSVR_IN_MAP_CONFIG_STASH_LEN GREATER 1) - # Not the first stash, get out. - return() - endif() - - # Actually perform the saving and replacement of CMAKE_MAP_IMPORTED_CONFIG_${config} - if(DEFINED CMAKE_MAP_IMPORTED_CONFIG_${config}) - set(OSVR_OLD_CMAKE_MAP_IMPORTED_CONFIG_${config} ${CMAKE_MAP_IMPORTED_CONFIG_${config}}) - endif() - set(CMAKE_MAP_IMPORTED_CONFIG_${config} ${ARGN}) -endmacro() - -macro(osvr_unstash_map_config config) - if(NOT DEFINED OSVR_IN_MAP_CONFIG_STASH_${config}) - # Nobody actually called the matching stash... - return() - endif() - # Other half of re-entrancy protection - list(REMOVE_AT OSVR_IN_MAP_CONFIG_STASH_${config} -1) - list(LENGTH OSVR_IN_MAP_CONFIG_STASH_${config} OSVR_IN_MAP_CONFIG_STASH_LEN) - if(OSVR_IN_MAP_CONFIG_STASH_LEN GREATER 0) - # someone still in here - return() - endif() - - # Restoration of CMAKE_MAP_IMPORTED_CONFIG_${config} - if(DEFINED OSVR_OLD_CMAKE_MAP_IMPORTED_CONFIG_${config}) - set(CMAKE_MAP_IMPORTED_CONFIG_${config} ${OSVR_OLD_CMAKE_MAP_IMPORTED_CONFIG_${config}}) - unset(OSVR_OLD_CMAKE_MAP_IMPORTED_CONFIG_${config}) - else() - unset(CMAKE_MAP_IMPORTED_CONFIG_${config}) - endif() -endmacro() - -macro(osvr_stash_common_map_config) - if(MSVC) - # Can't do this - different runtimes, incompatible ABI, etc. - set(OSVR_DEBUG_FALLBACK) - osvr_stash_map_config(DEBUG DEBUG) - else() - set(OSVR_DEBUG_FALLBACK DEBUG) - osvr_stash_map_config(DEBUG DEBUG RELWITHDEBINFO RELEASE MINSIZEREL NONE) - endif() - osvr_stash_map_config(RELEASE RELEASE RELWITHDEBINFO MINSIZEREL NONE ${OSVR_DEBUG_FALLBACK}) - osvr_stash_map_config(RELWITHDEBINFO RELWITHDEBINFO RELEASE MINSIZEREL NONE ${OSVR_DEBUG_FALLBACK}) - osvr_stash_map_config(MINSIZEREL MINSIZEREL RELEASE RELWITHDEBINFO NONE ${OSVR_DEBUG_FALLBACK}) - osvr_stash_map_config(NONE NONE RELEASE RELWITHDEBINFO MINSIZEREL ${OSVR_DEBUG_FALLBACK}) -endmacro() - -macro(osvr_unstash_common_map_config) - osvr_unstash_map_config(DEBUG) - osvr_unstash_map_config(RELEASE) - osvr_unstash_map_config(RELWITHDEBINFO) - osvr_unstash_map_config(MINSIZEREL) - osvr_unstash_map_config(NONE) -endmacro()