From 0d8494abc0983df20c82017944c00aa5e63ff3fc Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Thu, 9 Apr 2026 15:58:42 -0700 Subject: [PATCH] Add Bazel build support Change-Id: Idf205997010a95f975dbd347e268e36c2072f797 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/7745020 Reviewed-by: Wan-Teh Chang Reviewed-by: richard winterton Commit-Queue: Frank Barchard --- BUILD.bazel | 217 ++++++++++++++++++++++++++++++++++++++++ WORKSPACE.bazel | 14 +++ docs/getting_started.md | 47 +++++++++ libyuv.bzl | 43 ++++++++ 4 files changed, 321 insertions(+) create mode 100644 BUILD.bazel create mode 100644 WORKSPACE.bazel create mode 100644 libyuv.bzl diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 000000000..d71502313 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,217 @@ +# Copyright 2026 The LibYuv Project Authors. All rights reserved. +# +# Description: +# The libyuv package provides implementation yuv image conversion, rotation +# and scaling. + +load("@bazel_skylib//lib:selects.bzl", "selects") +load(":libyuv.bzl", "libyuv_hdrs", "libyuv_neon_srcs", "libyuv_srcs", "libyuv_sve_srcs", "libyuv_test_srcs") + +# Detect if we are in Google's internal repository (where source files are +# under files/) or open source (where source files are at the root). +PREFIX = "files/" if len(native.glob(["files/source/*.cc"])) > 0 else "" + +# We support NEON for all arm processors, as we only support ARMv7a+. +SUPPORTS_NEON_COPTS = [ + "-DLIBYUV_NEON", +] + +# ARMv7a requires that we explicitly enable NEON. arm64 enables it implicitly. +ENABLE_NEON_COPTS = [ + "-mfpu=neon", +] + +ENABLE_NEON64_COPTS = [ + "-march=armv8-a+dotprod+i8mm", +] + +NEON_COPTS = select({ + "@platforms//cpu:armv7": ENABLE_NEON_COPTS + SUPPORTS_NEON_COPTS, + "@platforms//cpu:aarch64": ENABLE_NEON64_COPTS + SUPPORTS_NEON_COPTS, + "//conditions:default": [], +}) + +SUPPORTS_SVE_COPTS = [ + "-DLIBYUV_SVE", +] + +ENABLE_SVE_COPTS = [ + "-march=armv9-a+i8mm+sve2", +] + +SVE_COPTS = select({ + "@platforms//cpu:aarch64": ENABLE_SVE_COPTS + SUPPORTS_SVE_COPTS, + "//conditions:default": [], +}) + +PLATFORM_COPTS = select({ + "@platforms//os:android": ["-DHAVE_JPEG"], + "@platforms//os:linux": ["-DHAVE_JPEG"], + "@platforms//os:windows": ["-DHAVE_JPEG"], + "@platforms//os:macos": ["-DHAVE_JPEG"], + "//conditions:default": [], +}) + [ + "-DLIBYUV_DISABLE_SME", + "-DLIBYUV_USE_ABSL_FLAGS", + "-DGOOGLE_COMMANDLINEFLAGS_FULL_API", +] + +ALL_COPTS = PLATFORM_COPTS + +ALL_NEON_COPTS = NEON_COPTS + PLATFORM_COPTS + +ALL_SVE_COPTS = SVE_COPTS + PLATFORM_COPTS + +NEON_DEPS = select({ + "@platforms//cpu:armv7": [":libyuv_neon_impl"], + "@platforms//cpu:aarch64": [":libyuv_neon_impl"], + "//conditions:default": [], +}) + +SVE_DEPS = select({ + "@platforms//cpu:aarch64": [":libyuv_sve_impl"], + "//conditions:default": [], +}) + +PLATFORM_DEPS = select({ + "@platforms//os:android": ["@libjpeg_turbo//:jpeg"], + "@platforms//os:linux": ["@libjpeg_turbo//:jpeg"], + "@platforms//os:windows": ["@libjpeg_turbo//:jpeg"], + "@platforms//os:macos": ["@libjpeg_turbo//:jpeg"], + "//conditions:default": [], +}) + +ALL_DEPS = NEON_DEPS + SVE_DEPS + PLATFORM_DEPS + +cc_library( + name = "libyuv", + hdrs = native.glob([PREFIX + "include/**/*.h"]), + strip_include_prefix = PREFIX + "include", + visibility = ["//visibility:public"], + deps = [":libyuv_impl"], +) + +cc_library( + name = "libyuv_impl", + srcs = libyuv_srcs(PREFIX), + hdrs = libyuv_hdrs(PREFIX), + copts = ALL_COPTS + selects.with_or({ + ( + "@platforms//os:android", + "@platforms//os:ios", + "@platforms//os:tvos", + "@platforms//os:windows", + "@platforms//os:macos", + ): [], + "//conditions:default": [ + "-fomit-frame-pointer", + ], + }) + selects.with_or({ + ( + "@platforms//os:android", + "@platforms//os:ios", + "@platforms//os:tvos", + ): ["-O2"], + "//conditions:default": [], + }), + includes = [PREFIX + "include"], + deps = ALL_DEPS, + alwayslink = 1, +) + +cc_library( + name = "libyuv_neon_impl", + srcs = libyuv_neon_srcs(PREFIX), + copts = ALL_NEON_COPTS, + includes = [PREFIX + "include"], + visibility = ["//visibility:private"], + alwayslink = 1, +) + +cc_library( + name = "libyuv_sve_impl", + srcs = libyuv_sve_srcs(PREFIX), + copts = ALL_SVE_COPTS, + includes = [PREFIX + "include"], + visibility = ["//visibility:private"], + alwayslink = 1, +) + +cc_test( + name = "libyuv_test", + srcs = libyuv_test_srcs(PREFIX), + copts = ALL_COPTS + [ + "-Wno-unused-variable", + ], + visibility = ["//visibility:public"], + deps = [ + ":libyuv", + "@com_google_googletest//:gtest_main", + "@com_google_absl//absl/flags:flag", + "@com_google_absl//absl/flags:parse", + ], +) + +cc_library( + name = "psnr_lib", + srcs = [PREFIX + "util/psnr.cc"], + hdrs = [PREFIX + "util/psnr.h"], + copts = PLATFORM_COPTS, + visibility = ["//visibility:private"], +) + +cc_library( + name = "ssim_lib", + srcs = [PREFIX + "util/ssim.cc"], + hdrs = [PREFIX + "util/ssim.h"], + visibility = ["//visibility:private"], +) + +cc_binary( + name = "psnr", + srcs = [PREFIX + "util/psnr_main.cc"], + copts = PLATFORM_COPTS + [ + "-Wframe-larger-than=64000", + ], + deps = [ + ":libyuv", + ":psnr_lib", + ":ssim_lib", + ], +) + +cc_binary( + name = "i444tonv12_eg", + srcs = [PREFIX + "util/i444tonv12_eg.cc"], + visibility = ["//visibility:public"], + deps = [ + ":libyuv", + ], +) + +cc_binary( + name = "cpuid", + srcs = [PREFIX + "util/cpuid.c"], + visibility = ["//visibility:public"], + deps = [ + ":libyuv", + ], +) + +cc_binary( + name = "yuvconstants", + srcs = [PREFIX + "util/yuvconstants.c"], + visibility = ["//visibility:public"], + deps = [ + ":libyuv", + ], +) + +cc_binary( + name = "yuvconvert", + srcs = [PREFIX + "util/yuvconvert.cc"], + visibility = ["//visibility:public"], + deps = [ + ":libyuv", + ], +) diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel new file mode 100644 index 000000000..0b288ac64 --- /dev/null +++ b/WORKSPACE.bazel @@ -0,0 +1,14 @@ +workspace(name = "libyuv") + +android_sdk_repository( + name = "androidsdk", + # Bazel will automatically use the ANDROID_HOME environment variable. +) + +android_ndk_repository( + name = "androidndk", + # Bazel will automatically use the ANDROID_NDK_HOME environment variable. +) + +# Optional: If you need to fetch specific dependencies (e.g., GoogleTest, libjpeg-turbo) +# you can define them here using http_archive. diff --git a/docs/getting_started.md b/docs/getting_started.md index 1ecfe438e..6f5593576 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -43,6 +43,39 @@ To get just the source (not buildable): ## Building the Library and Unittests +### Bazel + +Libyuv can be built using [Bazel](https://bazel.build/). + +#### Android Prerequisites +To build for Android using Bazel, you must have the Android SDK and NDK installed. Bazel will look for the following environment variables to locate them: +* `ANDROID_HOME`: Set this to the path of your Android SDK. +* `ANDROID_NDK_HOME`: Set this to the path of your Android NDK. + +Ensure these variables are set before running the Bazel Android build commands. + +**Android arm64:** + + bazel build -c opt --config=android_arm64 //:libyuv_test + + # Or, specifying standard open-source flags (if NDK is set up in workspace): + bazel build -c opt --cpu=arm64-v8a --crosstool_top=//external:android/crosstool //:libyuv_test + +**Linux x86_64:** + + bazel build -c opt //:libyuv_test + + # Or, specifying a specific CPU architecture: + bazel build -c opt --cpu=haswell //:libyuv_test + +Additional commonly used compiler options can be passed to Bazel via `--copt`: + + bazel build -c opt --config=android_arm64 \ + --copt=-DLIBYUV_UNLIMITED_DATA \ + --copt=-DLIBYUV_BIT_EXACT=1 \ + --copt=-DENABLE_ROW_TESTS \ + //:libyuv_test + ### Windows gn gen out\Release "--args=is_debug=false target_cpu=\"x64\"" @@ -251,6 +284,20 @@ See also https://www.ccoderun.ca/programming/2015-12-20_CrossCompiling/index.htm ## Running Unittests +### Bazel + +You can run the tests using Bazel's `test` command. This will build and run the test in an isolated environment: + + bazel test -c opt //:libyuv_test + +To pass specific arguments to the test binary (like a gtest filter), use `--test_arg`: + + bazel test -c opt //:libyuv_test --test_arg=--gtest_filter="*" --test_output=all + +Alternatively, you can run the compiled binary directly from the `bazel-bin` directory: + + ./bazel-bin/libyuv_test --gtest_filter="*" + ### Windows out\Release\libyuv_unittest.exe --gtest_catch_exceptions=0 --gtest_filter="*" diff --git a/libyuv.bzl b/libyuv.bzl new file mode 100644 index 000000000..53e23019b --- /dev/null +++ b/libyuv.bzl @@ -0,0 +1,43 @@ +# Copyright 2026 The LibYuv Project Authors. All rights reserved. +# +# Shared target definitions for Bazel and Blaze builds. + +def libyuv_srcs(prefix = ""): + return native.glob( + [ + prefix + "source/*.cc", + prefix + "include/libyuv/*.h", + ], + exclude = [ + prefix + "source/*neon*.cc", + prefix + "source/*sve*.cc", + prefix + "source/*sme*.cc", + ], + ) + +def libyuv_hdrs(prefix = ""): + return [ + prefix + "include/libyuv/compare.h", + prefix + "include/libyuv/convert.h", + prefix + "include/libyuv/convert_from_argb.h", + prefix + "include/libyuv/cpu_id.h", + prefix + "include/libyuv/row.h", + ] + +def libyuv_neon_srcs(prefix = ""): + return native.glob([ + prefix + "source/*neon*.cc", + prefix + "include/libyuv/*.h", + ]) + +def libyuv_sve_srcs(prefix = ""): + return native.glob([ + prefix + "source/*sve*.cc", + prefix + "include/libyuv/*.h", + ]) + +def libyuv_test_srcs(prefix = ""): + return native.glob([ + prefix + "unit_test/*.cc", + prefix + "unit_test/*.h", + ])