diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake index 4d50f15518e..738debeb27c 100644 --- a/cmake/QtBuildHelpers.cmake +++ b/cmake/QtBuildHelpers.cmake @@ -294,6 +294,7 @@ function(qt_internal_get_qt_build_public_helpers out_var) QtPublicTestHelpers QtPublicToolHelpers QtPublicWalkLibsHelpers + QtPublicWindowsHelpers PARENT_SCOPE ) endfunction() diff --git a/cmake/QtPublicWindowsHelpers.cmake b/cmake/QtPublicWindowsHelpers.cmake new file mode 100644 index 00000000000..8c182287d69 --- /dev/null +++ b/cmake/QtPublicWindowsHelpers.cmake @@ -0,0 +1,105 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +function(qt6_add_win_app_sdk target) + if(NOT MSVC) + message(WARNING + "qt6_add_win_app_sdk doesn't work when targeting platforms other than MSVC.") + return() + endif() + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64" OR + CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + set(win_app_sdk_arch "arm64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm*") + set(win_app_sdk_arch "arm") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(win_app_sdk_arch "64") + elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(win_app_sdk_arch "86") + endif() + + if(WIN_APP_SDK_ROOT) + set(win_app_sdk_root "${WIN_APP_SDK_ROOT}") + elseif(DEFINED ENV{WIN_APP_SDK_ROOT}) + set(win_app_sdk_root "$ENV{WIN_APP_SDK_ROOT}") + endif() + + if(WEB_VIEW_ROOT) + set(web_view_root "${WEB_VIEW_ROOT}") + elseif(DEFINED ENV{WEB_VIEW_ROOT}) + set(web_view_root "$ENV{WEB_VIEW_ROOT}") + endif() + + set(generated_headers_path "${CMAKE_CURRENT_BINARY_DIR}/winrt_includes") + + find_path(WINAPPSDK_GENERATED_INCLUDE_DIR + NAMES winrt/Microsoft.UI.h + HINTS "${generated_headers_path}") + # If headers are not already generated + if(NOT WINAPPSDK_GENERATED_INCLUDE_DIR) + if(CPP_WIN_RT_PATH) + set(cpp_win_rt_path "${CPP_WIN_RT_PATH}") + elseif(DEFINED ENV{CPP_WIN_RT_PATH}) + set(cpp_win_rt_path "$ENV{CPP_WIN_RT_PATH}") + endif() + if(NOT cpp_win_rt_path) + find_file(CPP_WIN_RT_PATH + NAMES cppwinrt.exe + HINTS "C:/Program Files*/Windows Kits/*/bin/*/*${win_app_sdk_arch}*/") + set(cpp_win_rt_path ${CPP_WIN_RT_PATH}) + endif() + if(NOT cpp_win_rt_path) + message(FATAL_ERROR "cppwinrt.exe could not be found") + endif() + + find_path(WINAPPSDK_INCLUDE_DIR + NAMES MddBootstrap.h + HINTS ${win_app_sdk_root}/include) + + find_library(WINAPPSDK_LIBRARY + NAMES Microsoft.WindowsAppRuntime + HINTS ${WINAPPSDK_LIBRARY_DIR} "${win_app_sdk_root}" + "${win_app_sdk_root}/lib" + "${win_app_sdk_root}/lib/win10-x${win_app_sdk_arch}") + + find_library(WINAPPSDK_BOOTSTRAP_LIBRARY + NAMES Microsoft.WindowsAppRuntime.Bootstrap + HINTS ${WINAPPSDK_LIBRARY_DIR} "${win_app_sdk_root}" + "${win_app_sdk_root}/lib" + "${win_app_sdk_root}/lib/win10-x${win_app_sdk_arch}") + + if(WINAPPSDK_INCLUDE_DIR AND WINAPPSDK_LIBRARY AND WINAPPSDK_BOOTSTRAP_LIBRARY) + execute_process(COMMAND + ${cpp_win_rt_path} -out "${generated_headers_path}" -ref sdk + -in "${win_app_sdk_root}/lib/uap10.0" + -in "${win_app_sdk_root}/lib/uap10.0.17763" + -in "${win_app_sdk_root}/lib/uap10.0.18362" + -in "${web_view_root}/lib") + + find_path(WINAPPSDK_GENERATED_INCLUDE_DIR + NAMES winrt/Microsoft.UI.h + HINTS "${generated_headers_path}") + + if(NOT WINAPPSDK_GENERATED_INCLUDE_DIR) + message(FATAL_ERROR "Windows App SDK library headers generation failed") + endif() + else() + message(FATAL_ERROR "Windows App SDK library not found") + endif() + endif() + + target_include_directories(${target} PRIVATE "${win_app_sdk_root}/include") + target_include_directories(${target} + PRIVATE "${generated_headers_path}") + target_link_directories(${target} + PRIVATE "${win_app_sdk_root}/lib/win10-x${win_app_sdk_arch}") + target_link_libraries(${target} + PRIVATE Microsoft.WindowsAppRuntime.lib Microsoft.WindowsAppRuntime.Bootstrap.lib) +endfunction() + +if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) + macro(qt_add_win_app_sdk) + qt6_add_win_app_sdk(${ARGV}) + endmacro() +endif() diff --git a/src/corelib/doc/src/cmake/qt_add_win_app_sdk.qdoc b/src/corelib/doc/src/cmake/qt_add_win_app_sdk.qdoc new file mode 100644 index 00000000000..873e9771ffb --- /dev/null +++ b/src/corelib/doc/src/cmake/qt_add_win_app_sdk.qdoc @@ -0,0 +1,38 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! +\page qt-add-win-app-sdk.html +\ingroup cmake-commands-qtcore + +\title qt_add_win_app_sdk +\keyword qt6_add_win_app_sdk + +\summary {Adds the Windows App SDK library to the application.} + +\cmakecommandsince 6.9 +\preliminarycmakecommand + +\section1 Synopsis + +\badcode +qt_add_win_app_sdk(target) +\endcode + +\versionlessCMakeCommandsNote qt6_add_win_app_sdk() + +\section1 Description + +Adds Windows App SDK include files to the project, and links the necessary +libraries to the given CMake target. Windows App SDK is provided as a \l{https://learn.microsoft.com/en-us/nuget/what-is-nuget}{NuGet} +package so it can be easily used in managed apps. However, for unmanaged +C++ applications we need header files. +The function takes the following steps: +\list 1 + \li Tries to find the Windows App SDK and cppwinrt.exe tool + \li Generates Windows App SDK headers using the cppwinrt.exe tool + \li Includes those header files and links the library to the given CMake target +\endlist + +\warning This command is not supported on non-MSVC platforms. +*/