[ffmpeg] multi arch support (#18635)

* Expand Architecture list with escape chars

This expands the architecture lists with escape characters. When
building FAT binaries for macos using multiple architectures in the
values they need to be escaped otherwise they are passed on to CMake
incorrectly #14932

* Adding the architecture fix to vcpkg-cmake port
updating port vcpkg-cmake version

* updated version in baseline

* Allow building ffmpeg for multiple architectures on macOS

Since ffmpeg does _not_ support multi-arch builds due to their use of
autotools and config.h which then includes the wrong platform-dependent
functions, we must perform two separate builds and join them using lipo

* fixup! Allow building ffmpeg for multiple architectures on macOS

* fixup! Allow building ffmpeg for multiple architectures on macOS

Co-authored-by: Sander Cox <sander@paralleldimension.nl>
Co-authored-by: Martijn Otto <martijn@resolume.com>
This commit is contained in:
omartijn 2021-07-01 18:24:59 +02:00 committed by GitHub
parent fad4d8eecc
commit 6d47a2faec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 119 additions and 10 deletions

View File

@ -15,6 +15,61 @@ cygpath() {
fi
}
move_binary() {
SOURCE=$1
TARGET=$2
BINARY=$3
# run lipo over the command to check whether it really
# is a binary that we need to merge architectures
lipo $SOURCE/$BINARY -info &> /dev/null || return 0
# get the directory name the file is in
DIRNAME=$(dirname $BINARY)
# ensure the directory to move the binary to exists
mkdir -p $TARGET/$DIRNAME
# now finally move the binary
mv $SOURCE/$BINARY $TARGET/$BINARY
}
move_binaries() {
SOURCE=$1
TARGET=$2
[ ! -d $SOURCE ] && return 0
pushd $SOURCE
for BINARY in $(find . -type f); do
move_binary $SOURCE $TARGET $BINARY
done
popd
}
merge_binaries() {
TARGET=$1
SOURCE=$2
shift
shift
pushd $SOURCE/$1
BINARIES=$(find . -type f)
popd
for BINARY in $BINARIES; do
COMMAND="lipo -create -output $TARGET/$BINARY"
for ARCH in $@; do
COMMAND="$COMMAND -arch $ARCH $SOURCE/$ARCH/$BINARY"
done
$($COMMAND)
done
}
export PKG_CONFIG_PATH="$(cygpath -p "${PKG_CONFIG_PATH}")"
# Export HTTP(S)_PROXY as http(s)_proxy:
@ -27,19 +82,45 @@ PATH_TO_PACKAGE_DIR=$(cygpath "@INST_PREFIX@")
JOBS=@VCPKG_CONCURRENCY@
OSX_ARCHS="@OSX_ARCHS@"
OSX_ARCH_COUNT=0@OSX_ARCH_COUNT@
# Default to hardware concurrency if unset.
: ${JOBS:=$(nproc)}
build_ffmpeg() {
echo "=== CONFIGURING ==="
sh "$PATH_TO_SRC_DIR/configure" "--prefix=$PATH_TO_PACKAGE_DIR" @CONFIGURE_OPTIONS@ $@
echo "=== BUILDING ==="
make -j${JOBS}
echo "=== INSTALLING ==="
make install
}
cd "$PATH_TO_BUILD_DIR"
echo "=== CONFIGURING ==="
if [ $OSX_ARCH_COUNT -gt 1 ]; then
for ARCH in $OSX_ARCHS; do
echo "=== CLEANING FOR $ARCH ==="
sh "$PATH_TO_SRC_DIR/configure" "--prefix=$PATH_TO_PACKAGE_DIR" @CONFIGURE_OPTIONS@
make clean && make distclean
echo "=== BUILDING ==="
build_ffmpeg --enable-cross-compile --arch=$ARCH --extra-cflags=-arch --extra-cflags=$ARCH --extra-ldflags=-arch --extra-ldflags=$ARCH
make -j${JOBS}
echo "=== COLLECTING BINARIES FOR $ARCH ==="
echo "=== INSTALLING ==="
move_binaries $PATH_TO_PACKAGE_DIR/lib $PATH_TO_BUILD_DIR/stage/$ARCH/lib
move_binaries $PATH_TO_PACKAGE_DIR/bin $PATH_TO_BUILD_DIR/stage/$ARCH/bin
done
make install
echo "=== MERGING ARCHITECTURES ==="
merge_binaries $PATH_TO_PACKAGE_DIR $PATH_TO_BUILD_DIR/stage $OSX_ARCHS
else
build_ffmpeg
fi

View File

@ -550,8 +550,22 @@ else()
set(OPTIONS "${OPTIONS} --disable-zlib")
endif()
set(CMAKE_VARS_FILE "${CURRENT_BUILDTREES_DIR}/vars.cmake")
vcpkg_internal_get_cmake_vars(OUTPUT_FILE CMAKE_VARS_FILE)
include("${CMAKE_VARS_FILE}")
if (VCPKG_TARGET_IS_OSX)
# if the sysroot isn't set in the triplet we fall back to whatever CMake detected for us
if ("${VCPKG_OSX_SYSROOT}" STREQUAL "")
set(VCPKG_OSX_SYSROOT ${VCPKG_DETECTED_CMAKE_OSX_SYSROOT})
endif()
set(OPTIONS "${OPTIONS} --disable-vdpau") # disable vdpau in OSX
set(OPTIONS "${OPTIONS} --extra-cflags=\"-isysroot ${VCPKG_OSX_SYSROOT}\"")
set(OPTIONS "${OPTIONS} --extra-ldflags=\"-isysroot ${VCPKG_OSX_SYSROOT}\"")
list(JOIN VCPKG_OSX_ARCHITECTURES " " OSX_ARCHS)
LIST(LENGTH VCPKG_OSX_ARCHITECTURES OSX_ARCH_COUNT)
endif()
set(OPTIONS_CROSS "")
@ -564,8 +578,17 @@ if (VCPKG_TARGET_ARCHITECTURE STREQUAL "arm" OR VCPKG_TARGET_ARCHITECTURE STREQU
get_filename_component(GAS_ITEM_PATH ${GAS_PATH} DIRECTORY)
set(ENV{PATH} "$ENV{PATH}${VCPKG_HOST_PATH_SEPARATOR}${GAS_ITEM_PATH}")
endforeach(GAS_PATH)
elseif(VCPKG_TARGET_IS_OSX) # VCPKG_TARGET_ARCHITECTURE = arm64
set(OPTIONS_CROSS " --enable-cross-compile --target-os=darwin --arch=arm64 --extra-ldflags=-arch --extra-ldflags=arm64 --extra-cflags=-arch --extra-cflags=arm64 --extra-cxxflags=-arch --extra-cxxflags=arm64")
elseif(VCPKG_TARGET_IS_OSX AND NOT VCPKG_TARGET_ARCHITECTURE STREQUAL "${VCPKG_DETECTED_CMAKE_SYSTEM_PROCESSOR}") # VCPKG_TARGET_ARCHITECTURE = arm64
# get the number of architectures requested
list(LENGTH VCPKG_OSX_ARCHITECTURES ARCHITECTURE_COUNT)
# ideally we should check the CMAKE_HOST_SYSTEM_PROCESSOR, but that seems to be
# broken when inside a vcpkg port, so we only set it when doing a simple build
# for a single platform. multi-platform builds use a different script
if (ARCHITECTURE_COUNT LESS 2)
message(STATUS "Building on host: ${CMAKE_SYSTEM_PROCESSOR}")
set(OPTIONS_CROSS " --enable-cross-compile --target-os=darwin --arch=arm64 --extra-ldflags=-arch --extra-ldflags=arm64 --extra-cflags=-arch --extra-cflags=arm64 --extra-cxxflags=-arch --extra-cxxflags=arm64")
endif()
endif()
elseif (VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
elseif (VCPKG_TARGET_ARCHITECTURE STREQUAL "x86")

View File

@ -1,7 +1,7 @@
{
"name": "ffmpeg",
"version": "4.4",
"port-version": 5,
"port-version": 6,
"description": [
"a library to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created.",
"FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created. It supports the most obscure ancient formats up to the cutting edge. No matter if they were designed by some standards committee, the community or a corporation. It is also highly portable: FFmpeg compiles, runs, and passes our testing infrastructure FATE across Linux, Mac OS X, Microsoft Windows, the BSDs, Solaris, etc. under a wide variety of build environments, machine architectures, and configurations."

View File

@ -1982,7 +1982,7 @@
},
"ffmpeg": {
"baseline": "4.4",
"port-version": 5
"port-version": 6
},
"ffnvcodec": {
"baseline": "10.0.26.0",

View File

@ -1,5 +1,10 @@
{
"versions": [
{
"git-tree": "8405d9f6850d7ceb6cede89a791b42c41253ef29",
"version": "4.4",
"port-version": 6
},
{
"git-tree": "234eb0e352d2a7be0a3b34fb9eb8a9f0417ffe94",
"version": "4.4",