From df97bddd879bc9bb20ddfae96395a7792754d9e2 Mon Sep 17 00:00:00 2001 From: PatTheMav Date: Sat, 8 Feb 2025 17:00:33 +0100 Subject: [PATCH] cmake: Update cross-platform build project management for Windows Enables creation of x64 and x86 child projects when building on ARM64 and decouples functionality from legacy_check function --- CMakePresets.json | 39 +++++++++++++++++++ cmake/finders/FindLibx264.cmake | 2 +- cmake/windows/architecture.cmake | 28 ++++++++++--- cmake/windows/buildspec.cmake | 15 +++++++ cmake/windows/helpers.cmake | 20 ++++++++-- plugins/CMakeLists.txt | 2 +- .../get-graphics-offsets/CMakeLists.txt | 15 ++++++- .../win-capture/graphics-hook/CMakeLists.txt | 15 ++++++- .../win-capture/inject-helper/CMakeLists.txt | 15 ++++++- .../virtualcam-module/CMakeLists.txt | 15 ++++++- .../cmake/windows/virtualcam-module-arm64.def | 8 ++++ 11 files changed, 155 insertions(+), 19 deletions(-) create mode 100644 plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module-arm64.def diff --git a/CMakePresets.json b/CMakePresets.json index 36820b19f..09d8e9e10 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -116,6 +116,38 @@ "cacheVariables": { "CMAKE_COMPILE_WARNING_AS_ERROR": true } + }, + { + "name": "windows-arm64", + "displayName": "Windows ARM64", + "description": "Default Windows build (ARM64)", + "inherits": ["environmentVars"], + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "architecture": "ARM64,version=10.0.22621", + "binaryDir": "${sourceDir}/build_arm64", + "generator": "Visual Studio 17 2022", + "cacheVariables": { + "GPU_PRIORITY_VAL": {"type": "STRING", "value": "$penv{GPU_PRIORITY_VAL}"}, + "VIRTUALCAM_GUID": {"type": "STRING", "value": "A3FCE0F5-3493-419F-958A-ABA1250EC20B"}, + "ENABLE_AJA": false, + "ENABLE_BROWSER": false, + "ENABLE_SCRIPTING": false, + "ENABLE_VST": false + } + }, + { + "name": "windows-ci-arm64", + "displayName": "Windows ARM64 (CI)", + "description": "CI Windows build (ARM64)", + "inherits": ["windows-arm64"], + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "CMAKE_COMPILE_WARNING_AS_ERROR": true + } } ], "buildPresets": [ @@ -125,6 +157,13 @@ "displayName": "Windows 64-bit", "description": "Windows build for 64-bit (aka x64)", "configuration": "RelWithDebInfo" + }, + { + "name": "windows-arm64", + "configurePreset": "windows-arm64", + "displayName": "Windows on ARM 64-bit", + "description": "Windows build for ARM 64-bit (aka ARM64)", + "configuration": "RelWithDebInfo" } ] } diff --git a/cmake/finders/FindLibx264.cmake b/cmake/finders/FindLibx264.cmake index feb50551c..1a9cc1c22 100644 --- a/cmake/finders/FindLibx264.cmake +++ b/cmake/finders/FindLibx264.cmake @@ -77,7 +77,7 @@ macro(Libx264_find_dll) cmake_path(GET Libx264_IMPLIB PARENT_PATH _implib_path) cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") - string(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" _dll_version "${Libx264_VERSION}") + string(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" _dll_version "${Libx264_VERSION}") find_program( Libx264_LIBRARY diff --git a/cmake/windows/architecture.cmake b/cmake/windows/architecture.cmake index 1fc9ed23f..1dc2fbd59 100644 --- a/cmake/windows/architecture.cmake +++ b/cmake/windows/architecture.cmake @@ -5,7 +5,7 @@ include_guard(GLOBAL) include(compilerconfig) if(NOT DEFINED OBS_PARENT_ARCHITECTURE) - if(CMAKE_VS_PLATFORM_NAME MATCHES "(Win32|x64)") + if(CMAKE_VS_PLATFORM_NAME MATCHES "(Win32|x64|ARM64)") set(OBS_PARENT_ARCHITECTURE ${CMAKE_VS_PLATFORM_NAME}) else() message(FATAL_ERROR "Unsupported generator platform for Windows builds: ${CMAKE_VS_PLATFORM_NAME}!") @@ -13,14 +13,32 @@ if(NOT DEFINED OBS_PARENT_ARCHITECTURE) endif() if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) - if(OBS_PARENT_ARCHITECTURE STREQUAL x64) + if(OBS_PARENT_ARCHITECTURE STREQUAL ARM64) + execute_process( + COMMAND + "${CMAKE_COMMAND}" -S ${CMAKE_CURRENT_SOURCE_DIR} -B ${CMAKE_SOURCE_DIR}/build_x64 -A + "x64,version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" -G "${CMAKE_GENERATOR}" + -DCMAKE_SYSTEM_VERSION:STRING='${CMAKE_SYSTEM_VERSION}' -DVIRTUALCAM_GUID:STRING=${VIRTUALCAM_GUID} + -DCMAKE_MESSAGE_LOG_LEVEL:STRING=${CMAKE_MESSAGE_LOG_LEVEL} -DOBS_PARENT_ARCHITECTURE:STRING=ARM64 + RESULT_VARIABLE _process_result + COMMAND_ERROR_IS_FATAL ANY + ) execute_process( COMMAND "${CMAKE_COMMAND}" -S ${CMAKE_CURRENT_SOURCE_DIR} -B ${CMAKE_SOURCE_DIR}/build_x86 -A "Win32,version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" -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:STRING=${CMAKE_MESSAGE_LOG_LEVEL} - -DENABLE_CCACHE:BOOL=${ENABLE_CCACHE} -DOBS_PARENT_ARCHITECTURE:STRING=x64 + -DCMAKE_SYSTEM_VERSION:STRING='${CMAKE_SYSTEM_VERSION}' -DVIRTUALCAM_GUID:STRING=${VIRTUALCAM_GUID} + -DCMAKE_MESSAGE_LOG_LEVEL:STRING=${CMAKE_MESSAGE_LOG_LEVEL} -DOBS_PARENT_ARCHITECTURE:STRING=ARM64 + RESULT_VARIABLE _process_result + COMMAND_ERROR_IS_FATAL ANY + ) + elseif(OBS_PARENT_ARCHITECTURE STREQUAL x64) + execute_process( + COMMAND + "${CMAKE_COMMAND}" -S ${CMAKE_CURRENT_SOURCE_DIR} -B ${CMAKE_SOURCE_DIR}/build_x86 -A + "Win32,version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" -G "${CMAKE_GENERATOR}" + -DCMAKE_SYSTEM_VERSION:STRING='${CMAKE_SYSTEM_VERSION}' -DVIRTUALCAM_GUID:STRING=${VIRTUALCAM_GUID} + -DCMAKE_MESSAGE_LOG_LEVEL:STRING=${CMAKE_MESSAGE_LOG_LEVEL} -DOBS_PARENT_ARCHITECTURE:STRING=x64 RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY ) diff --git a/cmake/windows/buildspec.cmake b/cmake/windows/buildspec.cmake index 50f1a4e75..22f87ec80 100644 --- a/cmake/windows/buildspec.cmake +++ b/cmake/windows/buildspec.cmake @@ -24,6 +24,21 @@ function(_check_dependencies_windows) set(platform windows-${arch}) _check_dependencies() + + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64 AND NOT QT_HOST_PATH) + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + + string(JSON dependency_data GET ${buildspec} dependencies) + string(JSON data GET ${dependency_data} qt6) + string(JSON version GET ${data} version) + set(qt_x64_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps/obs-deps-qt6-${version}-x64") + + if(IS_DIRECTORY "${qt_x64_dir}") + set(QT_HOST_PATH "${qt_x64_dir}" CACHE STRING "Qt Host Tools Path" FORCE) + else() + message(FATAL_ERROR "Building OBS Studio for Windows ARM64 requires x64 Qt dependencies") + endif() + endif() endfunction() _check_dependencies_windows() diff --git a/cmake/windows/helpers.cmake b/cmake/windows/helpers.cmake index fe51bac50..7fa55f5eb 100644 --- a/cmake/windows/helpers.cmake +++ b/cmake/windows/helpers.cmake @@ -27,6 +27,10 @@ function(set_target_properties_obs target) set(OBS_EXECUTABLE_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture") _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x86) + + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x64) + endif() endif() _target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION}) @@ -67,10 +71,18 @@ function(set_target_properties_obs target) target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "${target_destination}") _target_install_obs(${target} DESTINATION ${target_destination} x86) + + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + _target_install_obs(${target} DESTINATION ${target_destination} x64) + endif() elseif(target STREQUAL obs-virtualcam-module) set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow") _target_install_obs(${target} DESTINATION ${target_destination} x86) + + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + _target_install_obs(${target} DESTINATION ${target_destination} x64) + endif() else() set(target_destination "${OBS_PLUGIN_DESTINATION}") endif() @@ -206,13 +218,13 @@ function(_target_install_obs target) 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_x64/${project_path}") - set(target_file "${32bit_project_path}/$/${target}64.${suffix}") - set(target_pdb_file "${32bit_project_path}/$/${target}64.pdb") + set(64bit_project_path "${OBS_SOURCE_DIR}/build_x64/${project_path}") + set(target_file "${64bit_project_path}/$/${target}64.${suffix}") + set(target_pdb_file "${64bit_project_path}/$/${target}64.pdb") set(comment "Copy ${target} (x64) to destination") install( - FILES "${32bit_project_path}/$/${target}64.${suffix}" + FILES "${64bit_project_path}/$/${target}64.${suffix}" DESTINATION "${_TIO_DESTINATION}" COMPONENT Runtime OPTIONAL diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 1af782adc..470e727c1 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -61,7 +61,7 @@ check_obs_browser() add_obs_plugin(obs-ffmpeg) add_obs_plugin(obs-filters) add_obs_plugin(obs-libfdk) -add_obs_plugin(obs-nvenc PLATFORMS WINDOWS LINUX) +add_obs_plugin(obs-nvenc PLATFORMS WINDOWS LINUX ARCHITECTURES x64 x86_64) add_obs_plugin(obs-outputs) add_obs_plugin( obs-qsv11 diff --git a/plugins/win-capture/get-graphics-offsets/CMakeLists.txt b/plugins/win-capture/get-graphics-offsets/CMakeLists.txt index fffb3b4e6..d51b2a16d 100644 --- a/plugins/win-capture/get-graphics-offsets/CMakeLists.txt +++ b/plugins/win-capture/get-graphics-offsets/CMakeLists.txt @@ -20,7 +20,16 @@ target_link_libraries( ) if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) - if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + add_custom_command( + TARGET get-graphics-offsets + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x64 --config $ -t get-graphics-offsets + COMMENT "Build x64 get-graphics-offsets" + ) + endif() + + if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)") add_custom_command( TARGET get-graphics-offsets POST_BUILD @@ -32,7 +41,9 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) add_dependencies(win-capture get-graphics-offsets) endif() -if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) +if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + set(_OUTPUT_NAME get-graphics-offsets-arm64) +elseif(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(_OUTPUT_NAME get-graphics-offsets64) else() set(_OUTPUT_NAME get-graphics-offsets32) diff --git a/plugins/win-capture/graphics-hook/CMakeLists.txt b/plugins/win-capture/graphics-hook/CMakeLists.txt index caa1bc532..289362035 100644 --- a/plugins/win-capture/graphics-hook/CMakeLists.txt +++ b/plugins/win-capture/graphics-hook/CMakeLists.txt @@ -55,7 +55,16 @@ if(TARGET Vulkan::Vulkan) endif() if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) - if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + add_custom_command( + TARGET graphics-hook + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x64 --config $ -t graphics-hook + COMMENT "Build x64 graphics-hook" + ) + endif() + + if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)") add_custom_command( TARGET graphics-hook POST_BUILD @@ -67,7 +76,9 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) add_dependencies(win-capture graphics-hook) endif() -if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) +if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + set(_OUTPUT_NAME graphics-hook-arm64) +elseif(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(_OUTPUT_NAME graphics-hook64) else() set(_OUTPUT_NAME graphics-hook32) diff --git a/plugins/win-capture/inject-helper/CMakeLists.txt b/plugins/win-capture/inject-helper/CMakeLists.txt index ae62a032a..1c67473dc 100644 --- a/plugins/win-capture/inject-helper/CMakeLists.txt +++ b/plugins/win-capture/inject-helper/CMakeLists.txt @@ -15,7 +15,16 @@ target_sources(inject-helper PRIVATE inject-helper.c) target_link_libraries(inject-helper PRIVATE OBS::inject-library OBS::obfuscate) if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) - if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + add_custom_command( + TARGET inject-helper + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x64 --config $ -t inject-helper + COMMENT "Build x64 inject-helper" + ) + endif() + + if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)") add_custom_command( TARGET inject-helper POST_BUILD @@ -27,7 +36,9 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) add_dependencies(win-capture inject-helper) endif() -if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) +if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + set(_OUTPUT_NAME inject-helper-arm64) +elseif(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(_OUTPUT_NAME inject-helper64) else() set(_OUTPUT_NAME inject-helper32) diff --git a/plugins/win-dshow/virtualcam-module/CMakeLists.txt b/plugins/win-dshow/virtualcam-module/CMakeLists.txt index bc77f8efb..8ac916e17 100644 --- a/plugins/win-dshow/virtualcam-module/CMakeLists.txt +++ b/plugins/win-dshow/virtualcam-module/CMakeLists.txt @@ -105,7 +105,16 @@ target_link_libraries( ) if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) - if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) + if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + add_custom_command( + TARGET obs-virtualcam-module + POST_BUILD + COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x64 --config $ -t obs-virtualcam-module + COMMENT "Build x64 obs-virtualcam-module" + ) + endif() + + if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)") add_custom_command( TARGET obs-virtualcam-module POST_BUILD @@ -117,7 +126,9 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME) add_dependencies(win-dshow obs-virtualcam-module) endif() -if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) +if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64) + set(_OUTPUT_NAME virtualcam-module-arm64) +elseif(CMAKE_VS_PLATFORM_NAME STREQUAL x64) set(_OUTPUT_NAME virtualcam-module64) else() set(_OUTPUT_NAME virtualcam-module32) diff --git a/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module-arm64.def b/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module-arm64.def new file mode 100644 index 000000000..6a907ee35 --- /dev/null +++ b/plugins/win-dshow/virtualcam-module/cmake/windows/virtualcam-module-arm64.def @@ -0,0 +1,8 @@ +LIBRARY obs-virtualcam-module-arm64.dll +EXPORTS + DllMain PRIVATE + DllGetClassObject PRIVATE + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DllInstall PRIVATE