diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b5eb90b9..d32ccde18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -68,6 +68,15 @@ jobs: arch: x86_64 generator: "MSYS Makefiles" shell: msys2 {0} + msystem: ucrt64 + toolchain: ucrt-x86_64 + - name: Windows-ARM64 + os: windows-11-arm + arch: aarch64 + generator: "MSYS Makefiles" + shell: msys2 {0} + msystem: clangarm64 + toolchain: clang-aarch64 defaults: run: shell: ${{ matrix.shell }} @@ -269,21 +278,23 @@ jobs: if: runner.os == 'Windows' uses: msys2/setup-msys2@v2 with: - msystem: ucrt64 + msystem: ${{ matrix.msystem }} update: true - name: Update Windows dependencies env: - MSYSTEM: ucrt64 - TOOLCHAIN: ucrt-x86_64 + MSYSTEM: ${{ matrix.msystem }} + TOOLCHAIN: ${{ matrix.toolchain }} if: runner.os == 'Windows' shell: msys2 {0} run: | # variables declare -A pinned_deps pinned_deps["mingw-w64-${TOOLCHAIN}-cmake"]="3.31.6-1" - pinned_deps["mingw-w64-${TOOLCHAIN}-gcc"]="14.2.0-3" - pinned_deps["mingw-w64-${TOOLCHAIN}-gcc-libs"]="14.2.0-3" + if [[ ${MSYSTEM} == "ucrt64" ]]; then + pinned_deps["mingw-w64-${TOOLCHAIN}-gcc"]="14.2.0-3" + pinned_deps["mingw-w64-${TOOLCHAIN}-gcc-libs"]="14.2.0-3" + fi dependencies=( "diffutils" @@ -331,7 +342,8 @@ jobs: - name: Debug msys2.CMD if: runner.os == 'Windows' run: | - cat /d/a/_temp/setup-msys2/msys2.CMD + echo "MSYS2_ROOT=${{ runner.temp }}/msys64" >> $GITHUB_ENV + cat "${{ runner.temp }}/setup-msys2/msys2.CMD" - name: Initialize Submodules # libx265 has issues when using the recursive method of the first checkout action diff --git a/CMakeLists.txt b/CMakeLists.txt index 1056f5d16..b10cb61e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,11 +51,17 @@ elseif(NOT N MATCHES "^[0-9]+$") set(N_PROC 1) endif() +set(MSYS2_ROOT "C:/msys64") +if(WIN32 AND DEFINED ENV{MSYS2_ROOT}) + set(MSYS2_ROOT "$ENV{MSYS2_ROOT}") + message(STATUS "Detected MSYS2_ROOT, get msys2 path from environment: ${MSYS2_ROOT}") +endif() + if(NOT DEFINED BASH_EXECUTABLE) find_program(BASH_EXECUTABLE NAMES zsh bash REQUIRED - HINTS D:/a/_temp/msys64/usr/bin C:/msys64/usr/bin /bin /usr/bin /usr/local/bin) + HINTS "${MSYS2_ROOT}/usr/bin" /bin /usr/bin /usr/local/bin) message(STATUS "Found bash: ${BASH_EXECUTABLE}") endif() @@ -70,12 +76,25 @@ if(WIN32) set(MAKE_EXECUTABLE "make") message(STATUS "Detected Windows, falling back to using make: ${MAKE_EXECUTABLE}") + # fatal error when cross compiling + if(CMAKE_CROSSCOMPILING) + message(STATUS "System processor: ${CMAKE_SYSTEM_PROCESSOR}") + message(STATUS "Host system processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}") + message(FATAL_ERROR "Cross-compiling is not supported on Windows") + endif() + set(MSYSTEM "UCRT64") - find_file(MSYS2_EXECUTABLE NAMES msys2_shell.cmd REQUIRED HINTS D:/a/_temp/msys64 C:/msys64) + set(MSYS2_ARG "-ucrt64") + if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64") + set(MSYSTEM "CLANGARM64") + set(MSYS2_ARG "-clangarm64") + endif() + + find_file(MSYS2_EXECUTABLE NAMES msys2_shell.cmd REQUIRED HINTS ${MSYS2_ROOT}) message(STATUS "Found MSYS2: ${MSYS2_EXECUTABLE}") if(NOT DEFINED MSYS2_OPTION OR MSYS2_OPTION STREQUAL "1" OR MSYS2_OPTION STREQUAL "") - set(SHELL_CMD ${MSYS2_EXECUTABLE} -ucrt64 -defterm -here -no-start -shell bash -c) + set(SHELL_CMD ${MSYS2_EXECUTABLE} ${MSYS2_ARG} -defterm -here -no-start -shell bash -c) elseif(MSYS2_OPTION STREQUAL "2") # Theoretically, this is equivalent to the above configure_file(${CMAKE_CURRENT_SOURCE_DIR}/msys2.cmd.in ${CMAKE_CURRENT_BINARY_DIR}/msys2.cmd @ONLY) @@ -135,7 +154,7 @@ message(STATUS "Initial PKG_CONFIG_PATH: ${PKG_CONFIG_PATH}") find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config REQUIRED - HINTS D:/a/_temp/msys64/usr/bin C:/msys64/usr/bin /bin /usr/bin /usr/local/bin) + HINTS "${MSYS2_ROOT}/usr/bin" /bin /usr/bin /usr/local/bin) UNIX_PATH(PKG_CONFIG_EXECUTABLE ${PKG_CONFIG_EXECUTABLE}) message(STATUS "Found pkg-config: ${PKG_CONFIG_EXECUTABLE}") diff --git a/README.md b/README.md index c9fdc6815..4cc40186c 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,13 @@ brew install \ #### Windows -First, install [MSYS2](https://www.msys2.org/), then open the UCRT64 shell and run the following commands: +ℹ️ Cross-compilation is not supported on Windows. You must build on the target architecture. + +First, install [MSYS2](https://www.msys2.org/). + +##### x86_64 / amd64 + +Open the UCRT64 shell and run the following commands: ```bash pacman -Syu @@ -139,6 +145,26 @@ pacman -S \ mingw-w64-ucrt-x86_64-onevpl ``` +##### aarch64 / arm64 + +Open the CLANGARM64 shell and run the following commands: + +```bash +pacman -Syu +pacman -S \ + diffutils \ + git \ + make \ + pkg-config \ + mingw-w64-clang-aarch64-binutils \ + mingw-w64-clang-aarch64-cmake \ + mingw-w64-clang-aarch64-gcc \ + mingw-w64-clang-aarch64-make \ + mingw-w64-clang-aarch64-nasm \ + mingw-w64-clang-aarch64-ninja \ + mingw-w64-clang-aarch64-onevpl +``` + ### Configure Use the `Unix Makefiles` generator for Linux and macOS, and the `MSYS Makefiles` generator for Windows. diff --git a/cmake/ffmpeg/ffmpeg.cmake b/cmake/ffmpeg/ffmpeg.cmake index 4650691fc..7bcdc7745 100644 --- a/cmake/ffmpeg/ffmpeg.cmake +++ b/cmake/ffmpeg/ffmpeg.cmake @@ -52,17 +52,35 @@ list(APPEND FFMPEG_EXTRA_CONFIGURE if(WIN32) list(APPEND FFMPEG_EXTRA_CONFIGURE --enable-amf - --enable-cuda --enable-d3d11va --enable-encoder=h264_amf,hevc_amf,av1_amf --enable-encoder=h264_mf,hevc_mf - --enable-encoder=h264_nvenc,hevc_nvenc,av1_nvenc --enable-encoder=h264_qsv,hevc_qsv,av1_qsv - --enable-ffnvcodec --enable-libvpl - --enable-nvenc --enable-mediafoundation ) + + # On Windows Arm64 + # We must specify the arch parameter until one of the following issues is resolved + # + # https://github.com/msys2/msys2-runtime/issues/171 + # https://github.com/FFmpeg/FFmpeg/blob/4e5523c98597a417eb43555933b1075d18ec5f8b/configure#L4161 + # + # We must disable CUDA and NVENC until following issues is resolved + # + # https://github.com/FFmpeg/FFmpeg/blob/4e5523c98597a417eb43555933b1075d18ec5f8b/configure#L7443 + if(${arch} STREQUAL "aarch64" OR ${arch} STREQUAL "arm64") + list(APPEND FFMPEG_EXTRA_CONFIGURE + --arch=${arch} + ) + elseif (${arch} STREQUAL "amd64" OR ${arch} STREQUAL "x86_64") + list(APPEND FFMPEG_EXTRA_CONFIGURE + --enable-cuda + --enable-encoder=h264_nvenc,hevc_nvenc,av1_nvenc + --enable-ffnvcodec + --enable-nvenc + ) + endif() elseif(APPLE) list(APPEND FFMPEG_EXTRA_CONFIGURE --enable-encoder=h264_videotoolbox,hevc_videotoolbox diff --git a/cmake/ffmpeg/x264.cmake b/cmake/ffmpeg/x264.cmake index 2115a3bd3..58c4732ee 100644 --- a/cmake/ffmpeg/x264.cmake +++ b/cmake/ffmpeg/x264.cmake @@ -19,9 +19,9 @@ else() endif() if(WIN32) - set(X264_HOST ${X264_ARCH}-windows) + set(X264_HOST ${X264_ARCH}-mingw64) elseif(APPLE) - set(X264_HOST ${X264_ARCH}-macos) + set(X264_HOST ${X264_ARCH}-darwin) elseif(UNIX) set(X264_HOST ${X264_ARCH}-linux) else() @@ -37,6 +37,17 @@ if(CMAKE_CROSSCOMPILING) endif() endif() +# On Windows Arm64 +# We must specify the host parameter until one of the following issues is resolved +# +# https://github.com/msys2/msys2-runtime/issues/171 +# https://code.videolan.org/videolan/x264/-/tree/1ecc51ee971e0056a53bd6cf9c6f6af18b167e4b/config.guess#L809 +if(${X264_HOST} STREQUAL "aarch64-mingw64") + set(FFMPEG_X264_EXTRA_CONFIGURE + --host=${X264_HOST} + ) +endif() + # convert list to string # configure command will only take the first argument if not converted to string string(REPLACE ";" " " FFMPEG_X264_EXTRA_CONFIGURE "${FFMPEG_X264_EXTRA_CONFIGURE}") diff --git a/msys2.cmd.in b/msys2.cmd.in index f088754f1..e914d2bd2 100644 --- a/msys2.cmd.in +++ b/msys2.cmd.in @@ -3,4 +3,4 @@ setlocal IF NOT DEFINED MSYSTEM set MSYSTEM=@MSYSTEM@ IF NOT DEFINED MSYS2_PATH_TYPE set MSYS2_PATH_TYPE=inherit set CHERE_INVOKING=1 -@MSYS2_EXECUTABLE@ -ucrt64 -defterm -here -no-start -shell bash -c %* +@MSYS2_EXECUTABLE@ @MSYS2_ARG@ -defterm -here -no-start -shell bash -c %*