blob: 7e42aeccd92b69ad6148fe3fa1c0efda829ed8a2 [file] [log] [blame]
jpegxl-botf84edfb2020-04-20 09:48:41 +02001#!/usr/bin/env bash
jpegxl-botff093712019-12-27 18:12:34 +01002# Copyright (c) the JPEG XL Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16# Continuous integration helper module. This module is meant to be called from
17# the .gitlab-ci.yml file during the continuous integration build, as well as
18# from the command line for developers.
19
20set -eu
21
22OS=`uname -s`
23
24MYDIR=$(dirname $(realpath "$0"))
25
26### Environment parameters:
jpegxl-bot849ebf62020-09-29 16:23:20 +020027TEST_STACK_LIMIT="${TEST_STACK_LIMIT:-128}"
jpegxl-botff093712019-12-27 18:12:34 +010028CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-RelWithDebInfo}
29CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH:-}
jpegxl-bot50bbf272020-06-10 14:59:11 +020030CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER:-}
31CMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER:-}
jpegxl-bote3c58a02020-06-15 08:51:22 +020032CMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM:-}
jpegxl-botff093712019-12-27 18:12:34 +010033SKIP_TEST="${SKIP_TEST:-0}"
34BUILD_TARGET="${BUILD_TARGET:-}"
jpegxl-botf84edfb2020-04-20 09:48:41 +020035ENABLE_WASM_SIMD="${ENABLE_WASM_SIMD:-0}"
jpegxl-botff093712019-12-27 18:12:34 +010036if [[ -n "${BUILD_TARGET}" ]]; then
37 BUILD_DIR="${BUILD_DIR:-${MYDIR}/build-${BUILD_TARGET%%-*}}"
38else
39 BUILD_DIR="${BUILD_DIR:-${MYDIR}/build}"
40fi
41# Whether we should post a message in the MR when the build fails.
42POST_MESSAGE_ON_ERROR="${POST_MESSAGE_ON_ERROR:-1}"
43
jpegxl-bot9e183e12020-10-29 12:36:26 +010044# Set default compilers to clang if not already set
45export CC=${CC:-clang}
46export CXX=${CXX:-clang++}
47
jpegxl-botf84edfb2020-04-20 09:48:41 +020048# Time limit for the "fuzz" command in seconds (0 means no limit).
49FUZZER_MAX_TIME="${FUZZER_MAX_TIME:-0}"
50
jpegxl-bot63349442020-05-25 08:56:34 +020051SANITIZER="none"
52
53if [[ "${BUILD_TARGET}" == wasm* ]]; then
54 # Check that environment is setup for the WASM build target.
55 if [[ -z "${EMSCRIPTEN}" ]]; then
56 echo "'EMSCRIPTEN' is not defined. Use 'emconfigure' wrapper to setup WASM build environment" >&2
57 return 1
58 fi
jpegxl-bote3c58a02020-06-15 08:51:22 +020059 # Remove the side-effect of "emconfigure" wrapper - it considers NodeJS environment.
60 unset EMMAKEN_JUST_CONFIGURE
jpegxl-bot63349442020-05-25 08:56:34 +020061 EMS_TOOLCHAIN_FILE="${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake"
62 if [[ -f "${EMS_TOOLCHAIN_FILE}" ]]; then
63 CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE:-${EMS_TOOLCHAIN_FILE}}
64 else
65 echo "Warning: EMSCRIPTEN CMake module not found" >&2
66 fi
jpegxl-bote3c58a02020-06-15 08:51:22 +020067 CMAKE_CROSSCOMPILING_EMULATOR="${MYDIR}/js-wasm-wrapper.sh"
jpegxl-bot63349442020-05-25 08:56:34 +020068fi
69
70if [[ "${BUILD_TARGET%%-*}" == "x86_64" ||
71 "${BUILD_TARGET%%-*}" == "i686" ]]; then
72 # Default to building all targets, even if compiler baseline is SSE4
73 HWY_BASELINE_TARGETS=${HWY_BASELINE_TARGETS:-HWY_SCALAR}
74else
75 HWY_BASELINE_TARGETS=${HWY_BASELINE_TARGETS:-}
76fi
jpegxl-botf84edfb2020-04-20 09:48:41 +020077
jpegxl-botff093712019-12-27 18:12:34 +010078# Convenience flag to pass both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS
jpegxl-bot0709f3a2020-02-19 14:37:22 +010079CMAKE_FLAGS=${CMAKE_FLAGS:-}
jpegxl-botb3a65712020-02-06 13:22:22 +010080CMAKE_C_FLAGS="${CMAKE_C_FLAGS:-} ${CMAKE_FLAGS}"
81CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS:-} ${CMAKE_FLAGS}"
jpegxl-botf84edfb2020-04-20 09:48:41 +020082
jpegxl-botb3a65712020-02-06 13:22:22 +010083CMAKE_CROSSCOMPILING_EMULATOR=${CMAKE_CROSSCOMPILING_EMULATOR:-}
jpegxl-botff093712019-12-27 18:12:34 +010084CMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS:-}
jpegxl-botf84edfb2020-04-20 09:48:41 +020085CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH:-}
jpegxl-botff093712019-12-27 18:12:34 +010086CMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS:-}
87CMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS:-}
88CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE:-}
89
jpegxl-botf84edfb2020-04-20 09:48:41 +020090if [[ "${ENABLE_WASM_SIMD}" -ne "0" ]]; then
jpegxl-bot849ebf62020-09-29 16:23:20 +020091 CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -msimd128"
92 CMAKE_C_FLAGS="${CMAKE_C_FLAGS} -msimd128"
93 CMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS} -msimd128"
jpegxl-botf84edfb2020-04-20 09:48:41 +020094fi
95
jpegxl-bot63349442020-05-25 08:56:34 +020096if [[ ! -z "${HWY_BASELINE_TARGETS}" ]]; then
97 CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -DHWY_BASELINE_TARGETS=${HWY_BASELINE_TARGETS}"
98fi
jpegxl-botf84edfb2020-04-20 09:48:41 +020099
jpegxl-bot0709f3a2020-02-19 14:37:22 +0100100# Version inferred from the CI variables.
101CI_COMMIT_SHA=${CI_COMMIT_SHA:-}
102JPEGXL_VERSION=${JPEGXL_VERSION:-${CI_COMMIT_SHA:0:8}}
jpegxl-botff093712019-12-27 18:12:34 +0100103
104# Benchmark parameters
105STORE_IMAGES=${STORE_IMAGES:-1}
106BENCHMARK_CORPORA="${MYDIR}/third_party/corpora"
107
108# Local flags passed to sanitizers.
109UBSAN_FLAGS=(
110 -fsanitize=alignment
111 -fsanitize=bool
112 -fsanitize=bounds
113 -fsanitize=builtin
114 -fsanitize=enum
115 -fsanitize=float-cast-overflow
116 -fsanitize=float-divide-by-zero
117 -fsanitize=integer-divide-by-zero
118 -fsanitize=null
119 -fsanitize=object-size
120 -fsanitize=pointer-overflow
121 -fsanitize=return
122 -fsanitize=returns-nonnull-attribute
123 -fsanitize=shift-base
124 -fsanitize=shift-exponent
125 -fsanitize=unreachable
126 -fsanitize=vla-bound
127
128 -fno-sanitize-recover=undefined
129 # Brunsli uses unaligned accesses to uint32_t, so alignment is just a warning.
130 -fsanitize-recover=alignment
131)
132# -fsanitize=function doesn't work on aarch64 and arm.
133if [[ "${BUILD_TARGET%%-*}" != "aarch64" &&
134 "${BUILD_TARGET%%-*}" != "arm" ]]; then
135 UBSAN_FLAGS+=(
136 -fsanitize=function
137 )
138fi
139if [[ "${BUILD_TARGET%%-*}" != "arm" ]]; then
140 UBSAN_FLAGS+=(
141 -fsanitize=signed-integer-overflow
142 )
143fi
144
jpegxl-bot63349442020-05-25 08:56:34 +0200145CLANG_TIDY_BIN=$(which clang-tidy-6.0 clang-tidy-7 clang-tidy-8 clang-tidy | head -n 1)
jpegxl-botff093712019-12-27 18:12:34 +0100146# Default to "cat" if "colordiff" is not installed or if stdout is not a tty.
147if [[ -t 1 ]]; then
148 COLORDIFF_BIN=$(which colordiff cat | head -n 1)
149else
150 COLORDIFF_BIN="cat"
151fi
jpegxl-botf84edfb2020-04-20 09:48:41 +0200152FIND_BIN=$(which gfind find | head -n 1)
153# "false" will disable wine64 when not installed. This won't allow
154# cross-compiling.
155WINE_BIN=$(which wine64 false | head -n 1)
jpegxl-botff093712019-12-27 18:12:34 +0100156
157CLANG_VERSION="${CLANG_VERSION:-}"
158# Detect the clang version suffix and store it in CLANG_VERSION. For example,
159# "6.0" for clang 6 or "7" for clang 7.
160detect_clang_version() {
161 if [[ -n "${CLANG_VERSION}" ]]; then
162 return 0
163 fi
164 local clang_version=$("${CC:-clang}" --version | head -n1)
jpegxl-bot35ad23d2021-01-29 00:08:06 +0100165 clang_version=${clang_version#"Debian "}
jpegxl-botff093712019-12-27 18:12:34 +0100166 local llvm_tag
167 case "${clang_version}" in
168 "clang version 6."*)
169 CLANG_VERSION="6.0"
170 ;;
jpegxl-bote3c58a02020-06-15 08:51:22 +0200171 "clang version "*)
172 # Any other clang version uses just the major version number.
173 local suffix="${clang_version#clang version }"
174 CLANG_VERSION="${suffix%%.*}"
jpegxl-bot63349442020-05-25 08:56:34 +0200175 ;;
176 "emcc"*)
177 # We can't use asan or msan in the emcc case.
178 ;;
jpegxl-botff093712019-12-27 18:12:34 +0100179 *)
180 echo "Unknown clang version: ${clang_version}" >&2
181 return 1
182 esac
183}
184
185# Temporary files cleanup hooks.
186CLEANUP_FILES=()
187cleanup() {
188 if [[ ${#CLEANUP_FILES[@]} -ne 0 ]]; then
189 rm -fr "${CLEANUP_FILES[@]}"
190 fi
191}
192
193# Executed on exit.
194on_exit() {
195 local retcode="$1"
196 # Always cleanup the CLEANUP_FILES.
197 cleanup
198
199 # Post a message in the MR when requested with POST_MESSAGE_ON_ERROR but only
200 # if the run failed and we are not running from a MR pipeline.
201 if [[ ${retcode} -ne 0 && -n "${CI_BUILD_NAME:-}" &&
202 -n "${POST_MESSAGE_ON_ERROR}" && -z "${CI_MERGE_REQUEST_ID:-}" &&
203 "${CI_BUILD_REF_NAME}" = "master" ]]; then
204 load_mr_vars_from_commit
205 { set +xeu; } 2>/dev/null
206 local message="**Run ${CI_BUILD_NAME} @ ${CI_COMMIT_SHORT_SHA} failed.**
207
208Check the output of the job at ${CI_JOB_URL:-} to see if this was your problem.
209If it was, please rollback this change or fix the problem ASAP, broken builds
210slow down development. Check if the error already existed in the previous build
211as well.
212
213Pipeline: ${CI_PIPELINE_URL}
214
215Previous build commit: ${CI_COMMIT_BEFORE_SHA}
216"
217 cmd_post_mr_comment "${message}"
218 fi
219}
220
221trap 'retcode=$?; { set +x; } 2>/dev/null; on_exit ${retcode}' INT TERM EXIT
222
223
224# These variables are populated when calling merge_request_commits().
225
226# The current hash at the top of the current branch or merge request branch (if
227# running from a merge request pipeline).
228MR_HEAD_SHA=""
229# The common ancestor between the current commit and the tracked branch, such
230# as master. This includes a list
231MR_ANCESTOR_SHA=""
232
233# Populate MR_HEAD_SHA and MR_ANCESTOR_SHA.
234merge_request_commits() {
235 { set +x; } 2>/dev/null
236 # CI_BUILD_REF is the reference currently being build in the CI workflow.
237 MR_HEAD_SHA=$(git -C "${MYDIR}" rev-parse -q "${CI_BUILD_REF:-HEAD}")
238 if [[ -z "${CI_MERGE_REQUEST_IID:-}" ]]; then
239 # We are in a local branch, not a merge request.
240 MR_ANCESTOR_SHA=$(git -C "${MYDIR}" rev-parse -q HEAD@{upstream} || true)
241 else
242 # Merge request pipeline in CI. In this case the upstream is called "origin"
243 # but it refers to the forked project that's the source of the merge
244 # request. We need to get the target of the merge request, for which we need
245 # to query that repository using our CI_JOB_TOKEN.
246 echo "machine gitlab.com login gitlab-ci-token password ${CI_JOB_TOKEN}" \
247 >> "${HOME}/.netrc"
248 git -C "${MYDIR}" fetch "${CI_MERGE_REQUEST_PROJECT_URL}" \
249 "${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}"
250 MR_ANCESTOR_SHA=$(git -C "${MYDIR}" rev-parse -q FETCH_HEAD)
251 fi
252 if [[ -z "${MR_ANCESTOR_SHA}" ]]; then
253 echo "Warning, not tracking any branch, using the last commit in HEAD.">&2
254 # This prints the return value with just HEAD.
255 MR_ANCESTOR_SHA=$(git -C "${MYDIR}" rev-parse -q "${MR_HEAD_SHA}^")
256 else
257 MR_ANCESTOR_SHA=$(git -C "${MYDIR}" merge-base --all \
258 "${MR_ANCESTOR_SHA}" "${MR_HEAD_SHA}")
259 fi
260 set -x
261}
262
263# Load the MR iid from the landed commit message when running not from a
264# merge request workflow. This is useful to post back results at the merge
265# request when running pipelines from master.
266load_mr_vars_from_commit() {
267 { set +x; } 2>/dev/null
268 if [[ -z "${CI_MERGE_REQUEST_IID:-}" ]]; then
269 local mr_iid=$(git rev-list --format=%B --max-count=1 HEAD |
jpegxl-bot0709f3a2020-02-19 14:37:22 +0100270 grep -F "${CI_PROJECT_URL}" | grep -F "/merge_requests" | head -n 1)
jpegxl-botff093712019-12-27 18:12:34 +0100271 # mr_iid contains a string like this if it matched:
272 # Part-of: <https://gitlab.com/wg1/jpeg-xlm/merge_requests/123456>
273 if [[ -n "${mr_iid}" ]]; then
274 mr_iid=$(echo "${mr_iid}" |
275 sed -E 's,^.*merge_requests/([0-9]+)>.*$,\1,')
276 CI_MERGE_REQUEST_IID="${mr_iid}"
277 CI_MERGE_REQUEST_PROJECT_ID=${CI_PROJECT_ID}
278 fi
279 fi
280 set -x
281}
282
283# Posts a comment to the current merge request.
284cmd_post_mr_comment() {
285 { set +x; } 2>/dev/null
286 local comment="$1"
287 if [[ -n "${BOT_TOKEN:-}" && -n "${CI_MERGE_REQUEST_IID:-}" ]]; then
288 local url="${CI_API_V4_URL}/projects/${CI_MERGE_REQUEST_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes"
289 curl -X POST -g \
290 -H "PRIVATE-TOKEN: ${BOT_TOKEN}" \
291 --data-urlencode "body=${comment}" \
292 --output /dev/null \
293 "${url}"
294 fi
295 set -x
296}
297
jpegxl-botf84edfb2020-04-20 09:48:41 +0200298# Set up and export the environment variables needed by the child processes.
299export_env() {
300 if [[ "${BUILD_TARGET}" == *mingw32 ]]; then
301 # Wine needs to know the paths to the mingw dlls. These should be
302 # separated by ';'.
303 WINEPATH=$("${CC:-clang}" -print-search-dirs --target="${BUILD_TARGET}" \
304 | grep -F 'libraries: =' | cut -f 2- -d '=' | tr ':' ';')
305 # We also need our own libraries in the wine path.
306 local real_build_dir=$(realpath "${BUILD_DIR}")
jpegxl-bot9e183e12020-10-29 12:36:26 +0100307 # Some library .dll dependencies are installed in /bin:
jpegxl-botab7c5e92021-04-21 19:22:38 +0200308 export WINEPATH="${WINEPATH};${real_build_dir};${real_build_dir}/third_party/brotli;/usr/${BUILD_TARGET}/bin"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200309
310 local prefix="${BUILD_DIR}/wineprefix"
311 mkdir -p "${prefix}"
312 export WINEPREFIX=$(realpath "${prefix}")
313 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200314 # Sanitizers need these variables to print and properly format the stack
315 # traces:
jpegxl-bote3c58a02020-06-15 08:51:22 +0200316 LLVM_SYMBOLIZER=$("${CC:-clang}" -print-prog-name=llvm-symbolizer || true)
317 if [[ -n "${LLVM_SYMBOLIZER}" ]]; then
jpegxl-bot63349442020-05-25 08:56:34 +0200318 export ASAN_SYMBOLIZER_PATH="${LLVM_SYMBOLIZER}"
319 export MSAN_SYMBOLIZER_PATH="${LLVM_SYMBOLIZER}"
320 export UBSAN_SYMBOLIZER_PATH="${LLVM_SYMBOLIZER}"
321 fi
jpegxl-botf84edfb2020-04-20 09:48:41 +0200322}
323
jpegxl-botff093712019-12-27 18:12:34 +0100324cmake_configure() {
jpegxl-botf84edfb2020-04-20 09:48:41 +0200325 export_env
jpegxl-bot849ebf62020-09-29 16:23:20 +0200326
327 if [[ "${STACK_SIZE:-0}" == 1 ]]; then
328 # Dump the stack size of each function in the .stack_sizes section for
329 # analysis.
330 CMAKE_C_FLAGS+=" -fstack-size-section"
331 CMAKE_CXX_FLAGS+=" -fstack-size-section"
332 fi
333
jpegxl-botff093712019-12-27 18:12:34 +0100334 local args=(
335 -B"${BUILD_DIR}" -H"${MYDIR}"
336 -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
337 -G Ninja
338 -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS}"
339 -DCMAKE_C_FLAGS="${CMAKE_C_FLAGS}"
340 -DCMAKE_TOOLCHAIN_FILE="${CMAKE_TOOLCHAIN_FILE}"
341 -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}"
342 -DCMAKE_MODULE_LINKER_FLAGS="${CMAKE_MODULE_LINKER_FLAGS}"
343 -DCMAKE_SHARED_LINKER_FLAGS="${CMAKE_SHARED_LINKER_FLAGS}"
jpegxl-bot0709f3a2020-02-19 14:37:22 +0100344 -DJPEGXL_VERSION="${JPEGXL_VERSION}"
jpegxl-bot63349442020-05-25 08:56:34 +0200345 -DSANITIZER="${SANITIZER}"
jpegxl-bot9e183e12020-10-29 12:36:26 +0100346 # These are not enabled by default in cmake.
347 -DJPEGXL_ENABLE_VIEWERS=ON
348 -DJPEGXL_ENABLE_PLUGINS=ON
349 -DJPEGXL_ENABLE_DEVTOOLS=ON
jpegxl-botff093712019-12-27 18:12:34 +0100350 )
jpegxl-botab7c5e92021-04-21 19:22:38 +0200351 if [[ "${BUILD_TARGET}" != *mingw32 ]]; then
352 args+=(
353 -DJPEGXL_WARNINGS_AS_ERRORS=ON
354 )
355 fi
jpegxl-botff093712019-12-27 18:12:34 +0100356 if [[ -n "${BUILD_TARGET}" ]]; then
jpegxl-botf84edfb2020-04-20 09:48:41 +0200357 local system_name="Linux"
358 if [[ "${BUILD_TARGET}" == *mingw32 ]]; then
359 # When cross-compiling with mingw the target must be set to Windows and
360 # run programs with wine.
361 system_name="Windows"
362 args+=(
363 -DCMAKE_CROSSCOMPILING_EMULATOR="${WINE_BIN}"
364 # Normally CMake automatically defines MINGW=1 when building with the
365 # mingw compiler (x86_64-w64-mingw32-gcc) but we are normally compiling
366 # with clang.
367 -DMINGW=1
368 )
369 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200370 # EMSCRIPTEN toolchain sets the right values itself
371 if [[ "${BUILD_TARGET}" != wasm* ]]; then
372 # If set, BUILD_TARGET must be the target triplet such as
373 # x86_64-unknown-linux-gnu.
374 args+=(
375 -DCMAKE_C_COMPILER_TARGET="${BUILD_TARGET}"
376 -DCMAKE_CXX_COMPILER_TARGET="${BUILD_TARGET}"
377 # Only the first element of the target triplet.
378 -DCMAKE_SYSTEM_PROCESSOR="${BUILD_TARGET%%-*}"
379 -DCMAKE_SYSTEM_NAME="${system_name}"
380 )
jpegxl-bot849ebf62020-09-29 16:23:20 +0200381 else
382 # sjpeg confuses WASM SIMD with SSE.
383 args+=(
384 -DSJPEG_ENABLE_SIMD=OFF
385 )
jpegxl-bot63349442020-05-25 08:56:34 +0200386 fi
jpegxl-botff093712019-12-27 18:12:34 +0100387 args+=(
jpegxl-botff093712019-12-27 18:12:34 +0100388 # These are needed to make googletest work when cross-compiling.
389 -DCMAKE_CROSSCOMPILING=1
390 -DHAVE_STD_REGEX=0
391 -DHAVE_POSIX_REGEX=0
392 -DHAVE_GNU_POSIX_REGEX=0
393 -DHAVE_STEADY_CLOCK=0
394 -DHAVE_THREAD_SAFETY_ATTRIBUTES=0
395 )
jpegxl-botf84edfb2020-04-20 09:48:41 +0200396 if [[ -z "${CMAKE_FIND_ROOT_PATH}" ]]; then
397 # find_package() will look in this prefix for libraries.
398 CMAKE_FIND_ROOT_PATH="/usr/${BUILD_TARGET}"
399 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200400 if [[ -z "${CMAKE_PREFIX_PATH}" ]]; then
401 CMAKE_PREFIX_PATH="/usr/${BUILD_TARGET}"
402 fi
jpegxl-botf84edfb2020-04-20 09:48:41 +0200403 # Use pkg-config for the target. If there's no pkg-config available for the
404 # target we can set the PKG_CONFIG_PATH to the appropriate path in most
405 # linux distributions.
jpegxl-botff093712019-12-27 18:12:34 +0100406 local pkg_config=$(which "${BUILD_TARGET}-pkg-config" || true)
jpegxl-botf84edfb2020-04-20 09:48:41 +0200407 if [[ -z "${pkg_config}" ]]; then
408 pkg_config=$(which pkg-config)
409 export PKG_CONFIG_LIBDIR="/usr/${BUILD_TARGET}/lib/pkgconfig"
410 fi
jpegxl-botff093712019-12-27 18:12:34 +0100411 if [[ -n "${pkg_config}" ]]; then
412 args+=(-DPKG_CONFIG_EXECUTABLE="${pkg_config}")
413 fi
414 fi
jpegxl-botb3a65712020-02-06 13:22:22 +0100415 if [[ -n "${CMAKE_CROSSCOMPILING_EMULATOR}" ]]; then
416 args+=(
417 -DCMAKE_CROSSCOMPILING_EMULATOR="${CMAKE_CROSSCOMPILING_EMULATOR}"
418 )
419 fi
jpegxl-botf84edfb2020-04-20 09:48:41 +0200420 if [[ -n "${CMAKE_FIND_ROOT_PATH}" ]]; then
421 args+=(
422 -DCMAKE_FIND_ROOT_PATH="${CMAKE_FIND_ROOT_PATH}"
423 )
424 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200425 if [[ -n "${CMAKE_PREFIX_PATH}" ]]; then
426 args+=(
427 -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}"
428 )
429 fi
jpegxl-bot50bbf272020-06-10 14:59:11 +0200430 if [[ -n "${CMAKE_C_COMPILER_LAUNCHER}" ]]; then
431 args+=(
432 -DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_C_COMPILER_LAUNCHER}"
433 )
434 fi
435 if [[ -n "${CMAKE_CXX_COMPILER_LAUNCHER}" ]]; then
436 args+=(
437 -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CXX_COMPILER_LAUNCHER}"
438 )
439 fi
jpegxl-bote3c58a02020-06-15 08:51:22 +0200440 if [[ -n "${CMAKE_MAKE_PROGRAM}" ]]; then
441 args+=(
442 -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}"
443 )
444 fi
jpegxl-botff093712019-12-27 18:12:34 +0100445 cmake "${args[@]}" "$@"
446}
447
448cmake_build_and_test() {
449 # gtest_discover_tests() runs the test binaries to discover the list of tests
450 # at build time, which fails under qemu.
jpegxl-bot50bbf272020-06-10 14:59:11 +0200451 ASAN_OPTIONS=detect_leaks=0 cmake --build "${BUILD_DIR}" -- all doc
jpegxl-botff093712019-12-27 18:12:34 +0100452 # Pack test binaries if requested.
453 if [[ "${PACK_TEST:-}" == "1" ]]; then
454 (cd "${BUILD_DIR}"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200455 ${FIND_BIN} -name '*.cmake' -a '!' -path '*CMakeFiles*'
456 ${FIND_BIN} -type d -name tests -a '!' -path '*CMakeFiles*'
jpegxl-botff093712019-12-27 18:12:34 +0100457 ) | tar -C "${BUILD_DIR}" -cf "${BUILD_DIR}/tests.tar.xz" -T - \
458 --use-compress-program="xz --threads=$(nproc --all || echo 1) -6"
459 du -h "${BUILD_DIR}/tests.tar.xz"
460 # Pack coverage data if also available.
461 touch "${BUILD_DIR}/gcno.sentinel"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200462 (cd "${BUILD_DIR}"; echo gcno.sentinel; ${FIND_BIN} -name '*gcno') | \
jpegxl-botff093712019-12-27 18:12:34 +0100463 tar -C "${BUILD_DIR}" -cvf "${BUILD_DIR}/gcno.tar.xz" -T - \
464 --use-compress-program="xz --threads=$(nproc --all || echo 1) -6"
465 fi
466
467 if [[ "${SKIP_TEST}" -ne "1" ]]; then
468 (cd "${BUILD_DIR}"
469 export UBSAN_OPTIONS=print_stacktrace=1
jpegxl-bot56fd0222020-10-06 14:50:49 +0200470 [[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
jpegxl-botff093712019-12-27 18:12:34 +0100471 ctest -j $(nproc --all || echo 1) --output-on-failure)
472 fi
473}
474
475# Configure the build to strip unused functions. This considerably reduces the
476# output size, specially for tests which only use a small part of the whole
477# library.
478strip_dead_code() {
479 # Emscripten does tree shaking without any extra flags.
480 if [[ "${CMAKE_TOOLCHAIN_FILE##*/}" == "Emscripten.cmake" ]]; then
481 return 0
482 fi
483 # -ffunction-sections, -fdata-sections and -Wl,--gc-sections effectively
484 # discard all unreachable code, reducing the code size. For this to work, we
485 # need to also pass --no-export-dynamic to prevent it from exporting all the
486 # internal symbols (like functions) making them all reachable and thus not a
487 # candidate for removal.
488 CMAKE_CXX_FLAGS+=" -ffunction-sections -fdata-sections"
489 CMAKE_C_FLAGS+=" -ffunction-sections -fdata-sections"
490 if [[ "${OS}" == "Darwin" ]]; then
491 CMAKE_EXE_LINKER_FLAGS+=" -dead_strip"
492 CMAKE_SHARED_LINKER_FLAGS+=" -dead_strip"
493 else
494 CMAKE_EXE_LINKER_FLAGS+=" -Wl,--gc-sections -Wl,--no-export-dynamic"
495 CMAKE_SHARED_LINKER_FLAGS+=" -Wl,--gc-sections -Wl,--no-export-dynamic"
496 fi
497}
498
499### Externally visible commands
500
501cmd_debug() {
502 CMAKE_BUILD_TYPE="Debug"
503 cmake_configure "$@"
504 cmake_build_and_test
505}
506
507cmd_release() {
508 CMAKE_BUILD_TYPE="Release"
509 strip_dead_code
510 cmake_configure "$@"
511 cmake_build_and_test
512}
513
514cmd_opt() {
515 CMAKE_BUILD_TYPE="RelWithDebInfo"
516 CMAKE_CXX_FLAGS+=" -DJXL_DEBUG_WARNING -DJXL_DEBUG_ON_ERROR"
517 cmake_configure "$@"
518 cmake_build_and_test
519}
520
521cmd_coverage() {
jpegxl-botf2aeba72021-03-16 12:35:53 +0100522 # -O0 prohibits stack space reuse -> causes stack-overflow on dozens of tests.
523 TEST_STACK_LIMIT="none"
524
jpegxl-botff093712019-12-27 18:12:34 +0100525 cmd_release -DJPEGXL_ENABLE_COVERAGE=ON "$@"
526
527 if [[ "${SKIP_TEST}" -ne "1" ]]; then
528 # If we didn't run the test we also don't print a coverage report.
529 cmd_coverage_report
530 fi
531}
532
533cmd_coverage_report() {
jpegxl-bote3c58a02020-06-15 08:51:22 +0200534 LLVM_COV=$("${CC:-clang}" -print-prog-name=llvm-cov)
jpegxl-botf84edfb2020-04-20 09:48:41 +0200535 local real_build_dir=$(realpath "${BUILD_DIR}")
jpegxl-botff093712019-12-27 18:12:34 +0100536 local gcovr_args=(
537 -r "${real_build_dir}"
538 --gcov-executable "${LLVM_COV} gcov"
539 # Only print coverage information for the jxl and fuif directories. The rest
540 # is not part of the code under test.
541 --filter '.*jxl/.*'
542 --exclude '.*_test.cc'
543 --object-directory "${real_build_dir}"
544 )
545
546 (
547 cd "${real_build_dir}"
548 gcovr "${gcovr_args[@]}" --html --html-details \
549 --output="${real_build_dir}/coverage.html"
550 gcovr "${gcovr_args[@]}" --print-summary |
551 tee "${real_build_dir}/coverage.txt"
552 gcovr "${gcovr_args[@]}" --xml --output="${real_build_dir}/coverage.xml"
553 )
554}
555
556cmd_test() {
jpegxl-botf84edfb2020-04-20 09:48:41 +0200557 export_env
jpegxl-botff093712019-12-27 18:12:34 +0100558 # Unpack tests if needed.
559 if [[ -e "${BUILD_DIR}/tests.tar.xz" && ! -d "${BUILD_DIR}/tests" ]]; then
560 tar -C "${BUILD_DIR}" -Jxvf "${BUILD_DIR}/tests.tar.xz"
561 fi
562 if [[ -e "${BUILD_DIR}/gcno.tar.xz" && ! -d "${BUILD_DIR}/gcno.sentinel" ]]; then
563 tar -C "${BUILD_DIR}" -Jxvf "${BUILD_DIR}/gcno.tar.xz"
564 fi
565 (cd "${BUILD_DIR}"
566 export UBSAN_OPTIONS=print_stacktrace=1
jpegxl-bot56fd0222020-10-06 14:50:49 +0200567 [[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200568 ctest -j $(nproc --all || echo 1) --output-on-failure "$@")
jpegxl-botff093712019-12-27 18:12:34 +0100569}
570
jpegxl-bot5175d112021-02-23 16:59:45 +0100571cmd_gbench() {
572 export_env
573 (cd "${BUILD_DIR}"
574 export UBSAN_OPTIONS=print_stacktrace=1
575 lib/jxl_gbench \
576 --benchmark_counters_tabular=true \
577 --benchmark_out_format=json \
578 --benchmark_out=gbench.json "$@"
579 )
580}
581
jpegxl-botff093712019-12-27 18:12:34 +0100582cmd_asan() {
jpegxl-bot63349442020-05-25 08:56:34 +0200583 SANITIZER="asan"
jpegxl-botff093712019-12-27 18:12:34 +0100584 CMAKE_C_FLAGS+=" -DJXL_ENABLE_ASSERT=1 -g -DADDRESS_SANITIZER \
585 -fsanitize=address ${UBSAN_FLAGS[@]}"
586 CMAKE_CXX_FLAGS+=" -DJXL_ENABLE_ASSERT=1 -g -DADDRESS_SANITIZER \
587 -fsanitize=address ${UBSAN_FLAGS[@]}"
588 strip_dead_code
jpegxl-botb3a65712020-02-06 13:22:22 +0100589 cmake_configure "$@" -DJPEGXL_ENABLE_TCMALLOC=OFF
jpegxl-botff093712019-12-27 18:12:34 +0100590 cmake_build_and_test
591}
592
593cmd_tsan() {
jpegxl-bot63349442020-05-25 08:56:34 +0200594 SANITIZER="tsan"
jpegxl-botff093712019-12-27 18:12:34 +0100595 local tsan_args=(
596 -DJXL_ENABLE_ASSERT=1
597 -g
598 -DTHREAD_SANITIZER
599 ${UBSAN_FLAGS[@]}
600 -fsanitize=thread
601 )
602 CMAKE_C_FLAGS+=" ${tsan_args[@]}"
603 CMAKE_CXX_FLAGS+=" ${tsan_args[@]}"
604
605 CMAKE_BUILD_TYPE="RelWithDebInfo"
606 cmake_configure "$@" -DJPEGXL_ENABLE_TCMALLOC=OFF
607 cmake_build_and_test
608}
609
610cmd_msan() {
jpegxl-bot63349442020-05-25 08:56:34 +0200611 SANITIZER="msan"
jpegxl-botff093712019-12-27 18:12:34 +0100612 detect_clang_version
613 local msan_prefix="${HOME}/.msan/${CLANG_VERSION}"
614 if [[ ! -d "${msan_prefix}" || -e "${msan_prefix}/lib/libc++abi.a" ]]; then
615 # Install msan libraries for this version if needed or if an older version
616 # with libc++abi was installed.
617 cmd_msan_install
618 fi
619
620 local msan_c_flags=(
621 -fsanitize=memory
622 -fno-omit-frame-pointer
623 -fsanitize-memory-track-origins
624
625 -DJXL_ENABLE_ASSERT=1
626 -g
627 -DMEMORY_SANITIZER
628
629 # Force gtest to not use the cxxbai.
630 -DGTEST_HAS_CXXABI_H_=0
631 )
632 local msan_cxx_flags=(
633 "${msan_c_flags[@]}"
634
635 # Some C++ sources don't use the std at all, so the -stdlib=libc++ is unused
636 # in those cases. Ignore the warning.
637 -Wno-unused-command-line-argument
638 -stdlib=libc++
639
640 # We include the libc++ from the msan directory instead, so we don't want
641 # the std includes.
642 -nostdinc++
643 -cxx-isystem"${msan_prefix}/include/c++/v1"
644 )
645
646 local msan_linker_flags=(
647 -L"${msan_prefix}"/lib
648 -Wl,-rpath -Wl,"${msan_prefix}"/lib/
649 )
650
jpegxl-botff093712019-12-27 18:12:34 +0100651 CMAKE_C_FLAGS+=" ${msan_c_flags[@]} ${UBSAN_FLAGS[@]}"
652 CMAKE_CXX_FLAGS+=" ${msan_cxx_flags[@]} ${UBSAN_FLAGS[@]}"
653 CMAKE_EXE_LINKER_FLAGS+=" ${msan_linker_flags[@]}"
654 CMAKE_MODULE_LINKER_FLAGS+=" ${msan_linker_flags[@]}"
655 CMAKE_SHARED_LINKER_FLAGS+=" ${msan_linker_flags[@]}"
656 strip_dead_code
657 cmake_configure "$@" \
jpegxl-botb3a65712020-02-06 13:22:22 +0100658 -DCMAKE_CROSSCOMPILING=1 -DRUN_HAVE_STD_REGEX=0 -DRUN_HAVE_POSIX_REGEX=0 \
659 -DJPEGXL_ENABLE_TCMALLOC=OFF
jpegxl-botff093712019-12-27 18:12:34 +0100660 cmake_build_and_test
661}
662
663# Install libc++ libraries compiled with msan in the msan_prefix for the current
664# compiler version.
665cmd_msan_install() {
666 local tmpdir=$(mktemp -d)
667 CLEANUP_FILES+=("${tmpdir}")
668 # Detect the llvm to install:
669 export CC="${CC:-clang}"
670 export CXX="${CXX:-clang++}"
671 detect_clang_version
jpegxl-bote3c58a02020-06-15 08:51:22 +0200672 local llvm_tag="llvmorg-${CLANG_VERSION}.0.0"
jpegxl-botff093712019-12-27 18:12:34 +0100673 case "${CLANG_VERSION}" in
674 "6.0")
675 llvm_tag="llvmorg-6.0.1"
676 ;;
677 "7")
678 llvm_tag="llvmorg-7.0.1"
679 ;;
jpegxl-botff093712019-12-27 18:12:34 +0100680 esac
681 local llvm_targz="${tmpdir}/${llvm_tag}.tar.gz"
682 curl -L --show-error -o "${llvm_targz}" \
683 "https://github.com/llvm/llvm-project/archive/${llvm_tag}.tar.gz"
684 tar -C "${tmpdir}" -zxf "${llvm_targz}"
685 local llvm_root="${tmpdir}/llvm-project-${llvm_tag}"
686
687 local msan_prefix="${HOME}/.msan/${CLANG_VERSION}"
688 rm -rf "${msan_prefix}"
689
690 declare -A CMAKE_EXTRAS
691 CMAKE_EXTRAS[libcxx]="\
692 -DLIBCXX_CXX_ABI=libstdc++ \
693 -DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON"
694
695 for project in libcxx; do
696 local proj_build="${tmpdir}/build-${project}"
697 local proj_dir="${llvm_root}/${project}"
698 mkdir -p "${proj_build}"
699 cmake -B"${proj_build}" -H"${proj_dir}" \
700 -G Ninja \
701 -DCMAKE_BUILD_TYPE=Release \
702 -DLLVM_USE_SANITIZER=Memory \
703 -DLLVM_PATH="${llvm_root}/llvm" \
704 -DLLVM_CONFIG_PATH="$(which llvm-config llvm-config-7 llvm-config-6.0 | \
705 head -n1)" \
706 -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS}" \
707 -DCMAKE_C_FLAGS="${CMAKE_C_FLAGS}" \
708 -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}" \
709 -DCMAKE_SHARED_LINKER_FLAGS="${CMAKE_SHARED_LINKER_FLAGS}" \
710 -DCMAKE_INSTALL_PREFIX="${msan_prefix}" \
711 ${CMAKE_EXTRAS[${project}]}
712 cmake --build "${proj_build}"
713 ninja -C "${proj_build}" install
714 done
715}
716
717cmd_fast_benchmark() {
718 local small_corpus_tar="${BENCHMARK_CORPORA}/jyrki-full.tar"
719 mkdir -p "${BENCHMARK_CORPORA}"
720 curl --show-error -o "${small_corpus_tar}" -z "${small_corpus_tar}" \
721 "https://storage.googleapis.com/artifacts.jpegxl.appspot.com/corpora/jyrki-full.tar"
722
723 local tmpdir=$(mktemp -d)
724 CLEANUP_FILES+=("${tmpdir}")
725 tar -xf "${small_corpus_tar}" -C "${tmpdir}"
726
727 run_benchmark "${tmpdir}" 1048576
728}
729
730cmd_benchmark() {
731 local nikon_corpus_tar="${BENCHMARK_CORPORA}/nikon-subset.tar"
732 mkdir -p "${BENCHMARK_CORPORA}"
733 curl --show-error -o "${nikon_corpus_tar}" -z "${nikon_corpus_tar}" \
734 "https://storage.googleapis.com/artifacts.jpegxl.appspot.com/corpora/nikon-subset.tar"
735
736 local tmpdir=$(mktemp -d)
737 CLEANUP_FILES+=("${tmpdir}")
738 tar -xvf "${nikon_corpus_tar}" -C "${tmpdir}"
739
740 local sem_id="jpegxl_benchmark-$$"
741 local nprocs=$(nproc --all || echo 1)
742 images=()
743 local filename
744 while IFS= read -r filename; do
745 # This removes the './'
746 filename="${filename:2}"
747 local mode
748 if [[ "${filename:0:4}" == "srgb" ]]; then
749 mode="RGB_D65_SRG_Rel_SRG"
750 elif [[ "${filename:0:5}" == "adobe" ]]; then
751 mode="RGB_D65_Ado_Rel_Ado"
752 else
753 echo "Unknown image colorspace: ${filename}" >&2
754 exit 1
755 fi
756 png_filename="${filename%.ppm}.png"
757 png_filename=$(echo "${png_filename}" | tr '/' '_')
758 sem --bg --id "${sem_id}" -j"${nprocs}" -- \
759 "${BUILD_DIR}/tools/decode_and_encode" \
760 "${tmpdir}/${filename}" "${mode}" "${tmpdir}/${png_filename}"
761 images+=( "${png_filename}" )
jpegxl-botf84edfb2020-04-20 09:48:41 +0200762 done < <(cd "${tmpdir}"; ${FIND_BIN} . -name '*.ppm' -type f)
jpegxl-botff093712019-12-27 18:12:34 +0100763 sem --id "${sem_id}" --wait
764
765 # We need about 10 GiB per thread on these images.
766 run_benchmark "${tmpdir}" 10485760
767}
768
769get_mem_available() {
770 if [[ "${OS}" == "Darwin" ]]; then
771 echo $(vm_stat | grep -F 'Pages free:' | awk '{print $3 * 4}')
772 else
773 echo $(grep -F MemAvailable: /proc/meminfo | awk '{print $2}')
774 fi
775}
776
777run_benchmark() {
778 local src_img_dir="$1"
779 local mem_per_thread="${2:-10485760}"
780
781 local output_dir="${BUILD_DIR}/benchmark_results"
782 mkdir -p "${output_dir}"
783
784 # The memory available at the beginning of the benchmark run in kB. The number
785 # of threads depends on the available memory, and the passed memory per
786 # thread. We also add a 2 GiB of constant memory.
787 local mem_available="$(get_mem_available)"
788 # Check that we actually have a MemAvailable value.
789 [[ -n "${mem_available}" ]]
790 local num_threads=$(( (${mem_available} - 1048576) / ${mem_per_thread} ))
791 if [[ ${num_threads} -le 0 ]]; then
792 num_threads=1
793 fi
794
795 local benchmark_args=(
796 --input "${src_img_dir}/*.png"
jpegxl-bot131953a2020-11-10 15:30:00 +0100797 --codec=jpeg:yuv420:q85,webp:q80,jxl:fast:d1,jxl:fast:d1:downsampling=8,jxl:fast:d4,jxl:fast:d4:downsampling=8,jxl:m:cheetah:nl,jxl:cheetah:m,jxl:m:cheetah:P6,jxl:m:falcon:q80
jpegxl-botff093712019-12-27 18:12:34 +0100798 --output_dir "${output_dir}"
799 --noprofiler --show_progress
800 --num_threads="${num_threads}"
801 )
802 if [[ "${STORE_IMAGES}" == "1" ]]; then
803 benchmark_args+=(--save_decompressed --save_compressed)
804 fi
jpegxl-bot849ebf62020-09-29 16:23:20 +0200805 (
jpegxl-bot56fd0222020-10-06 14:50:49 +0200806 [[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
jpegxl-bot849ebf62020-09-29 16:23:20 +0200807 "${BUILD_DIR}/tools/benchmark_xl" "${benchmark_args[@]}" | \
808 tee "${output_dir}/results.txt"
809
810 # Check error code for benckmark_xl command. This will exit if not.
811 return ${PIPESTATUS[0]}
812 )
jpegxl-botff093712019-12-27 18:12:34 +0100813
814 if [[ -n "${CI_BUILD_NAME:-}" ]]; then
815 { set +x; } 2>/dev/null
816 local message="Results for ${CI_BUILD_NAME} @ ${CI_COMMIT_SHORT_SHA} (job ${CI_JOB_URL:-}):
817
818$(cat "${output_dir}/results.txt")
819"
820 cmd_post_mr_comment "${message}"
821 set -x
822 fi
823}
824
825# Helper function to wait for the CPU temperature to cool down on ARM.
826wait_for_temp() {
827 { set +x; } 2>/dev/null
828 local temp_limit=${1:-37000}
829 if [[ -z "${THERMAL_FILE:-}" ]]; then
830 echo "Must define the THERMAL_FILE with the thermal_zoneX/temp file" \
831 "to read the temperature from. This is normally set in the runner." >&2
832 exit 1
833 fi
834 local org_temp=$(cat "${THERMAL_FILE}")
835 if [[ "${org_temp}" -ge "${temp_limit}" ]]; then
836 echo -n "Waiting for temp to get down from ${org_temp}... "
837 fi
838 local temp="${org_temp}"
839 while [[ "${temp}" -ge "${temp_limit}" ]]; do
840 sleep 1
841 temp=$(cat "${THERMAL_FILE}")
842 done
843 if [[ "${org_temp}" -ge "${temp_limit}" ]]; then
844 echo "Done, temp=${temp}"
845 fi
846 set -x
847}
848
849# Helper function to set the cpuset restriction of the current process.
850cmd_cpuset() {
jpegxl-bot21f5f752020-06-30 13:06:56 +0200851 [[ "${SKIP_CPUSET:-}" != "1" ]] || return 0
jpegxl-botff093712019-12-27 18:12:34 +0100852 local newset="$1"
853 local mycpuset=$(cat /proc/self/cpuset)
854 mycpuset="/dev/cpuset${mycpuset}"
855 # Check that the directory exists:
856 [[ -d "${mycpuset}" ]]
jpegxl-botb3a65712020-02-06 13:22:22 +0100857 if [[ -e "${mycpuset}/cpuset.cpus" ]]; then
858 echo "${newset}" >"${mycpuset}/cpuset.cpus"
859 else
860 echo "${newset}" >"${mycpuset}/cpus"
861 fi
862}
863
864# Return the encoding/decoding speed from the Stats output.
865_speed_from_output() {
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200866 local speed="$1"
867 local unit="${2:-MP/s}"
868 if [[ "${speed}" == *"${unit}"* ]]; then
869 speed="${speed%% ${unit}*}"
870 speed="${speed##* }"
871 echo "${speed}"
872 fi
jpegxl-botff093712019-12-27 18:12:34 +0100873}
874
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200875
jpegxl-botff093712019-12-27 18:12:34 +0100876# Run benchmarks on ARM for the big and little CPUs.
877cmd_arm_benchmark() {
jpegxl-bot9e183e12020-10-29 12:36:26 +0100878 # Flags used for cjxl encoder with .png inputs
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200879 local jxl_png_benchmarks=(
jpegxl-botff093712019-12-27 18:12:34 +0100880 # Lossy options:
jpegxl-bot9e183e12020-10-29 12:36:26 +0100881 "--epf=0 --distance=1.0 --speed=cheetah"
882 "--epf=2 --distance=1.0 --speed=cheetah"
883 "--epf=0 --distance=8.0 --speed=cheetah"
884 "--epf=1 --distance=8.0 --speed=cheetah"
885 "--epf=2 --distance=8.0 --speed=cheetah"
886 "--epf=3 --distance=8.0 --speed=cheetah"
jpegxl-bot131953a2020-11-10 15:30:00 +0100887 "--modular -Q 90"
888 "--modular -Q 50"
jpegxl-botff093712019-12-27 18:12:34 +0100889 # Lossless options:
jpegxl-bot131953a2020-11-10 15:30:00 +0100890 "--modular"
891 "--modular -E 0 -I 0"
892 "--modular -P 5"
893 "--modular --responsive=1"
jpegxl-botff093712019-12-27 18:12:34 +0100894 # Near-lossless options:
jpegxl-bot9e183e12020-10-29 12:36:26 +0100895 "--epf=0 --distance=0.3 --speed=fast"
jpegxl-bot131953a2020-11-10 15:30:00 +0100896 "--modular -N 3 -I 0"
897 "--modular -Q 97"
jpegxl-botff093712019-12-27 18:12:34 +0100898 )
899
jpegxl-bot9e183e12020-10-29 12:36:26 +0100900 # Flags used for cjxl encoder with .jpg inputs. These should do lossless
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200901 # JPEG recompression (of pixels or full jpeg).
902 local jxl_jpeg_benchmarks=(
903 "--num_reps=3"
904 )
905
jpegxl-botff093712019-12-27 18:12:34 +0100906 local images=(
907 "third_party/testdata/imagecompression.info/flower_foveon.png"
908 )
909
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200910 local jpg_images=(
911 "third_party/testdata/imagecompression.info/flower_foveon.png.im_q85_420.jpg"
912 )
913
jpegxl-bot21f5f752020-06-30 13:06:56 +0200914 if [[ "${SKIP_CPUSET:-}" == "1" ]]; then
915 # Use a single cpu config in this case.
916 local cpu_confs=("?")
917 else
918 # Otherwise the CPU config comes from the environment:
919 local cpu_confs=(
920 "${RUNNER_CPU_LITTLE}"
921 "${RUNNER_CPU_BIG}"
922 # The CPU description is something like 3-7, so these configurations only
923 # take the first CPU of the group.
924 "${RUNNER_CPU_LITTLE%%-*}"
925 "${RUNNER_CPU_BIG%%-*}"
926 )
927 # Check that RUNNER_CPU_ALL is defined. In the SKIP_CPUSET=1 case this will
928 # be ignored but still evaluated when calling cmd_cpuset.
929 [[ -n "${RUNNER_CPU_ALL}" ]]
930 fi
jpegxl-botb3a65712020-02-06 13:22:22 +0100931
932 local jpg_dirname="third_party/corpora/jpeg"
933 mkdir -p "${jpg_dirname}"
jpegxl-botb3a65712020-02-06 13:22:22 +0100934 local jpg_qualities=( 50 80 95 )
935 for src_img in "${images[@]}"; do
936 for q in "${jpg_qualities[@]}"; do
937 local jpeg_name="${jpg_dirname}/"$(basename "${src_img}" .png)"-q${q}.jpg"
jpegxl-bot849ebf62020-09-29 16:23:20 +0200938 convert -sampling-factor 1x1 -quality "${q}" \
jpegxl-botb3a65712020-02-06 13:22:22 +0100939 "${src_img}" "${jpeg_name}"
940 jpg_images+=("${jpeg_name}")
941 done
942 done
943
jpegxl-botff093712019-12-27 18:12:34 +0100944 local output_dir="${BUILD_DIR}/benchmark_results"
945 mkdir -p "${output_dir}"
946 local runs_file="${output_dir}/runs.txt"
947
948 if [[ ! -e "${runs_file}" ]]; then
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200949 echo -e "binary\tflags\tsrc_img\tsrc size\tsrc pixels\tcpuset\tenc size (B)\tenc speed (MP/s)\tdec speed (MP/s)\tJPG dec speed (MP/s)\tJPG dec speed (MB/s)" |
jpegxl-botff093712019-12-27 18:12:34 +0100950 tee -a "${runs_file}"
951 fi
952
jpegxl-botb3a65712020-02-06 13:22:22 +0100953 mkdir -p "${BUILD_DIR}/arm_benchmark"
jpegxl-botff093712019-12-27 18:12:34 +0100954 local flags
955 local src_img
jpegxl-botb3a65712020-02-06 13:22:22 +0100956 for src_img in "${jpg_images[@]}" "${images[@]}"; do
jpegxl-botff093712019-12-27 18:12:34 +0100957 local src_img_hash=$(sha1sum "${src_img}" | cut -f 1 -d ' ')
jpegxl-bot9e183e12020-10-29 12:36:26 +0100958 local enc_binaries=("${BUILD_DIR}/tools/cjxl")
jpegxl-botb3a65712020-02-06 13:22:22 +0100959 local src_ext="${src_img##*.}"
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200960 for enc_binary in "${enc_binaries[@]}"; do
961 local enc_binary_base=$(basename "${enc_binary}")
jpegxl-botff093712019-12-27 18:12:34 +0100962
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200963 # Select the list of flags to use for the current encoder/image pair.
964 local img_benchmarks
jpegxl-botc8ce59f2020-10-12 16:06:35 +0200965 if [[ "${src_ext}" == "jpg" ]]; then
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200966 img_benchmarks=("${jxl_jpeg_benchmarks[@]}")
967 else
968 img_benchmarks=("${jxl_png_benchmarks[@]}")
969 fi
jpegxl-botb3a65712020-02-06 13:22:22 +0100970
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200971 for flags in "${img_benchmarks[@]}"; do
972 # Encoding step.
973 local enc_file_hash="${enc_binary_base} || $flags || ${src_img} || ${src_img_hash}"
974 enc_file_hash=$(echo "${enc_file_hash}" | sha1sum | cut -f 1 -d ' ')
975 local enc_file="${BUILD_DIR}/arm_benchmark/${enc_file_hash}.jxl"
976
977 for cpu_conf in "${cpu_confs[@]}"; do
978 cmd_cpuset "${cpu_conf}"
979 # nproc returns the number of active CPUs, which is given by the cpuset
980 # mask.
981 local num_threads="$(nproc)"
982
983 echo "Encoding with: ${enc_binary_base} img=${src_img} cpus=${cpu_conf} enc_flags=${flags}"
984 local enc_output
jpegxl-bot131953a2020-11-10 15:30:00 +0100985 if [[ "${flags}" == *"modular"* ]]; then
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200986 # We don't benchmark encoding speed in this case.
987 if [[ ! -f "${enc_file}" ]]; then
988 cmd_cpuset "${RUNNER_CPU_ALL:-}"
989 "${enc_binary}" ${flags} "${src_img}" "${enc_file}.tmp"
990 mv "${enc_file}.tmp" "${enc_file}"
991 cmd_cpuset "${cpu_conf}"
992 fi
993 enc_output=" ?? MP/s"
994 else
995 wait_for_temp
996 enc_output=$("${enc_binary}" ${flags} "${src_img}" "${enc_file}.tmp" \
997 2>&1 | tee /dev/stderr | grep -F "MP/s [")
jpegxl-botb3a65712020-02-06 13:22:22 +0100998 mv "${enc_file}.tmp" "${enc_file}"
jpegxl-botb3a65712020-02-06 13:22:22 +0100999 fi
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001000 local enc_speed=$(_speed_from_output "${enc_output}")
1001 local enc_size=$(stat -c "%s" "${enc_file}")
1002
1003 echo "Decoding with: img=${src_img} cpus=${cpu_conf} enc_flags=${flags}"
1004
1005 local dec_output
jpegxl-botb3a65712020-02-06 13:22:22 +01001006 wait_for_temp
jpegxl-bot9e183e12020-10-29 12:36:26 +01001007 dec_output=$("${BUILD_DIR}/tools/djxl" "${enc_file}" \
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001008 --num_reps=5 --num_threads="${num_threads}" 2>&1 | tee /dev/stderr |
1009 grep -E "M[BP]/s \[")
1010 local img_size=$(echo "${dec_output}" | cut -f 1 -d ',')
1011 local img_size_x=$(echo "${img_size}" | cut -f 1 -d ' ')
1012 local img_size_y=$(echo "${img_size}" | cut -f 3 -d ' ')
1013 local img_size_px=$(( ${img_size_x} * ${img_size_y} ))
1014 local dec_speed=$(_speed_from_output "${dec_output}")
jpegxl-botb3a65712020-02-06 13:22:22 +01001015
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001016 # For JPEG lossless recompression modes (where the original is a JPEG)
1017 # decode to JPG as well.
1018 local jpeg_dec_mps_speed=""
1019 local jpeg_dec_mbs_speed=""
1020 if [[ "${src_ext}" == "jpg" ]]; then
1021 wait_for_temp
1022 local dec_file="${BUILD_DIR}/arm_benchmark/${enc_file_hash}.jpg"
jpegxl-botb1c6fdc2021-03-05 18:32:15 +01001023 dec_output=$("${BUILD_DIR}/tools/djxl" "${enc_file}" \
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001024 "${dec_file}" --num_reps=5 --num_threads="${num_threads}" 2>&1 | \
1025 tee /dev/stderr | grep -E "M[BP]/s \[")
1026 local jpeg_dec_mps_speed=$(_speed_from_output "${dec_output}")
1027 local jpeg_dec_mbs_speed=$(_speed_from_output "${dec_output}" MB/s)
1028 if ! cmp --quiet "${src_img}" "${dec_file}"; then
1029 # Add a start at the end to signal that the files are different.
1030 jpeg_dec_mbs_speed+="*"
1031 fi
1032 fi
jpegxl-botff093712019-12-27 18:12:34 +01001033
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001034 # Record entry in a tab-separated file.
1035 local src_img_base=$(basename "${src_img}")
1036 echo -e "${enc_binary_base}\t${flags}\t${src_img_base}\t${img_size}\t${img_size_px}\t${cpu_conf}\t${enc_size}\t${enc_speed}\t${dec_speed}\t${jpeg_dec_mps_speed}\t${jpeg_dec_mbs_speed}" |
1037 tee -a "${runs_file}"
1038 done
jpegxl-botff093712019-12-27 18:12:34 +01001039 done
1040 done
1041 done
jpegxl-bot21f5f752020-06-30 13:06:56 +02001042 cmd_cpuset "${RUNNER_CPU_ALL:-}"
jpegxl-botff093712019-12-27 18:12:34 +01001043 cat "${runs_file}"
1044
1045 if [[ -n "${CI_BUILD_NAME:-}" ]]; then
1046 load_mr_vars_from_commit
1047 { set +x; } 2>/dev/null
1048 local message="Results for ${CI_BUILD_NAME} @ ${CI_COMMIT_SHORT_SHA} (job ${CI_JOB_URL:-}):
1049
1050\`\`\`
1051$(column -t -s " " "${runs_file}")
1052\`\`\`
1053"
1054 cmd_post_mr_comment "${message}"
1055 set -x
1056 fi
1057}
1058
jpegxl-botf84edfb2020-04-20 09:48:41 +02001059# Generate a corpus and run the fuzzer on that corpus.
1060cmd_fuzz() {
1061 local corpus_dir=$(realpath "${BUILD_DIR}/fuzzer_corpus")
1062 local fuzzer_crash_dir=$(realpath "${BUILD_DIR}/fuzzer_crash")
1063 mkdir -p "${corpus_dir}" "${fuzzer_crash_dir}"
1064 # Generate step.
1065 "${BUILD_DIR}/tools/fuzzer_corpus" "${corpus_dir}"
1066 # Run step:
1067 local nprocs=$(nproc --all || echo 1)
1068 (
1069 cd "${BUILD_DIR}"
1070 "tools/djxl_fuzzer" "${fuzzer_crash_dir}" "${corpus_dir}" \
1071 -max_total_time="${FUZZER_MAX_TIME}" -jobs=${nprocs} \
1072 -artifact_prefix="${fuzzer_crash_dir}/"
1073 )
1074}
1075
jpegxl-botff093712019-12-27 18:12:34 +01001076# Runs the linter (clang-format) on the pending CLs.
1077cmd_lint() {
1078 merge_request_commits
jpegxl-bot31c71b02020-12-24 17:42:41 +01001079 { set +x; } 2>/dev/null
jpegxl-botff093712019-12-27 18:12:34 +01001080 local versions=(${1:-6.0 7 8 9})
1081 local clang_format_bins=("${versions[@]/#/clang-format-}" clang-format)
1082 local tmpdir=$(mktemp -d)
1083 CLEANUP_FILES+=("${tmpdir}")
1084
jpegxl-bot31c71b02020-12-24 17:42:41 +01001085 local ret=0
1086 local build_patch="${tmpdir}/build_cleaner.patch"
1087 if ! "${MYDIR}/tools/build_cleaner.py" >"${build_patch}"; then
1088 ret=1
1089 echo "build_cleaner.py findings:" >&2
1090 "${COLORDIFF_BIN}" <"${build_patch}"
1091 echo "Run \`tools/build_cleaner.py --update\` to apply them" >&2
1092 fi
1093
jpegxl-botff093712019-12-27 18:12:34 +01001094 local installed=()
1095 local clang_patch
1096 local clang_format
1097 for clang_format in "${clang_format_bins[@]}"; do
1098 if ! which "${clang_format}" >/dev/null; then
1099 continue
1100 fi
1101 installed+=("${clang_format}")
1102 local tmppatch="${tmpdir}/${clang_format}.patch"
1103 # We include in this linter all the changes including the uncommited changes
1104 # to avoid printing changes already applied.
1105 set -x
1106 git -C "${MYDIR}" "${clang_format}" --binary "${clang_format}" \
1107 --style=file --diff "${MR_ANCESTOR_SHA}" -- >"${tmppatch}"
1108 { set +x; } 2>/dev/null
1109
1110 if grep -E '^--- ' "${tmppatch}">/dev/null; then
1111 if [[ -n "${LINT_OUTPUT:-}" ]]; then
1112 cp "${tmppatch}" "${LINT_OUTPUT}"
1113 fi
1114 clang_patch="${tmppatch}"
1115 else
1116 echo "clang-format check OK" >&2
jpegxl-bot31c71b02020-12-24 17:42:41 +01001117 return ${ret}
jpegxl-botff093712019-12-27 18:12:34 +01001118 fi
1119 done
1120
1121 if [[ ${#installed[@]} -eq 0 ]]; then
1122 echo "You must install clang-format for \"git clang-format\"" >&2
1123 exit 1
1124 fi
1125
1126 # clang-format is installed but found problems.
1127 echo "clang-format findings:" >&2
1128 "${COLORDIFF_BIN}" < "${clang_patch}"
1129
1130 echo "clang-format found issues in your patches from ${MR_ANCESTOR_SHA}" \
1131 "to the current patch. Run \`./ci.sh lint | patch -p1\` from the base" \
1132 "directory to apply them." >&2
1133 exit 1
1134}
1135
1136# Runs clang-tidy on the pending CLs. If the "all" argument is passed it runs
1137# clang-tidy over all the source files instead.
1138cmd_tidy() {
1139 local what="${1:-}"
1140
1141 if [[ -z "${CLANG_TIDY_BIN}" ]]; then
jpegxl-bot63349442020-05-25 08:56:34 +02001142 echo "ERROR: You must install clang-tidy-7 or newer to use ci.sh tidy" >&2
jpegxl-botff093712019-12-27 18:12:34 +01001143 exit 1
1144 fi
1145
1146 local git_args=()
1147 if [[ "${what}" == "all" ]]; then
1148 git_args=(ls-files)
1149 shift
1150 else
1151 merge_request_commits
1152 git_args=(
1153 diff-tree --no-commit-id --name-only -r "${MR_ANCESTOR_SHA}"
1154 "${MR_HEAD_SHA}"
1155 )
1156 fi
1157
1158 # Clang-tidy needs the compilation database generated by cmake.
1159 if [[ ! -e "${BUILD_DIR}/compile_commands.json" ]]; then
1160 # Generate the build options in debug mode, since we need the debug asserts
1161 # enabled for the clang-tidy analyzer to use them.
1162 CMAKE_BUILD_TYPE="Debug"
1163 cmake_configure
jpegxl-bot63349442020-05-25 08:56:34 +02001164 # Build the autogen targets to generate the .h files from the .ui files.
1165 local autogen_targets=(
1166 $(ninja -C "${BUILD_DIR}" -t targets | grep -F _autogen: |
1167 cut -f 1 -d :)
1168 )
1169 if [[ ${#autogen_targets[@]} != 0 ]]; then
1170 ninja -C "${BUILD_DIR}" "${autogen_targets[@]}"
1171 fi
jpegxl-botff093712019-12-27 18:12:34 +01001172 fi
1173
1174 cd "${MYDIR}"
1175 local nprocs=$(nproc --all || echo 1)
1176 local ret=0
1177 if ! parallel -j"${nprocs}" --keep-order -- \
1178 "${CLANG_TIDY_BIN}" -p "${BUILD_DIR}" -format-style=file -quiet "$@" {} \
1179 < <(git "${git_args[@]}" | grep -E '(\.cc|\.cpp)$') \
1180 >"${BUILD_DIR}/clang-tidy.txt"; then
1181 ret=1
1182 fi
1183 { set +x; } 2>/dev/null
1184 echo "Findings statistics:" >&2
1185 grep -E ' \[[A-Za-z\.,\-]+\]' -o "${BUILD_DIR}/clang-tidy.txt" | sort \
1186 | uniq -c >&2
1187
1188 if [[ $ret -ne 0 ]]; then
1189 cat >&2 <<EOF
1190Errors found, see ${BUILD_DIR}/clang-tidy.txt for details.
1191To automatically fix them, run:
1192
1193 SKIP_TEST=1 ./ci.sh debug
1194 ${CLANG_TIDY_BIN} -p ${BUILD_DIR} -fix -format-style=file -quiet $@ \$(git ${git_args[@]} | grep -E '(\.cc|\.cpp)\$')
1195EOF
1196 fi
1197
1198 return ${ret}
1199}
1200
jpegxl-bot9e183e12020-10-29 12:36:26 +01001201# Print stats about all the packages built in ${BUILD_DIR}/debs/.
1202cmd_debian_stats() {
1203 { set +x; } 2>/dev/null
1204 local debsdir="${BUILD_DIR}/debs"
1205 local f
1206 while IFS='' read -r -d '' f; do
1207 echo "====================================================================="
1208 echo "Package $f:"
1209 dpkg --info $f
1210 dpkg --contents $f
1211 done < <(find "${BUILD_DIR}/debs" -maxdepth 1 -mindepth 1 -type f \
1212 -name '*.deb' -print0)
1213}
1214
1215build_debian_pkg() {
1216 local srcdir="$1"
1217 local srcpkg="$2"
1218
1219 local debsdir="${BUILD_DIR}/debs"
1220 local builddir="${debsdir}/${srcpkg}"
1221
1222 # debuild doesn't have an easy way to build out of tree, so we make a copy
1223 # of with all symlinks on the first level.
1224 mkdir -p "${builddir}"
1225 for f in $(find "${srcdir}" -mindepth 1 -maxdepth 1 -printf '%P\n'); do
1226 if [[ ! -L "${builddir}/$f" ]]; then
1227 rm -f "${builddir}/$f"
1228 ln -s "${srcdir}/$f" "${builddir}/$f"
1229 fi
1230 done
1231 (
1232 cd "${builddir}"
1233 debuild -b -uc -us
1234 )
1235}
1236
1237cmd_debian_build() {
1238 local srcpkg="${1:-}"
1239
1240 case "${srcpkg}" in
1241 jpeg-xl)
1242 build_debian_pkg "${MYDIR}" "jpeg-xl"
1243 ;;
1244 highway)
1245 build_debian_pkg "${MYDIR}/third_party/highway" "highway"
1246 ;;
1247 *)
1248 echo "ERROR: Must pass a valid source package name to build." >&2
1249 ;;
1250 esac
1251}
1252
jpegxl-botff093712019-12-27 18:12:34 +01001253main() {
1254 local cmd="${1:-}"
1255 if [[ -z "${cmd}" ]]; then
1256 cat >&2 <<EOF
1257Use: $0 CMD
1258
1259Where cmd is one of:
1260 opt Build and test a Release with symbols build.
1261 debug Build and test a Debug build (NDEBUG is not defined).
1262 release Build and test a striped Release binary without debug information.
1263 asan Build and test an ASan (AddressSanitizer) build.
1264 msan Build and test an MSan (MemorySanitizer) build. Needs to have msan
1265 c++ libs installed with msan_install first.
1266 tsan Build and test a TSan (ThreadSanitizer) build.
1267 test Run the tests build by opt, debug, release, asan or msan. Useful when
1268 building with SKIP_TEST=1.
jpegxl-bot5175d112021-02-23 16:59:45 +01001269 gbench Run the Google benchmark tests.
jpegxl-botf84edfb2020-04-20 09:48:41 +02001270 fuzz Generate the fuzzer corpus and run the fuzzer on it. Useful after
1271 building with asan or msan.
jpegxl-botff093712019-12-27 18:12:34 +01001272 benchmark Run the benchmark over the default corpus.
1273 fast_benchmark Run the benchmark over the small corpus.
1274
1275 coverage Buils and run tests with coverage support. Runs coverage_report as
1276 well.
1277 coverage_report Generate HTML, XML and text coverage report after a coverage
1278 run.
1279
1280 lint Run the linter checks on the current commit or merge request.
1281 tidy Run clang-tidy on the current commit or merge request.
1282
1283 msan_install Install the libc++ libraries required to build in msan mode. This
1284 needs to be done once.
1285
jpegxl-bot9e183e12020-10-29 12:36:26 +01001286 debian_build <srcpkg> Build the given source package.
1287 debian_stats Print stats about the built packages.
1288
jpegxl-botff093712019-12-27 18:12:34 +01001289You can pass some optional environment variables as well:
1290 - BUILD_DIR: The output build directory (by default "$$repo/build")
1291 - BUILD_TARGET: The target triplet used when cross-compiling.
1292 - CMAKE_FLAGS: Convenience flag to pass both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS.
1293 - CMAKE_PREFIX_PATH: Installation prefixes to be searched by the find_package.
jpegxl-botf84edfb2020-04-20 09:48:41 +02001294 - ENABLE_WASM_SIMD=1: enable experimental SIMD in WASM build (only).
1295 - FUZZER_MAX_TIME: "fuzz" command fuzzer running timeout in seconds.
jpegxl-botff093712019-12-27 18:12:34 +01001296 - LINT_OUTPUT: Path to the output patch from the "lint" command.
jpegxl-bot21f5f752020-06-30 13:06:56 +02001297 - SKIP_CPUSET=1: Skip modifying the cpuset in the arm_benchmark.
jpegxl-botff093712019-12-27 18:12:34 +01001298 - SKIP_TEST=1: Skip the test stage.
1299 - STORE_IMAGES=0: Makes the benchmark discard the computed images.
jpegxl-bot849ebf62020-09-29 16:23:20 +02001300 - TEST_STACK_LIMIT: Stack size limit (ulimit -s) during tests, in KiB.
1301 - STACK_SIZE=1: Generate binaries with the .stack_sizes sections.
jpegxl-botff093712019-12-27 18:12:34 +01001302
1303These optional environment variables are forwarded to the cmake call as
1304parameters:
jpegxl-botf84edfb2020-04-20 09:48:41 +02001305 - CMAKE_BUILD_TYPE
jpegxl-botff093712019-12-27 18:12:34 +01001306 - CMAKE_C_FLAGS
1307 - CMAKE_CXX_FLAGS
jpegxl-bot50bbf272020-06-10 14:59:11 +02001308 - CMAKE_C_COMPILER_LAUNCHER
1309 - CMAKE_CXX_COMPILER_LAUNCHER
jpegxl-botb3a65712020-02-06 13:22:22 +01001310 - CMAKE_CROSSCOMPILING_EMULATOR
jpegxl-botf84edfb2020-04-20 09:48:41 +02001311 - CMAKE_FIND_ROOT_PATH
jpegxl-botff093712019-12-27 18:12:34 +01001312 - CMAKE_EXE_LINKER_FLAGS
jpegxl-bote3c58a02020-06-15 08:51:22 +02001313 - CMAKE_MAKE_PROGRAM
jpegxl-botff093712019-12-27 18:12:34 +01001314 - CMAKE_MODULE_LINKER_FLAGS
1315 - CMAKE_SHARED_LINKER_FLAGS
1316 - CMAKE_TOOLCHAIN_FILE
jpegxl-botff093712019-12-27 18:12:34 +01001317
1318Example:
1319 BUILD_DIR=/tmp/build $0 opt
1320EOF
1321 exit 1
1322 fi
1323
1324 cmd="cmd_${cmd}"
1325 shift
1326 set -x
1327 "${cmd}" "$@"
1328}
1329
1330main "$@"