mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-10-11 08:27:48 +00:00
Transfers the majority of submodules and large externals to CPM, using source archives rather than full Git clones. Not only does this save massive amounts of clone and configure time, but dependencies are grabbed on-demand rather than being required by default. Additionally, CPM will (generally) automatically search for system dependencies, though certain dependencies have options to control this. Testing shows gains ranging from 5x to 10x in terms of overall clone/configure time. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/143 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
288 lines
11 KiB
CMake
288 lines
11 KiB
CMake
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
if (NOT WIN32 AND NOT ANDROID)
|
|
# Build FFmpeg from externals
|
|
message(STATUS "Using FFmpeg from externals")
|
|
|
|
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)")
|
|
# FFmpeg has source that requires one of nasm or yasm to assemble it.
|
|
# REQUIRED throws an error if not found here during configuration rather than during compilation.
|
|
find_program(ASSEMBLER NAMES nasm yasm)
|
|
if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND")
|
|
message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.")
|
|
endif()
|
|
endif()
|
|
|
|
find_program(AUTOCONF autoconf)
|
|
if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND")
|
|
message(FATAL_ERROR "Required program `autoconf` not found.")
|
|
endif()
|
|
|
|
include(CPM)
|
|
set(CPM_USE_LOCAL_PACKAGES OFF)
|
|
|
|
CPMAddPackage(
|
|
NAME ffmpeg
|
|
URL "https://github.com/ffmpeg/ffmpeg/archive/9c1294eadd.zip"
|
|
URL_HASH SHA512=2076e4cb843787c44718c70c4452517273dbc963ef98442f343762ade6c7b9f78555ae9b50a7c628844a15d8cb5e866c04e2f1acfb77093cea4fbc9edf3ad21a
|
|
CUSTOM_CACHE_KEY "9c12"
|
|
)
|
|
|
|
set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR})
|
|
set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR})
|
|
set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile)
|
|
make_directory(${FFmpeg_BUILD_DIR})
|
|
|
|
# Read version string from external
|
|
file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION)
|
|
set(FFmpeg_FOUND NO)
|
|
if (NOT FFmpeg_VERSION STREQUAL "")
|
|
set(FFmpeg_FOUND YES)
|
|
endif()
|
|
|
|
unset(FFmpeg_LIBRARIES CACHE)
|
|
|
|
foreach(COMPONENT ${FFmpeg_COMPONENTS})
|
|
set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}")
|
|
set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a")
|
|
set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}")
|
|
|
|
set(FFmpeg_LIBRARIES
|
|
${FFmpeg_LIBRARIES}
|
|
${FFmpeg_${COMPONENT}_LIBRARY}
|
|
CACHE PATH "Paths to FFmpeg libraries" FORCE)
|
|
endforeach()
|
|
|
|
find_package(PkgConfig REQUIRED)
|
|
if (NOT ANDROID)
|
|
pkg_check_modules(LIBVA libva)
|
|
pkg_check_modules(CUDA cuda)
|
|
pkg_check_modules(FFNVCODEC ffnvcodec)
|
|
pkg_check_modules(VDPAU vdpau)
|
|
endif()
|
|
|
|
set(FFmpeg_HWACCEL_LIBRARIES)
|
|
set(FFmpeg_HWACCEL_FLAGS)
|
|
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
|
|
set(FFmpeg_HWACCEL_LDFLAGS)
|
|
|
|
if(LIBVA_FOUND)
|
|
pkg_check_modules(LIBDRM libdrm REQUIRED)
|
|
find_package(X11 REQUIRED)
|
|
pkg_check_modules(LIBVA-DRM libva-drm REQUIRED)
|
|
pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED)
|
|
list(APPEND FFmpeg_HWACCEL_LIBRARIES
|
|
${LIBDRM_LIBRARIES}
|
|
${X11_LIBRARIES}
|
|
${LIBVA-DRM_LIBRARIES}
|
|
${LIBVA-X11_LIBRARIES}
|
|
${LIBVA_LIBRARIES})
|
|
set(FFmpeg_HWACCEL_FLAGS
|
|
--enable-hwaccel=h264_vaapi
|
|
--enable-hwaccel=vp8_vaapi
|
|
--enable-hwaccel=vp9_vaapi
|
|
--enable-libdrm)
|
|
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
|
|
${LIBDRM_INCLUDE_DIRS}
|
|
${X11_INCLUDE_DIRS}
|
|
${LIBVA-DRM_INCLUDE_DIRS}
|
|
${LIBVA-X11_INCLUDE_DIRS}
|
|
${LIBVA_INCLUDE_DIRS}
|
|
)
|
|
message(STATUS "VA-API found")
|
|
else()
|
|
set(FFmpeg_HWACCEL_FLAGS --disable-vaapi)
|
|
endif()
|
|
|
|
if (FFNVCODEC_FOUND)
|
|
list(APPEND FFmpeg_HWACCEL_FLAGS
|
|
--enable-cuvid
|
|
--enable-ffnvcodec
|
|
--enable-nvdec
|
|
--enable-hwaccel=h264_nvdec
|
|
--enable-hwaccel=vp8_nvdec
|
|
--enable-hwaccel=vp9_nvdec
|
|
)
|
|
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${FFNVCODEC_LIBRARIES})
|
|
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${FFNVCODEC_INCLUDE_DIRS})
|
|
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${FFNVCODEC_LDFLAGS})
|
|
message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found")
|
|
# ffnvenc could load CUDA libraries at the runtime using dlopen/dlsym or LoadLibrary/GetProcAddress
|
|
# here we handle the hard-linking senario where CUDA is linked during compilation
|
|
if (CUDA_FOUND)
|
|
# This line causes build error if CUDA_INCLUDE_DIRS is anything but a single non-empty value
|
|
#list(APPEND FFmpeg_HWACCEL_FLAGS --extra-cflags=-I${CUDA_INCLUDE_DIRS})
|
|
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${CUDA_LIBRARIES})
|
|
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS})
|
|
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${CUDA_LDFLAGS})
|
|
message(STATUS "CUDA libraries found, hard-linking will be performed")
|
|
endif(CUDA_FOUND)
|
|
endif()
|
|
|
|
if (VDPAU_FOUND)
|
|
list(APPEND FFmpeg_HWACCEL_FLAGS
|
|
--enable-vdpau
|
|
--enable-hwaccel=h264_vdpau
|
|
--enable-hwaccel=vp9_vdpau
|
|
)
|
|
list(APPEND FFmpeg_HWACCEL_LIBRARIES ${VDPAU_LIBRARIES})
|
|
list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${VDPAU_INCLUDE_DIRS})
|
|
list(APPEND FFmpeg_HWACCEL_LDFLAGS ${VDPAU_LDFLAGS})
|
|
message(STATUS "vdpau libraries version ${VDPAU_VERSION} found")
|
|
else()
|
|
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
|
|
endif()
|
|
|
|
find_program(BASH_PROGRAM bash REQUIRED)
|
|
|
|
set(FFmpeg_CROSS_COMPILE_FLAGS "")
|
|
if (ANDROID)
|
|
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME)
|
|
set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
|
set(SYSROOT "${TOOLCHAIN}/sysroot")
|
|
set(FFmpeg_CPU "armv8-a")
|
|
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
|
|
--arch=arm64
|
|
#--cpu=${FFmpeg_CPU}
|
|
--enable-cross-compile
|
|
--cross-prefix=${TOOLCHAIN}/bin/aarch64-linux-android-
|
|
--sysroot=${SYSROOT}
|
|
--target-os=android
|
|
--extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
|
|
--extra-ldflags="-nostdlib"
|
|
)
|
|
endif()
|
|
|
|
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
|
|
# `--disable-vdpau` is needed to avoid linking issues
|
|
set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
|
|
set(FFmpeg_CXX ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER})
|
|
add_custom_command(
|
|
OUTPUT
|
|
${FFmpeg_MAKEFILE}
|
|
COMMAND
|
|
${BASH_PROGRAM} ${FFmpeg_PREFIX}/configure
|
|
--disable-avdevice
|
|
--disable-avformat
|
|
--disable-doc
|
|
--disable-everything
|
|
--disable-ffmpeg
|
|
--disable-ffprobe
|
|
--disable-network
|
|
--disable-postproc
|
|
--disable-swresample
|
|
--enable-decoder=h264
|
|
--enable-decoder=vp8
|
|
--enable-decoder=vp9
|
|
--enable-filter=yadif,scale
|
|
--cc="${FFmpeg_CC}"
|
|
--cxx="${FFmpeg_CXX}"
|
|
${FFmpeg_HWACCEL_FLAGS}
|
|
${FFmpeg_CROSS_COMPILE_FLAGS}
|
|
WORKING_DIRECTORY
|
|
${FFmpeg_BUILD_DIR}
|
|
)
|
|
unset(FFmpeg_CC)
|
|
unset(FFmpeg_CXX)
|
|
unset(FFmpeg_HWACCEL_FLAGS)
|
|
unset(FFmpeg_CROSS_COMPILE_FLAGS)
|
|
|
|
# Workaround for Ubuntu 18.04's older version of make not being able to call make as a child
|
|
# with context of the jobserver. Also helps ninja users.
|
|
execute_process(
|
|
COMMAND
|
|
nproc
|
|
OUTPUT_VARIABLE
|
|
SYSTEM_THREADS)
|
|
|
|
set(FFmpeg_BUILD_LIBRARIES ${FFmpeg_LIBRARIES})
|
|
add_custom_command(
|
|
OUTPUT
|
|
${FFmpeg_BUILD_LIBRARIES}
|
|
COMMAND
|
|
make -j${SYSTEM_THREADS}
|
|
WORKING_DIRECTORY
|
|
${FFmpeg_BUILD_DIR}
|
|
)
|
|
|
|
set(FFmpeg_INCLUDE_DIR
|
|
"${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}"
|
|
CACHE PATH "Path to FFmpeg headers" FORCE)
|
|
|
|
set(FFmpeg_LDFLAGS
|
|
"${FFmpeg_HWACCEL_LDFLAGS}"
|
|
CACHE STRING "FFmpeg linker flags" FORCE)
|
|
|
|
# ALL makes this custom target build every time
|
|
# but it won't actually build if the DEPENDS parameter is up to date
|
|
add_custom_target(ffmpeg-configure ALL DEPENDS ${FFmpeg_MAKEFILE})
|
|
add_custom_target(ffmpeg-build ALL DEPENDS ${FFmpeg_BUILD_LIBRARIES} ffmpeg-configure)
|
|
link_libraries(${FFmpeg_LIBVA_LIBRARIES})
|
|
set(FFmpeg_LIBRARIES ${FFmpeg_BUILD_LIBRARIES} ${FFmpeg_HWACCEL_LIBRARIES}
|
|
CACHE PATH "Paths to FFmpeg libraries" FORCE)
|
|
unset(FFmpeg_BUILD_LIBRARIES)
|
|
unset(FFmpeg_HWACCEL_FLAGS)
|
|
unset(FFmpeg_HWACCEL_INCLUDE_DIRS)
|
|
unset(FFmpeg_HWACCEL_LDFLAGS)
|
|
unset(FFmpeg_HWACCEL_LIBRARIES)
|
|
|
|
if (FFmpeg_FOUND)
|
|
message(STATUS "Found FFmpeg version ${FFmpeg_VERSION}")
|
|
else()
|
|
message(FATAL_ERROR "FFmpeg not found")
|
|
endif()
|
|
elseif(ANDROID)
|
|
# Use yuzu FFmpeg binaries
|
|
if (ARCHITECTURE_arm64)
|
|
set(FFmpeg_EXT_NAME "ffmpeg-android-7.1.1-aarch64")
|
|
elseif (ARCHITECTURE_x86_64)
|
|
set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-x86_64")
|
|
else()
|
|
message(FATAL_ERROR "Unsupported architecture for Android FFmpeg")
|
|
endif()
|
|
|
|
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "ffmpeg-bundled" FFmpeg_PATH)
|
|
set(FFmpeg_FOUND YES)
|
|
set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
|
|
set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/lib" CACHE PATH "Path to FFmpeg library directory" FORCE)
|
|
set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
|
|
set(FFmpeg_LIBRARIES
|
|
${FFmpeg_LIBRARY_DIR}/libavcodec.so
|
|
${FFmpeg_LIBRARY_DIR}/libavdevice.so
|
|
${FFmpeg_LIBRARY_DIR}/libavfilter.so
|
|
${FFmpeg_LIBRARY_DIR}/libavformat.so
|
|
${FFmpeg_LIBRARY_DIR}/libavutil.so
|
|
${FFmpeg_LIBRARY_DIR}/libswresample.so
|
|
${FFmpeg_LIBRARY_DIR}/libswscale.so
|
|
${FFmpeg_LIBRARY_DIR}/libvpx.a
|
|
${FFmpeg_LIBRARY_DIR}/libx264.a
|
|
CACHE PATH "Paths to FFmpeg libraries" FORCE)
|
|
# exported variables
|
|
set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE)
|
|
set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE)
|
|
set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE)
|
|
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
|
|
elseif(WIN32)
|
|
# Use yuzu FFmpeg binaries
|
|
set(FFmpeg_EXT_NAME "ffmpeg-7.1.1")
|
|
|
|
download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "ffmpeg-bundled" FFmpeg_PATH)
|
|
set(FFmpeg_FOUND YES)
|
|
set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE)
|
|
set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE)
|
|
set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE)
|
|
set(FFmpeg_LIBRARIES
|
|
${FFmpeg_LIBRARY_DIR}/swscale.lib
|
|
${FFmpeg_LIBRARY_DIR}/avcodec.lib
|
|
${FFmpeg_LIBRARY_DIR}/avfilter.lib
|
|
${FFmpeg_LIBRARY_DIR}/avutil.lib
|
|
CACHE PATH "Paths to FFmpeg libraries" FORCE)
|
|
# exported variables
|
|
set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE)
|
|
set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE)
|
|
set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE)
|
|
set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
|
|
endif()
|
|
|
|
unset(FFmpeg_COMPONENTS)
|