From 850976eba98199ed0cd4db5abae8916521434ff0 Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Sat, 24 Jun 2023 18:50:32 +0200 Subject: [PATCH] cmake: Add Windows component to CMake build framework 3.0 --- CMakePresets.json | 67 +--- buildspec.json | 17 +- cmake/32bit/projects.cmake | 63 ++++ cmake/common/.cmake-format.json | 41 -- cmake/common/cpackconfig_common.cmake | 2 + cmake/common/helpers_common.cmake | 2 +- cmake/finders/FindAMF.cmake | 92 +++++ cmake/finders/FindDetours.cmake | 124 ++++++ cmake/windows/FindPython.cmake | 103 +++++ cmake/windows/buildspec.cmake | 29 ++ cmake/windows/compilerconfig.cmake | 49 +++ cmake/windows/cpackconfig.cmake | 15 + cmake/windows/defaults.cmake | 35 ++ cmake/windows/helpers.cmake | 523 ++++++++++++++++++++++++++ cmake/windows/idlfilehelper.cmake | 27 ++ 15 files changed, 1086 insertions(+), 103 deletions(-) create mode 100644 cmake/32bit/projects.cmake delete mode 100644 cmake/common/.cmake-format.json create mode 100644 cmake/finders/FindAMF.cmake create mode 100644 cmake/finders/FindDetours.cmake create mode 100644 cmake/windows/FindPython.cmake create mode 100644 cmake/windows/buildspec.cmake create mode 100644 cmake/windows/compilerconfig.cmake create mode 100644 cmake/windows/cpackconfig.cmake create mode 100644 cmake/windows/defaults.cmake create mode 100644 cmake/windows/helpers.cmake create mode 100644 cmake/windows/idlfilehelper.cmake diff --git a/CMakePresets.json b/CMakePresets.json index a849f4554..4efc4012c 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -20,7 +20,6 @@ "cacheVariables": { "ENABLE_BROWSER": true, "CMAKE_OSX_DEPLOYMENT_TARGET": {"type": "STRING", "value": "11.0"}, - "OBS_CMAKE_VERSION": {"type": "STRING", "value": "3.0.0"}, "OBS_CODESIGN_TEAM": {"type": "STRING", "value": "$penv{CODESIGN_TEAM}"}, "OBS_CODESIGN_IDENTITY": {"type": "STRING", "value": "$penv{CODESIGN_IDENT}"}, "OBS_PROVISIONING_PROFILE": {"type": "STRING", "value": "$penv{PROVISIONING_PROFILE}"}, @@ -57,12 +56,7 @@ "ENABLE_WAYLAND": true, "ENABLE_VLC": true, "QT_VERSION": "6", - "CMAKE_BUILD_TYPE": "Debug", - "OBS_CMAKE_VERSION": "2.0.0", - "CMAKE_PREFIX_PATH": { - "type": "PATH", - "value": "" - } + "CMAKE_BUILD_TYPE": "Debug" } }, { @@ -97,23 +91,13 @@ "cacheVariables": { "ENABLE_WAYLAND": true, "ENABLE_VLC": true, - "QT_VERSION": "6", - "CMAKE_BUILD_TYPE": "Debug", - "OBS_CMAKE_VERSION": "2.0.0", - "CMAKE_PREFIX_PATH": { - "type": "PATH", - "value": "" - }, - "CEF_ROOT_DIR": { - "type": "PATH", - "value": "" - } + "QT_VERSION": {"type": "STRING", "value": "6"}, + "CMAKE_BUILD_TYPE": {"type": "STRING", "value": "Debug"} } }, { "name": "linux-ci-x86_64", "inherits": ["linux-x86_64"], - "hidden": true, "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo" } @@ -131,7 +115,7 @@ { "name": "windows-x64", "displayName": "Windows x64", - "description": "obs-studio for Windows (x64)", + "description": "Default Windows build (x64)", "condition": { "type": "equals", "lhs": "${hostSystemName}", @@ -140,45 +124,22 @@ "architecture": "x64", "binaryDir": "${sourceDir}/build_x64", "generator": "Visual Studio 17 2022", - "warnings": {"dev": true, "deprecated": true}, "cacheVariables": { - "QT_VERSION": "6", - "CMAKE_BUILD_TYPE": "Debug", - "OBS_WINDOWS_LEGACY_DIRS": true, - "CMAKE_SYSTEM_VERSION": "10.0.18363.657", - "OBS_CMAKE_VERSION": "2.0.0", - "CMAKE_PREFIX_PATH": { - "type": "PATH", - "value": "" - }, - "CEF_ROOT_DIR": { - "type": "PATH", - "value": "" - }, - "VLC_PATH": { - "type": "PATH", - "value": "" - } + "OBS_CMAKE_VERSION": {"type": "STRING", "value": "3.0.0"}, + "ENABLE_BROWSER": true, + "VIRTUALCAM_GUID": {"type": "STRING", "value": "A3FCE0F5-3493-419F-958A-ABA1250EC20B"}, + "ENABLE_CCACHE": false } }, { "name": "windows-ci-x64", - "inherits": "windows-x64", - "hidden": true, + "displayName": "Windows x64 (CI)", + "description": "CI Windows build (x64)", + "inherits": ["windows-x64"], + "warnings": {"dev": true, "deprecated": true}, "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" - } - }, - { - "name": "windows-release-x64", - "displayName": "Windowx x64 (Release)", - "description": "obs-studio for Windows (x64) - Release Configuration", - "inherits": "windows-x64", - "cacheVariables": { - "ENABLE_RELEASE_BUILD": true, - "ENABLE_BROWSER": true, - "ENABLE_VLC": true, - "VIRTUALCAM_GUID": { "type": "STRING", "value": "A3FCE0F5-3493-419F-958A-ABA1250EC20B"} + "CMAKE_COMPILE_WARNING_AS_ERROR": true, + "ENABLE_CCACHE": false } } ], diff --git a/buildspec.json b/buildspec.json index e60fc6042..835ad700f 100644 --- a/buildspec.json +++ b/buildspec.json @@ -7,6 +7,7 @@ "hashes": { "macos-universal": "a0d2e03f0ea79681634c31627430a220d9b62113d6ff58174d0bdab6fafdd32b", "windows-x64": "1b12e86e2d62a97a889866d66b95fe47ddc6f7fa9b13e88aedfab4ea9e298ea2", + "windows-x86": "8c6bfda01ec7d38a50a61ac4954dc00d6fcb171830a7f32593c5bd20a44be3a9", "linux-x86_64": "1b82ab4247bc2730ae84caa5a009e76637eac77b05bfb4b4a2bae610e7a75262" } }, @@ -37,14 +38,14 @@ "macos-x86_64": 2, "macos-arm64": 2 } - }, - "vlc": { - "version": "3.0.8", - "baseUrl": "https://downloads.videolan.org/vlc", - "label": "VLC", - "hashes": { - "windows-x64": "91f589ef69fce51645a3ecbb215b405c98db7b891479474ec3b5ed3b63c25e4a" - } + } + }, + "tools": { + "ccache-win": { + "version": "4.8.1", + "baseUrl": "https://github.com/ccache/ccache/releases/download/", + "label": "Ccache for Windows x64", + "hash": "ca59770e9f46b59d6bec6e7036a17a27d601a0a5a0a721fe8e03fea734ccf732" } }, "platformConfig": { diff --git a/cmake/32bit/projects.cmake b/cmake/32bit/projects.cmake new file mode 100644 index 000000000..00111e51e --- /dev/null +++ b/cmake/32bit/projects.cmake @@ -0,0 +1,63 @@ +# OBS CMake 32-bit slice module + +include_guard(GLOBAL) + +include(compilerconfig) + +# legacy_check: Helper macro to automatically include available 32-bit build script +macro(legacy_check) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/32bit-build.cmake") + include(cmake/32bit-build.cmake) + endif() + return() +endmacro() + +# cmake-format: off +macro(target_disable_feature) +endmacro() + +macro(target_disable) +endmacro() +# cmake-format: on + +# check_uuid: Helper function to check for valid UUID +function(check_uuid uuid_string return_value) + set(valid_uuid TRUE) + set(uuid_token_lengths 8 4 4 4 12) + set(token_num 0) + + string(REPLACE "-" ";" uuid_tokens ${uuid_string}) + list(LENGTH uuid_tokens uuid_num_tokens) + + if(uuid_num_tokens EQUAL 5) + message(DEBUG "UUID ${uuid_string} is valid with 5 tokens.") + foreach(uuid_token IN LISTS uuid_tokens) + list(GET uuid_token_lengths ${token_num} uuid_target_length) + string(LENGTH "${uuid_token}" uuid_actual_length) + if(uuid_actual_length EQUAL uuid_target_length) + string(REGEX MATCH "[0-9a-fA-F]+" uuid_hex_match ${uuid_token}) + if(NOT uuid_hex_match STREQUAL uuid_token) + set(valid_uuid FALSE) + break() + endif() + else() + set(valid_uuid FALSE) + break() + endif() + math(EXPR token_num "${token_num}+1") + endforeach() + else() + set(valid_uuid FALSE) + endif() + message(DEBUG "UUID ${uuid_string} valid: ${valid_uuid}") + # cmake-format: off + set(${return_value} ${valid_uuid} PARENT_SCOPE) + # cmake-format: on +endfunction() + +if(OS_WINDOWS) + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows/buildspec.cmake") + add_subdirectory(libobs) + add_subdirectory(plugins/win-capture) + add_subdirectory(plugins/win-dshow) +endif() diff --git a/cmake/common/.cmake-format.json b/cmake/common/.cmake-format.json deleted file mode 100644 index 75fd03ad3..000000000 --- a/cmake/common/.cmake-format.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "format": { - "line_width": 120, - "tab_size": 2, - "dangle_parens": false, - "enable_sort": true, - "autosort": true - }, - "additional_commands": { - "find_qt": { - "flags": [], - "kwargs": { - "COMPONENTS": "+", - "COMPONENTS_WIN": "+", - "COMPONENTS_MACOS": "+", - "COMPONENTS_LINUX": "+" - } - }, - "set_target_properties_obs": { - "pargs": 1, - "flags": [], - "kwargs": { - "PROPERTIES": { - "kwargs": { - "PREFIX": 1, - "OUTPUT_NAME": 1, - "FOLDER": 1, - "VERSION": 1, - "SOVERSION": 1, - "FRAMEWORK": 1, - "BUNDLE": 1, - "AUTOMOC": 1, - "AUTOUIC": 1, - "AUTORCC": 1, - "AUTOUIC_SEARCH_PATHS": 1 - } - } - } - } - } -} diff --git a/cmake/common/cpackconfig_common.cmake b/cmake/common/cpackconfig_common.cmake index a8bf55ca9..9846df72d 100644 --- a/cmake/common/cpackconfig_common.cmake +++ b/cmake/common/cpackconfig_common.cmake @@ -5,7 +5,9 @@ include_guard(GLOBAL) # Set default global CPack variables set(CPACK_PACKAGE_NAME obs-studio) set(CPACK_PACKAGE_VENDOR "${OBS_WEBSITE}") +set(CPACK_PACKAGE_HOMEPAGE_URL "${OBS_WEBSITE}") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${OBS_COMMENTS}") +set(CPACK_PACKAGE_CHECKSUM SHA256) set(CPACK_PACKAGE_VERSION_MAJOR ${OBS_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${OBS_VERSION_MINOR}) diff --git a/cmake/common/helpers_common.cmake b/cmake/common/helpers_common.cmake index db423731b..a7562752d 100644 --- a/cmake/common/helpers_common.cmake +++ b/cmake/common/helpers_common.cmake @@ -232,7 +232,7 @@ function(find_dependencies) list(GET gen_expression 0 gen_platform) list(GET gen_expression 1 gen_library) string(REPLACE "," ";" gen_platform "${gen_platform}") - if(CMAKE_HOST_SYSTEM_NAME IN_LIST platform) + if(CMAKE_SYSTEM_NAME IN_LIST platform) set(library "${gen_library}") else() continue() diff --git a/cmake/finders/FindAMF.cmake b/cmake/finders/FindAMF.cmake new file mode 100644 index 000000000..18cd4c10d --- /dev/null +++ b/cmake/finders/FindAMF.cmake @@ -0,0 +1,92 @@ +#[=======================================================================[.rst +FindAMF +------- + +FindModule for AMF and associated headers + +Imported Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 2.0 + +This module defines the :prop_tgt:`IMPORTED` target ``AMF::AMF``. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module sets the following variables: + +``AMF_FOUND`` + True, if headers were found. +``AMF_VERSION`` + Detected version of found AMF headers. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``AMF_INCLUDE_DIR`` + Directory containing ``AMF/core/Factory.h``. + +#]=======================================================================] + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-lint: disable=C0301 +# cmake-format: on + +include(FindPackageHandleStandardArgs) + +find_path( + AMF_INCLUDE_DIR + NAMES AMF/core/Factory.h + PATHS /usr/include /usr/local/include + DOC "AMF include directory") + +if(EXISTS "${AMF_INCLUDE_DIR}/AMF/core/Version.h") + file(STRINGS "${AMF_INCLUDE_DIR}/AMF/core/Version.h" _version_string + REGEX "^.*VERSION_(MAJOR|MINOR|RELEASE|BUILD_NUM)[ \t]+[0-9]+[ \t]*$") + + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _version_major "${_version_string}") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _version_minor "${_version_string}") + string(REGEX REPLACE ".*VERSION_RELEASE[ \t]+([0-9]+).*" "\\1" _version_release "${_version_string}") + + set(AMF_VERSION "${_version_major}.${_version_minor}.${_version_release}") + unset(_version_major) + unset(_version_minor) + unset(_version_release) +else() + if(NOT AMF_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find AMF version.") + endif() + set(AMF_VERSION 0.0.0) +endif() + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") + set(AMF_ERROR_REASON "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + set(AMF_ERROR_REASON "Ensure AMF headers are available in local library paths.") +endif() + +find_package_handle_standard_args( + AMF + REQUIRED_VARS AMF_INCLUDE_DIR + VERSION_VAR AMF_VERSION REASON_FAILURE_MESSAGE "${AMF_ERROR_REASON}") +mark_as_advanced(AMF_INCLUDE_DIR) +unset(AMF_ERROR_REASON) + +if(AMF_FOUND) + if(NOT TARGET AMF::AMF) + add_library(AMF::AMF INTERFACE IMPORTED) + set_target_properties(AMF::AMF PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${AMF_INCLUDE_DIR}") + endif() +endif() + +include(FeatureSummary) +set_package_properties( + AMF PROPERTIES + URL "https://github.com/GPUOpen-LibrariesAndSDKs/AMF" + DESCRIPTION + "AMF is a light-weight, portable multimedia framework that abstracts away most of the platform and API-specific details and allows for easy implementation of multimedia applications using a variety of technologies, such as DirectX 11, OpenGL, and OpenCL and facilitates an efficient interop between them." +) diff --git a/cmake/finders/FindDetours.cmake b/cmake/finders/FindDetours.cmake new file mode 100644 index 000000000..81c804fe3 --- /dev/null +++ b/cmake/finders/FindDetours.cmake @@ -0,0 +1,124 @@ +#[=======================================================================[.rst +FindDetours +----------- + +FindModule for Detours and associated libraries + +.. versionchanged:: 3.0 + Updated FindModule to CMake standards + +Imported Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 2.0 + +This module defines the :prop_tgt:`IMPORTED` target ``Detours::Detours``. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module sets the following variables: + +``Detours_FOUND`` + True, if all required components and the core library were found. +``Detours_VERSION`` + Detected version of found Detours libraries. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``Detours_LIBRARY`` + Path to the library component of Detours. +``Detours_INCLUDE_DIR`` + Directory containing ``detours.h``. + +#]=======================================================================] + +# cmake-format: off +# bmake-lint: disable=C0103 +# cmake-format: on + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_Detours QUIET detours) +endif() + +find_path( + Detours_INCLUDE_DIR + NAMES detours.h + HINTS ${PC_Detours_INCLUDE_DIRS} + DOC "Detours include directory") + +find_library( + Detours_IMPLIB + NAMES detours + HINTS ${PC_Detours_LIBRARY_DIRS} + DOC "Detours location") + +cmake_path(GET Detours_IMPLIB PARENT_PATH _implib_path) +cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") + +find_program( + Detours_LIBRARY + NAMES detours.dll + HINTS ${_implib_path} ${_bin_path} + DOC "Detours DLL location") + +if(NOT Detours_LIBRARY) + set(Detours_LIBRARY "${Detours_IMPLIB}") +endif() +unset(_implib_path) +unset(_bin_path) + +if(PC_Detours_VERSION VERSION_GREATER 0) + set(Detours_VERSION ${PC_Detours_VERSION}) +else() + if(NOT Detours_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find detours version.") + endif() + set(Detours_VERSION 0.0.0) +endif() + +find_package_handle_standard_args( + Detours + REQUIRED_VARS Detours_LIBRARY Detours_INCLUDE_DIR + VERSION_VAR Detours_VERSION REASON_FAILURE_MESSAGE "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") +mark_as_advanced(Detours_INCLUDE_DIR Detours_LIBRARY) + +if(Detours_FOUND) + if(NOT TARGET Detours::Detours) + if(IS_ABSOLUTE "${Detours_LIBRARY}") + if(DEFINED Detours_IMPLIB) + if(Detours_IMPLIB STREQUAL Detours_LIBRARY) + add_library(Detours::Detours STATIC IMPORTED) + else() + add_library(Detours::Detours SHARED IMPORTED) + set_property(TARGET Detours::Detours PROPERTY IMPORTED_IMPLIB "${Detours_IMPLIB}") + endif() + else() + add_library(Detours::Detours UNKNOWN IMPORTED) + endif() + + set_property(TARGET Detours::Detours PROPERTY IMPORTED_LOCATION "${Detours_LIBRARY}") + else() + add_library(Detours::Detours INTERFACE IMPORTED) + set_property(TARGET Detours::Detours PROPERTY IMPORTED_LIBNAME "${Detours_LIBRARY}") + endif() + + set_target_properties( + Detours::Detours + PROPERTIES INTERFACE_COMPILE_OPTIONS "${PC_Detours_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${Detours_INCLUDE_DIR}" + VERSION ${Detours_VERSION}) + endif() +endif() + +include(FeatureSummary) +set_package_properties( + Detours PROPERTIES + URL "https://github.com/microsoft/detours" + DESCRIPTION "Detours is a software package for monitoring and instrumenting API calls on Windows.") diff --git a/cmake/windows/FindPython.cmake b/cmake/windows/FindPython.cmake new file mode 100644 index 000000000..cc2adeae0 --- /dev/null +++ b/cmake/windows/FindPython.cmake @@ -0,0 +1,103 @@ +#[=======================================================================[.rst +FindPython +---------- + +FindModule for Python import libraries and header on Windows + +.. versionchanged:: 3.0 + Updated FindModule to CMake standards + +Imported Targets +^^^^^^^^^^^^^^^^ + +.. versionadded:: 2.0 + +This module defines the :prop_tgt:`IMPORTED` target ``Python::Python``. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module sets the following variables: + +``Python_FOUND`` + True, if all required components and the core library were found. +``Python_VERSION`` + Detected version of found Python libraries. +``Python_INCLUDE_DIRS`` + Include directories needed for Python. +``Python_LIBRARIES`` + Libraries needed to link to Python. + +Cache variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``Python_LIBRARY`` + Path to the library component of Python. +``Python_INCLUDE_DIR`` + Directory containing ``python.h``. + +#]=======================================================================] + +# cmake-format: off +# cmake-lint: disable=C0103 +# cmake-lint: disable=C0301 +# cmake-format: on + +include(FindPackageHandleStandardArgs) + +find_path( + Python_INCLUDE_DIR + NAMES Python.h + PATH_SUFFIXES include include/python + DOC "Python include directory") + +find_library( + Python_LIBRARY + NAMES python3 + PATHS lib + DOC "Python location") + +if(EXISTS "${Python_INCLUDE_DIR}/patchlevel.h") + file(STRINGS "${Python_INCLUDE_DIR}/patchlevel.h" _VERSION_STRING REGEX "^.*PY_VERSION[ \t]+\"[0-9\\.]+\"[ \t]*$") + string(REGEX REPLACE ".*PY_VERSION[ \t]+\"([0-9\\.]+)\".*" "\\1" Python_VERSION "${_VERSION_STRING}") +else() + if(NOT Python_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find Python version.") + endif() + set(Python_VERSION 0.0.0) +endif() + +find_package_handle_standard_args( + Python + REQUIRED_VARS Python_LIBRARY Python_INCLUDE_DIR + VERSION_VAR Python_VERSION HANDLE_VERSION_RANGE REASON_FAILURE_MESSAGE + "Ensure that obs-deps is provided as part of CMAKE_PREFIX_PATH.") +mark_as_advanced(Python_INCLUDE_DIR Python_LIBRARY) + +if(Python_FOUND) + set(Python_INCLUDE_DIRS ${Python_INCLUDE_DIR}) + set(Python_LIBRARIES ${Python_LIBRARY}) + set(Python_DEFINITIONS ${PC_Python_CFLAGS_OTHER}) + + if(NOT TARGET Python::Python) + if(IS_ABSOLUTE "${Python_LIBRARY}") + add_library(Python::Python UNKNOWN IMPORTED) + set_property(TARGET Python::Python PROPERTY IMPORTED_LOCATION "${Python_LIBRARY}") + else() + add_library(Python::Python INTERFACE IMPORTED) + set_property(TARGET Python::Python PROPERTY IMPORTED_LIBNAME "${Python_LIBRARY}") + endif() + + set_target_properties(Python::Python PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Python_INCLUDE_DIR}" + VERSION ${Python_VERSION}) + endif() +endif() + +include(FeatureSummary) +set_package_properties( + Python PROPERTIES + URL "https://www.python.org" + DESCRIPTION + "Python is a programming language that lets you work more quickly and integrate your systems more effectively.") diff --git a/cmake/windows/buildspec.cmake b/cmake/windows/buildspec.cmake new file mode 100644 index 000000000..72a2e0c6d --- /dev/null +++ b/cmake/windows/buildspec.cmake @@ -0,0 +1,29 @@ +# OBS CMake Windows build dependencies module + +include_guard(GLOBAL) + +include(buildspec_common) + +# _check_dependencies_windows: Set up Windows slice for _check_dependencies +function(_check_dependencies_windows) + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "windows-deps-VERSION-ARCH-REVISION.zip") + set(prebuilt_destination "obs-deps-VERSION-ARCH") + set(qt6_filename "windows-deps-qt6-VERSION-ARCH-REVISION.zip") + set(qt6_destination "obs-deps-qt6-VERSION-ARCH") + set(cef_filename "cef_binary_VERSION_windows_ARCH_REVISION.zip") + set(cef_destination "cef_binary_VERSION_windows_ARCH") + + if(CMAKE_GENERATOR_PLATFORM STREQUAL Win32) + set(arch x86) + set(dependencies_list prebuilt) + else() + set(arch ${CMAKE_GENERATOR_PLATFORM}) + set(dependencies_list prebuilt qt6 cef) + endif() + set(platform windows-${arch}) + + _check_dependencies() +endfunction() + +_check_dependencies_windows() diff --git a/cmake/windows/compilerconfig.cmake b/cmake/windows/compilerconfig.cmake new file mode 100644 index 000000000..54f0e7c40 --- /dev/null +++ b/cmake/windows/compilerconfig.cmake @@ -0,0 +1,49 @@ +# OBS CMake Windows compiler configuration module + +include_guard(GLOBAL) + +include(ccache) +include(compiler_common) + +if(ENABLE_CCACHE AND CCACHE_PROGRAM) + if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + file(COPY_FILE ${CCACHE_PROGRAM} "${CMAKE_CURRENT_BINARY_DIR}/cl.exe") + set(CMAKE_VS_GLOBALS "CLToolExe=cl.exe" "CLToolPath=${CMAKE_BINARY_DIR}" "TrackFileAccess=false" + "UseMultiToolTask=true") + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded) + elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang") + file(COPY_FILE ${CCACHE_PROGRAM} "${CMAKE_CURRENT_BINARY_DIR}/clang-cl.exe") + set(CMAKE_VS_GLOBALS "CLToolExe=clang-cl.exe" "CLToolPath=${CMAKE_BINARY_DIR}" "TrackFileAccess=false" + "UseMultiToolTask=true") + endif() +endif() + +# CMake 3.24 introduces a bug mistakenly interpreting MSVC as supporting the '-pthread' compiler flag +if(CMAKE_VERSION VERSION_EQUAL 3.24.0) + set(THREADS_HAVE_PTHREAD_ARG FALSE) +endif() + +message(DEBUG "Current Windows API version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") +if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM) + message(DEBUG "Maximum Windows API version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM}") +endif() + +if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION VERSION_LESS 10.0.20348) + message(FATAL_ERROR "OBS requires Windows SDK version 10.0.20348.0 or more recent.\n" + "Please download and install the most recent Windows SDK.") +endif() + +add_compile_options( + /W3 /utf-8 "$<$:/MP>" "$<$:/MP>" + "$<$:${_obs_clang_c_options}>" + "$<$:${_obs_clang_cxx_options}>") + +add_compile_definitions(UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS $<$:DEBUG> + $<$:_DEBUG>) + +add_link_options("$<$>:/OPT\:REF>" "$<$:/INCREMENTAL\:NO>" + "$<$:/INCREMENTAL\:NO>" "$<$:/OPT\:ICF>") + +if(CMAKE_COMPILE_WARNING_AS_ERROR) + add_link_options(/WX) +endif() diff --git a/cmake/windows/cpackconfig.cmake b/cmake/windows/cpackconfig.cmake new file mode 100644 index 000000000..bd82e4e8b --- /dev/null +++ b/cmake/windows/cpackconfig.cmake @@ -0,0 +1,15 @@ +# OBS CMake Windows CPack configuration module + +include_guard(GLOBAL) + +include(cpackconfig_common) + +# Add GPLv2 license file to CPack +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/UI/data/license/gplv2.txt") +set(CPACK_PACKAGE_VERSION "${OBS_VERSION_CANONICAL}") +set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-windows-${CMAKE_GENERATOR_PLATFORM}") +set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY FALSE) +set(CPACK_GENERATOR ZIP) +set(CPACK_THREADS 0) + +include(CPack) diff --git a/cmake/windows/defaults.cmake b/cmake/windows/defaults.cmake new file mode 100644 index 000000000..ff0dae7b3 --- /dev/null +++ b/cmake/windows/defaults.cmake @@ -0,0 +1,35 @@ +# OBS CMake Windows defaults module + +include_guard(GLOBAL) + +set(OBS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(OBS_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/rundir") + +set(OBS_PLUGIN_DESTINATION obs-plugins/64bit) +set(OBS_DATA_DESTINATION data) +set(OBS_CMAKE_DESTINATION cmake) +set(OBS_SCRIPT_PLUGIN_DESTINATION "${OBS_DATA_DESTINATION}/obs-scripting/64bit") + +set(OBS_EXECUTABLE_DESTINATION bin/64bit) +set(OBS_LIBRARY_DESTINATION lib) +set(OBS_INCLUDE_DESTINATION include) +# Set relative paths used by OBS for self-discovery +set(OBS_PLUGIN_PATH "../../${CMAKE_INSTALL_LIBDIR}/obs-plugins/64bit") +set(OBS_SCRIPT_PLUGIN_PATH "../../${OBS_DATA_DESTINATION}/obs-scripting/64bit") +set(OBS_DATA_PATH "../../${OBS_DATA_DESTINATION}") + +# Enable find_package targets to become globally available targets +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) + +include(buildspec) +include(cpackconfig) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + execute_process( + COMMAND + "${CMAKE_COMMAND}" -S ${CMAKE_CURRENT_SOURCE_DIR} -B ${CMAKE_SOURCE_DIR}/build_x86 -A Win32 -G + "${CMAKE_GENERATOR}" -DCMAKE_SYSTEM_VERSION:STRING='${CMAKE_SYSTEM_VERSION}' -DOBS_CMAKE_VERSION:STRING=3.0.0 + -DVIRTUALCAM_GUID:STRING=${VIRTUALCAM_GUID} -DCMAKE_MESSAGE_LOG_LEVEL=${CMAKE_MESSAGE_LOG_LEVEL} + -DENABLE_CCACHE=${ENABLE_CCACHE} + RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY) +endif() diff --git a/cmake/windows/helpers.cmake b/cmake/windows/helpers.cmake new file mode 100644 index 000000000..432616b0b --- /dev/null +++ b/cmake/windows/helpers.cmake @@ -0,0 +1,523 @@ +# OBS CMake Windows helper functions module + +# cmake-format: off +# cmake-lint: disable=C0301 +# cmake-lint: disable=R0915 +# cmake-format: on + +include_guard(GLOBAL) + +include(helpers_common) + +# set_target_properties_obs: Set target properties for use in obs-studio +function(set_target_properties_obs target) + set(options "") + set(oneValueArgs "") + set(multiValueArgs PROPERTIES) + cmake_parse_arguments(PARSE_ARGV 0 _STPO "${options}" "${oneValueArgs}" "${multiValueArgs}") + + message(DEBUG "Setting additional properties for target ${target}...") + + while(_STPO_PROPERTIES) + list(POP_FRONT _STPO_PROPERTIES key value) + set_property(TARGET ${target} PROPERTY ${key} "${value}") + endwhile() + + get_target_property(target_type ${target} TYPE) + + if(target_type STREQUAL EXECUTABLE) + if(target STREQUAL obs-browser-helper) + set(OBS_EXECUTABLE_DESTINATION "${OBS_PLUGIN_DESTINATION}") + elseif(target STREQUAL inject-helper OR target STREQUAL get-graphics-offsets) + set(OBS_EXECUTABLE_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture") + + # cmake-format: off + _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} 32BIT) + # cmake-format: on + elseif(target STREQUAL enc-amf-test) + set(OBS_EXECUTABLE_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/enc-amf") + endif() + + # cmake-format: off + _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION}) + # cmake-format: on + + if(target STREQUAL obs-studio) + get_property(obs_executables GLOBAL PROPERTY _OBS_EXECUTABLES) + get_property(obs_modules GLOBAL PROPERTY OBS_MODULES_ENABLED) + add_dependencies(${target} ${obs_executables} ${obs_modules}) + _bundle_dependencies(${target}) + target_add_resource(${target} "${CMAKE_CURRENT_SOURCE_DIR}/../AUTHORS" + "${OBS_DATA_DESTINATION}/obs-studio/authors") + elseif(target STREQUAL obs-browser-helper) + set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target}) + return() + else() + set_property(GLOBAL APPEND PROPERTY _OBS_EXECUTABLES ${target}) + endif() + elseif(target_type STREQUAL SHARED_LIBRARY) + set_target_properties(${target} PROPERTIES VERSION ${OBS_VERSION_MAJOR} SOVERSION ${OBS_VERSION_CANONICAL}) + + # cmake-format: off + _target_install_obs( + ${target} + DESTINATION "${OBS_EXECUTABLE_DESTINATION}" + LIBRARY_DESTINATION "${OBS_LIBRARY_DESTINATION}" + HEADER_DESTINATION "${OBS_INCLUDE_DESTINATION}") + # cmake-format: on + elseif(target_type STREQUAL MODULE_LIBRARY) + set_target_properties(${target} PROPERTIES VERSION 0 SOVERSION ${OBS_VERSION_CANONICAL}) + + if(target STREQUAL libobs-d3d11 + OR target STREQUAL libobs-opengl + OR target STREQUAL libobs-winrt) + set(target_destination "${OBS_EXECUTABLE_DESTINATION}") + elseif(target STREQUAL "obspython" OR target STREQUAL "obslua") + set(target_destination "${OBS_SCRIPT_PLUGIN_DESTINATION}") + elseif(target STREQUAL graphics-hook) + set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-capture") + target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan64.json" "${target_destination}") + target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "${target_destination}") + + # cmake-format: off + _target_install_obs(${target} DESTINATION ${target_destination} 32BIT) + # cmake-format: on + elseif(target STREQUAL obs-virtualcam-module) + set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow") + + # cmake-format: off + _target_install_obs(${target} DESTINATION ${target_destination} 32BIT) + # cmake-format: on + else() + set(target_destination "${OBS_PLUGIN_DESTINATION}") + endif() + + # cmake-format: off + _target_install_obs(${target} DESTINATION ${target_destination}) + # cmake-format: on + + if(${target} STREQUAL obspython) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${OBS_SCRIPT_PLUGIN_DESTINATION}/" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$/obspython.py" + "${OBS_OUTPUT_DIR}/$/${OBS_SCRIPT_PLUGIN_DESTINATION}/" + COMMENT "Add obspython import module") + + install( + FILES "$/obspython.py" + DESTINATION "${OBS_SCRIPT_PLUGIN_DESTINATION}" + COMPONENT Runtime) + elseif(${target} STREQUAL obs-browser) + message(DEBUG "Add Chromium Embedded Framework to project for obs-browser plugin...") + if(TARGET CEF::Library) + get_target_property(imported_location CEF::Library IMPORTED_LOCATION_RELEASE) + + if(imported_location) + cmake_path(GET imported_location PARENT_PATH cef_location) + cmake_path(GET cef_location PARENT_PATH cef_root_location) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${target_destination}" + COMMAND + "${CMAKE_COMMAND}" -E copy_if_different "${imported_location}" "${cef_location}/chrome_elf.dll" + "${cef_location}/libEGL.dll" "${cef_location}/libGLESv2.dll" "${cef_location}/snapshot_blob.bin" + "${cef_location}/v8_context_snapshot.bin" "${OBS_OUTPUT_DIR}/$/${target_destination}" + COMMAND + "${CMAKE_COMMAND}" -E copy_if_different "${cef_root_location}/Resources/chrome_100_percent.pak" + "${cef_root_location}/Resources/chrome_200_percent.pak" "${cef_root_location}/Resources/icudtl.dat" + "${cef_root_location}/Resources/resources.pak" "${OBS_OUTPUT_DIR}/$/${target_destination}/" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${cef_root_location}/Resources/locales" + "${OBS_OUTPUT_DIR}/$/${target_destination}/locales" + COMMENT "Add Chromium Embedded Framework to library directory") + + install( + FILES "${imported_location}" + "${cef_location}/chrome_elf.dll" + "${cef_location}/libEGL.dll" + "${cef_location}/libGLESv2.dll" + "${cef_location}/snapshot_blob.bin" + "${cef_location}/v8_context_snapshot.bin" + "${cef_root_location}/Resources/chrome_100_percent.pak" + "${cef_root_location}/Resources/chrome_200_percent.pak" + "${cef_root_location}/Resources/icudtl.dat" + "${cef_root_location}/Resources/resources.pak" + DESTINATION "${target_destination}" + COMPONENT Runtime) + + install( + DIRECTORY "${cef_root_location}/Resources/locales" + DESTINATION "${target_destination}" + USE_SOURCE_PERMISSIONS + COMPONENT Runtime) + endif() + endif() + endif() + + set_property(GLOBAL APPEND PROPERTY OBS_MODULES_ENABLED ${target}) + endif() + + target_install_resources(${target}) +endfunction() + +# _target_install_obs: Helper function to install build artifacts to rundir and install location +function(_target_install_obs target) + set(options "32BIT") + set(oneValueArgs "DESTINATION" "LIBRARY_DESTINATION" "HEADER_DESTINATION") + set(multiValueArgs "") + cmake_parse_arguments(PARSE_ARGV 0 _TIO "${options}" "${oneValueArgs}" "${multiValueArgs}") + + if(_TIO_32BIT) + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL EXECUTABLE) + set(suffix exe) + else() + set(suffix dll) + endif() + + cmake_path(RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR BASE_DIRECTORY "${OBS_SOURCE_DIR}" OUTPUT_VARIABLE project_path) + + set(32bit_project_path "${OBS_SOURCE_DIR}/build_x86/${project_path}") + set(target_file "${32bit_project_path}/$/${target}32.${suffix}") + set(target_pdb_file "${32bit_project_path}/$/${target}32.pdb") + set(comment "Copy ${target} (32-bit) to destination") + + install( + FILES "${32bit_project_path}/$/${target}32.${suffix}" + DESTINATION "${_TIO_DESTINATION}" + COMPONENT Runtime + OPTIONAL) + else() + set(target_file "$") + set(target_pdb_file "$") + set(comment "Copy ${target} to destination") + + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL EXECUTABLE) + install(TARGETS ${target} RUNTIME DESTINATION "${_TIO_DESTINATION}" COMPONENT Runtime) + elseif(target_type STREQUAL SHARED_LIBRARY) + if(NOT _TIO_LIBRARY_DESTINATION) + set(_TIO_LIBRARY_DESTINATION ${_TIO_DESTINATION}) + endif() + if(NOT _TIO_HEADER_DESTINATION) + set(_TIO_HEADER_DESTINATION include) + endif() + install( + TARGETS ${target} + RUNTIME DESTINATION "${_TIO_DESTINATION}" + LIBRARY DESTINATION "${_TIO_LIBRARY_DESTINATION}" + COMPONENT Runtime + EXCLUDE_FROM_ALL + PUBLIC_HEADER + DESTINATION "${_TIO_HEADER_DESTINATION}" + COMPONENT Development + EXCLUDE_FROM_ALL) + elseif(target_type STREQUAL MODULE_LIBRARY) + install( + TARGETS ${target} + LIBRARY DESTINATION "${_TIO_DESTINATION}" + COMPONENT Runtime + NAMELINK_COMPONENT Development) + endif() + endif() + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${_TIO_DESTINATION}" + COMMAND "${CMAKE_COMMAND}" -E copy ${target_file} "$<$:${target_pdb_file}>" + "${OBS_OUTPUT_DIR}/$/${_TIO_DESTINATION}" + COMMENT "${comment}" + VERBATIM) + + install( + FILES ${target_pdb_file} + CONFIGURATIONS RelWithDebInfo Debug + DESTINATION "${_TIO_DESTINATION}" + COMPONENT Runtime + OPTIONAL) +endfunction() + +# target_export: Helper function to export target as CMake package +function(target_export target) + # Exclude CMake package from 'ALL' target + set(exclude_variant EXCLUDE_FROM_ALL) + _target_export(${target}) + + install( + FILES "$" + CONFIGURATIONS RelWithDebInfo Debug + DESTINATION "${OBS_EXECUTABLE_DESTINATION}" + COMPONENT Development + OPTIONAL) +endfunction() + +# Helper function to add resources into bundle +function(target_install_resources target) + message(DEBUG "Installing resources for target ${target}...") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/data") + file(GLOB_RECURSE data_files "${CMAKE_CURRENT_SOURCE_DIR}/data/*") + foreach(data_file IN LISTS data_files) + cmake_path(RELATIVE_PATH data_file BASE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/" OUTPUT_VARIABLE + relative_path) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + source_group("Resources/${relative_path}" FILES "${data_file}") + endforeach() + + get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) + if(target IN_LIST obs_module_list) + set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}") + elseif(target STREQUAL obs-studio) + set(target_destination "${OBS_DATA_DESTINATION}/obs-studio") + else() + set(target_destination "${OBS_DATA_DESTINATION}/${target}") + endif() + + install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/" + DESTINATION "${target_destination}" + USE_SOURCE_PERMISSIONS + COMPONENT Runtime) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${target_destination}" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/data" + "${OBS_OUTPUT_DIR}/$/${target_destination}" + COMMENT "Copy ${target} resources to data directory" + VERBATIM) + endif() +endfunction() + +# Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + + get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) + if(ARGN) + set(target_destination "${ARGN}") + elseif(${target} IN_LIST obs_module_list) + set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/${target}") + elseif(target STREQUAL obs-studio) + set(target_destination "${OBS_DATA_DESTINATION}/obs-studio") + else() + set(target_destination "${OBS_DATA_DESTINATION}/${target}") + endif() + + message(DEBUG "Add resource '${resource}' to target ${target} at destination '${target_destination}'...") + + install( + FILES "${resource}" + DESTINATION "${target_destination}" + COMPONENT Runtime) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${target_destination}/" + COMMAND "${CMAKE_COMMAND}" -E copy "${resource}" "${OBS_OUTPUT_DIR}/$/${target_destination}/" + COMMENT "Copy ${target} resource ${resource} to library directory" + VERBATIM) + + source_group("Resources" FILES "${resource}") +endfunction() + +# _bundle_dependencies: Resolve third party dependencies and add them to Windows binary directory +function(_bundle_dependencies target) + message(DEBUG "Discover dependencies of target ${target}...") + set(found_dependencies) + find_dependencies(TARGET ${target} FOUND_VAR found_dependencies) + + get_property(obs_module_list GLOBAL PROPERTY OBS_MODULES_ENABLED) + list(LENGTH obs_module_list num_modules) + if(num_modules GREATER 0) + add_dependencies(${target} ${obs_module_list}) + foreach(module IN LISTS obs_module_list) + find_dependencies(TARGET ${module} FOUND_VAR found_dependencies) + endforeach() + endif() + + list(REMOVE_DUPLICATES found_dependencies) + set(library_paths_DEBUG) + set(library_paths_RELWITHDEBINFO) + set(library_paths_RELEASE) + set(library_paths_MINSIZEREL) + set(plugins_list) + + foreach(library IN LISTS found_dependencies) + # CEF needs to be placed in obs-plugins directory on Windows, which is handled already + if(${library} STREQUAL CEF::Library) + continue() + endif() + + get_target_property(library_type ${library} TYPE) + get_target_property(is_imported ${library} IMPORTED) + + if(is_imported) + get_target_property(imported_location ${library} IMPORTED_LOCATION) + + foreach(config IN ITEMS RELEASE RELWITHDEBINFO MINSIZEREL DEBUG) + get_target_property(imported_location_${config} ${library} IMPORTED_LOCATION_${config}) + if(imported_location_${config}) + _check_library_location(${imported_location_${config}}) + elseif(NOT imported_location_${config} AND imported_location_RELEASE) + _check_library_location(${imported_location_RELEASE}) + else() + _check_library_location(${imported_location}) + endif() + endforeach() + + if(library MATCHES "Qt[56]?::.+") + find_qt_plugins(COMPONENT ${library} TARGET ${target} FOUND_VAR plugins_list) + endif() + endif() + endforeach() + + foreach(config IN ITEMS DEBUG RELWITHDEBINFO RELEASE MINSIZEREL) + list(REMOVE_DUPLICATES library_paths_${config}) + endforeach() + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}" + COMMAND "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_DEBUG}>" "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}" + COMMAND + "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_RELWITHDEBINFO}>" + "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}" + COMMAND "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_RELEASE}>" "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}" + COMMAND + "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_MINSIZEREL}>" "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}" + COMMENT "Copy dependencies to binary directory (${OBS_EXECUTABLE_DESTINATION})..." + VERBATIM COMMAND_EXPAND_LISTS) + + install( + FILES ${library_paths_DEBUG} + CONFIGURATIONS Debug + DESTINATION "${OBS_EXECUTABLE_DESTINATION}" + COMPONENT Runtime) + + install( + FILES ${library_paths_RELWITHDEBINFO} + CONFIGURATIONS RelWithDebInfo + DESTINATION "${OBS_EXECUTABLE_DESTINATION}" + COMPONENT Runtime) + + install( + FILES ${library_paths_RELEASE} + CONFIGURATIONS Release + DESTINATION "${OBS_EXECUTABLE_DESTINATION}" + COMPONENT Runtime) + + install( + FILES ${library_paths_MINSIZEREL} + CONFIGURATIONS MinSizeRel + DESTINATION "${OBS_EXECUTABLE_DESTINATION}" + COMPONENT Runtime) + + list(REMOVE_DUPLICATES plugins_list) + foreach(plugin IN LISTS plugins_list) + message(TRACE "Adding Qt plugin ${plugin}...") + + cmake_path(GET plugin PARENT_PATH plugin_path) + cmake_path(GET plugin_path STEM plugin_stem) + + list(APPEND plugin_stems ${plugin_stem}) + + if(plugin MATCHES ".+d\\.dll$") + list(APPEND plugin_${plugin_stem}_debug ${plugin}) + else() + list(APPEND plugin_${plugin_stem} ${plugin}) + endif() + endforeach() + + list(REMOVE_DUPLICATES plugin_stems) + foreach(stem IN LISTS plugin_stems) + set(plugin_list ${plugin_${stem}}) + set(plugin_list_debug ${plugin_${stem}_debug}) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}/${stem}" + COMMAND "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" "${plugin_list_debug}" + "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}/${stem}" + COMMAND "${CMAKE_COMMAND}" -E "$,true,copy_if_different>" "${plugin_list}" + "${OBS_OUTPUT_DIR}/$/${OBS_EXECUTABLE_DESTINATION}/${stem}" + COMMENT "Copy Qt plugins ${stem} to binary directory (${OBS_EXECUTABLE_DESTINATION}/${stem})" + VERBATIM COMMAND_EXPAND_LISTS) + + install( + FILES ${plugin_list_debug} + CONFIGURATIONS Debug + DESTINATION "${OBS_EXECUTABLE_DESTINATION}/${stem}" + COMPONENT Runtime) + + install( + FILES ${plugin_list} + CONFIGURATIONS RelWithDebInfo Release MinSizeRel + DESTINATION "${OBS_EXECUTABLE_DESTINATION}/${stem}" + COMPONENT Runtime) + endforeach() +endfunction() + +# _check_library_location: Check for corresponding DLL given an import library path +macro(_check_library_location location) + if(library_type STREQUAL "SHARED_LIBRARY") + set(library_location "${location}") + else() + string(STRIP "${location}" location) + if(location MATCHES ".+lib$") + cmake_path(GET location FILENAME _dll_name) + cmake_path(GET location PARENT_PATH _implib_path) + cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") + string(REPLACE ".lib" ".dll" _dll_name "${_dll_name}") + string(REPLACE ".dll" ".pdb" _pdb_name "${_dll_name}") + + find_program( + _dll_path + NAMES "${_dll_name}" + HINTS ${_implib_path} ${_bin_path} NO_CACHE + NO_DEFAULT_PATH) + + find_program( + _pdb_path + NAMES "${_pdb_name}" + HINTS ${_implib_path} ${_bin_path} NO_CACHE + NO_DEFAULT_PATH) + + if(_dll_path) + set(library_location "${_dll_path}") + set(library_pdb_location "${_pdb_path}") + else() + unset(library_location) + unset(library_pdb_location) + endif() + unset(_dll_path) + unset(_pdb_path) + unset(_bin_path) + unset(_implib_path) + unset(_dll_name) + unset(_pdb_name) + else() + unset(library_location) + unset(library_pdb_location) + endif() + endif() + + if(library_location) + list(APPEND library_paths_${config} ${library_location}) + endif() + if(library_pdb_location) + list(APPEND library_paths_${config} ${library_pdb_location}) + endif() + unset(location) + unset(library_location) + unset(library_pdb_location) +endmacro() diff --git a/cmake/windows/idlfilehelper.cmake b/cmake/windows/idlfilehelper.cmake new file mode 100644 index 000000000..b24e4a5bd --- /dev/null +++ b/cmake/windows/idlfilehelper.cmake @@ -0,0 +1,27 @@ +# target_add_idl_files: Compile IDL file and add generated source files to target +function(target_add_idl_files target) + set(options target WITH_TLB) + set(oneValueArgs "") + set(multiValueArgs "") + cmake_parse_arguments(PARSE_ARGV 1 _AIF "${options}" "${oneValueArgs}" "${multiValueArgs}") + set(aif_files ${_AIF_UNPARSED_ARGUMENTS}) + + foreach(idl_file IN LISTS aif_files) + cmake_path(GET idl_file STEM idl_file_name) + cmake_path(GET idl_file PARENT_PATH idl_file_path) + + set(idl_file_header "${CMAKE_CURRENT_BINARY_DIR}/${idl_file_name}.h") + set(idl_file_source "${CMAKE_CURRENT_BINARY_DIR}/${idl_file_name}_i.c") + + add_custom_command( + OUTPUT "${idl_file_header}" "${idl_file_source}" + DEPENDS "${idl_file}" + COMMAND midl /h "${idl_file_name}.h" /iid "${idl_file_name}_i.c" "$<$>:/notlb>" + /win64 "${CMAKE_CURRENT_SOURCE_DIR}/${idl_file}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + COMMENT "Generate idl files") + + set_source_files_properties(${idl_file} PROPERTIES HEADER_FILE_ONLY TRUE) + target_sources(${target} PRIVATE "${idl_file_source}" "${idl_file_header}") + endforeach() +endfunction()