mcap/modules/ffmpeg/build_macos.jai

118 lines
5.2 KiB
Plaintext

// Builds the FFmpeg 6.0 libraries mcap uses on macOS (avformat, avcodec, avutil, swscale and
// swresample) from the release's source, its SHA-256 checked, and puts them in macos/ with the
// headers the bindings are made from (generate.jai) in macos-build/install/include. The same version
// as the Windows DLLs (windows/), so the two sets of bindings match.
//
// cd modules/ffmpeg && jai build_macos.jai
//
// An LGPL build: no GPL parts (the Windows DLLs are a GPL build with libx264), nothing from outside
// macOS (--disable-autodetect, pkg-config pointed nowhere, so nothing from Homebrew is linked), and
// VideoToolbox and AudioToolbox for the hardware codecs. Needs Apple's command line tools: curl,
// tar, make and clang. A few minutes on Apple silicon.
FFMPEG_VERSION :: "6.0";
FFMPEG_ARCHIVE :: "ffmpeg-6.0.tar.xz";
FFMPEG_SHA256 :: "57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082";
BUILD_FOLDER :: "macos-build"; // the source, the build and the installed headers; not in git
OUTPUT_FOLDER :: "macos"; // the libraries, in git as windows/ is
// Each library as its major version names it, which is how they find each other (@rpath/...).
LIBRARIES :: string.["libavcodec.60.dylib", "libavformat.60.dylib", "libavutil.58.dylib", "libswresample.4.dylib", "libswscale.7.dylib"];
CONFIGURE_OPTIONS :: string.[
"--install-name-dir=@rpath",
"--enable-shared", "--disable-static",
"--disable-programs", "--disable-doc",
"--disable-avdevice", "--disable-avfilter", "--disable-postproc", "--disable-network",
"--disable-autodetect",
"--enable-videotoolbox", "--enable-audiotoolbox", "--enable-zlib", "--enable-bzlib",
"--extra-cflags=-mmacosx-version-min=14.0", "--extra-ldflags=-mmacosx-version-min=14.0",
];
#run,stallable {
set_build_options_dc(.{do_output = false});
#if OS != .MACOS {
log_error("build_macos.jai builds on a Mac only.");
return;
}
if !build() compiler_set_workspace_status(.FAILED);
}
build :: () -> bool {
here := get_working_directory();
build_folder := tprint("%/%", here, BUILD_FOLDER);
make_directory_if_it_does_not_exist(build_folder);
archive := tprint("%/%", build_folder, FFMPEG_ARCHIVE);
if !file_exists(archive) || sha256_of(archive) != FFMPEG_SHA256 {
url := tprint("https://ffmpeg.org/releases/%", FFMPEG_ARCHIVE);
log("Downloading %...", url);
result := run_command("curl", "-L", "--fail", "--progress-bar", "-o", archive, url);
if result.exit_code != 0 { log_error("curl failed (exit code %).", result.exit_code); return false; }
hash := sha256_of(archive);
if hash != FFMPEG_SHA256 {
log_error("% has SHA-256 %, expected %; it was not used.", archive, hash, FFMPEG_SHA256);
return false;
}
}
source := tprint("%/ffmpeg-%", build_folder, FFMPEG_VERSION);
install := tprint("%/install", build_folder);
run_command("rm", "-rf", source, install);
result := run_command("tar", "xf", archive, "-C", build_folder);
if result.exit_code != 0 { log_error("tar could not unpack %.", archive); return false; }
log("Configuring...");
arguments: [..] string;
array_add(*arguments, "env", "PKG_CONFIG_LIBDIR=", "PKG_CONFIG_PATH=", "./configure", tprint("--prefix=%", install));
array_add(*arguments, ..CONFIGURE_OPTIONS);
result = run_command(..arguments, working_directory = source);
if result.exit_code != 0 { log_error("configure failed; see %/ffbuild/config.log.", source); return false; }
log("Building...");
cpus := get_number_of_processors();
result = run_command("make", tprint("-j%", cpus), working_directory = source);
if result.exit_code != 0 { log_error("make failed."); return false; }
result = run_command("make", "install", working_directory = source);
if result.exit_code != 0 { log_error("make install failed."); return false; }
output := tprint("%/%", here, OUTPUT_FOLDER);
run_command("rm", "-rf", output);
make_directory_if_it_does_not_exist(output);
for LIBRARIES {
// The major-version name is a link to the full one; the file itself is copied under that name.
if !copy_file(tprint("%/lib/%", install, it), tprint("%/%", output, it)) { log_error("Could not copy %.", it); return false; }
run_command("strip", "-x", tprint("%/%", output, it));
}
write_entire_file(tprint("%/LICENSE-BUILD.txt", output), tprint(LICENSE_TEXT, FFMPEG_VERSION, FFMPEG_ARCHIVE, FFMPEG_SHA256, join(..CONFIGURE_OPTIONS, "\n ")));
log("Put % libraries in % and the headers in %/include (FFmpeg %, LGPL).", LIBRARIES.count, output, install, FFMPEG_VERSION);
return true;
}
LICENSE_TEXT :: #string TEXT
FFmpeg % shared libraries for macOS on Apple silicon, built by modules/ffmpeg/build_macos.jai.
Source: https://ffmpeg.org/releases/%
SHA-256: %
License: LGPL version 2.1 or later (no GPL or non-free parts). The source is at the address above;
the libraries are built from it unchanged, with these configure options:
%
TEXT
// Lowercase hex, or "" when it could not be worked out.
sha256_of :: (path: string) -> string {
result, output := run_command("shasum", "-a", "256", path, capture_and_return_output = true);
if result.exit_code != 0 return "";
return to_lower_copy(trim(split(output, " ")[0]));
}
#import "Basic";
#import "Compiler";
#import "File";
#import "File_Utilities";
#import "Process";
#import "String";
#import "System";