blob: b1d6f3551d69c5b2f81b053945d1f4bbcf9918da [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:
308 export WINEPATH="${WINEPATH};${real_build_dir};/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 )
351 if [[ -n "${BUILD_TARGET}" ]]; then
jpegxl-botf84edfb2020-04-20 09:48:41 +0200352 local system_name="Linux"
353 if [[ "${BUILD_TARGET}" == *mingw32 ]]; then
354 # When cross-compiling with mingw the target must be set to Windows and
355 # run programs with wine.
356 system_name="Windows"
357 args+=(
358 -DCMAKE_CROSSCOMPILING_EMULATOR="${WINE_BIN}"
359 # Normally CMake automatically defines MINGW=1 when building with the
360 # mingw compiler (x86_64-w64-mingw32-gcc) but we are normally compiling
361 # with clang.
362 -DMINGW=1
363 )
364 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200365 # EMSCRIPTEN toolchain sets the right values itself
366 if [[ "${BUILD_TARGET}" != wasm* ]]; then
367 # If set, BUILD_TARGET must be the target triplet such as
368 # x86_64-unknown-linux-gnu.
369 args+=(
370 -DCMAKE_C_COMPILER_TARGET="${BUILD_TARGET}"
371 -DCMAKE_CXX_COMPILER_TARGET="${BUILD_TARGET}"
372 # Only the first element of the target triplet.
373 -DCMAKE_SYSTEM_PROCESSOR="${BUILD_TARGET%%-*}"
374 -DCMAKE_SYSTEM_NAME="${system_name}"
375 )
jpegxl-bot849ebf62020-09-29 16:23:20 +0200376 else
377 # sjpeg confuses WASM SIMD with SSE.
378 args+=(
379 -DSJPEG_ENABLE_SIMD=OFF
380 )
jpegxl-bot63349442020-05-25 08:56:34 +0200381 fi
jpegxl-botff093712019-12-27 18:12:34 +0100382 args+=(
jpegxl-botff093712019-12-27 18:12:34 +0100383 # These are needed to make googletest work when cross-compiling.
384 -DCMAKE_CROSSCOMPILING=1
385 -DHAVE_STD_REGEX=0
386 -DHAVE_POSIX_REGEX=0
387 -DHAVE_GNU_POSIX_REGEX=0
388 -DHAVE_STEADY_CLOCK=0
389 -DHAVE_THREAD_SAFETY_ATTRIBUTES=0
390 )
jpegxl-botf84edfb2020-04-20 09:48:41 +0200391 if [[ -z "${CMAKE_FIND_ROOT_PATH}" ]]; then
392 # find_package() will look in this prefix for libraries.
393 CMAKE_FIND_ROOT_PATH="/usr/${BUILD_TARGET}"
394 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200395 if [[ -z "${CMAKE_PREFIX_PATH}" ]]; then
396 CMAKE_PREFIX_PATH="/usr/${BUILD_TARGET}"
397 fi
jpegxl-botf84edfb2020-04-20 09:48:41 +0200398 # Use pkg-config for the target. If there's no pkg-config available for the
399 # target we can set the PKG_CONFIG_PATH to the appropriate path in most
400 # linux distributions.
jpegxl-botff093712019-12-27 18:12:34 +0100401 local pkg_config=$(which "${BUILD_TARGET}-pkg-config" || true)
jpegxl-botf84edfb2020-04-20 09:48:41 +0200402 if [[ -z "${pkg_config}" ]]; then
403 pkg_config=$(which pkg-config)
404 export PKG_CONFIG_LIBDIR="/usr/${BUILD_TARGET}/lib/pkgconfig"
405 fi
jpegxl-botff093712019-12-27 18:12:34 +0100406 if [[ -n "${pkg_config}" ]]; then
407 args+=(-DPKG_CONFIG_EXECUTABLE="${pkg_config}")
408 fi
409 fi
jpegxl-botb3a65712020-02-06 13:22:22 +0100410 if [[ -n "${CMAKE_CROSSCOMPILING_EMULATOR}" ]]; then
411 args+=(
412 -DCMAKE_CROSSCOMPILING_EMULATOR="${CMAKE_CROSSCOMPILING_EMULATOR}"
413 )
414 fi
jpegxl-botf84edfb2020-04-20 09:48:41 +0200415 if [[ -n "${CMAKE_FIND_ROOT_PATH}" ]]; then
416 args+=(
417 -DCMAKE_FIND_ROOT_PATH="${CMAKE_FIND_ROOT_PATH}"
418 )
419 fi
jpegxl-bot63349442020-05-25 08:56:34 +0200420 if [[ -n "${CMAKE_PREFIX_PATH}" ]]; then
421 args+=(
422 -DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}"
423 )
424 fi
jpegxl-bot50bbf272020-06-10 14:59:11 +0200425 if [[ -n "${CMAKE_C_COMPILER_LAUNCHER}" ]]; then
426 args+=(
427 -DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_C_COMPILER_LAUNCHER}"
428 )
429 fi
430 if [[ -n "${CMAKE_CXX_COMPILER_LAUNCHER}" ]]; then
431 args+=(
432 -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CXX_COMPILER_LAUNCHER}"
433 )
434 fi
jpegxl-bote3c58a02020-06-15 08:51:22 +0200435 if [[ -n "${CMAKE_MAKE_PROGRAM}" ]]; then
436 args+=(
437 -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}"
438 )
439 fi
jpegxl-botff093712019-12-27 18:12:34 +0100440 cmake "${args[@]}" "$@"
441}
442
443cmake_build_and_test() {
444 # gtest_discover_tests() runs the test binaries to discover the list of tests
445 # at build time, which fails under qemu.
jpegxl-bot50bbf272020-06-10 14:59:11 +0200446 ASAN_OPTIONS=detect_leaks=0 cmake --build "${BUILD_DIR}" -- all doc
jpegxl-botff093712019-12-27 18:12:34 +0100447 # Pack test binaries if requested.
448 if [[ "${PACK_TEST:-}" == "1" ]]; then
449 (cd "${BUILD_DIR}"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200450 ${FIND_BIN} -name '*.cmake' -a '!' -path '*CMakeFiles*'
451 ${FIND_BIN} -type d -name tests -a '!' -path '*CMakeFiles*'
jpegxl-botff093712019-12-27 18:12:34 +0100452 ) | tar -C "${BUILD_DIR}" -cf "${BUILD_DIR}/tests.tar.xz" -T - \
453 --use-compress-program="xz --threads=$(nproc --all || echo 1) -6"
454 du -h "${BUILD_DIR}/tests.tar.xz"
455 # Pack coverage data if also available.
456 touch "${BUILD_DIR}/gcno.sentinel"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200457 (cd "${BUILD_DIR}"; echo gcno.sentinel; ${FIND_BIN} -name '*gcno') | \
jpegxl-botff093712019-12-27 18:12:34 +0100458 tar -C "${BUILD_DIR}" -cvf "${BUILD_DIR}/gcno.tar.xz" -T - \
459 --use-compress-program="xz --threads=$(nproc --all || echo 1) -6"
460 fi
461
462 if [[ "${SKIP_TEST}" -ne "1" ]]; then
463 (cd "${BUILD_DIR}"
464 export UBSAN_OPTIONS=print_stacktrace=1
jpegxl-bot56fd0222020-10-06 14:50:49 +0200465 [[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
jpegxl-botff093712019-12-27 18:12:34 +0100466 ctest -j $(nproc --all || echo 1) --output-on-failure)
467 fi
468}
469
470# Configure the build to strip unused functions. This considerably reduces the
471# output size, specially for tests which only use a small part of the whole
472# library.
473strip_dead_code() {
474 # Emscripten does tree shaking without any extra flags.
475 if [[ "${CMAKE_TOOLCHAIN_FILE##*/}" == "Emscripten.cmake" ]]; then
476 return 0
477 fi
478 # -ffunction-sections, -fdata-sections and -Wl,--gc-sections effectively
479 # discard all unreachable code, reducing the code size. For this to work, we
480 # need to also pass --no-export-dynamic to prevent it from exporting all the
481 # internal symbols (like functions) making them all reachable and thus not a
482 # candidate for removal.
483 CMAKE_CXX_FLAGS+=" -ffunction-sections -fdata-sections"
484 CMAKE_C_FLAGS+=" -ffunction-sections -fdata-sections"
485 if [[ "${OS}" == "Darwin" ]]; then
486 CMAKE_EXE_LINKER_FLAGS+=" -dead_strip"
487 CMAKE_SHARED_LINKER_FLAGS+=" -dead_strip"
488 else
489 CMAKE_EXE_LINKER_FLAGS+=" -Wl,--gc-sections -Wl,--no-export-dynamic"
490 CMAKE_SHARED_LINKER_FLAGS+=" -Wl,--gc-sections -Wl,--no-export-dynamic"
491 fi
492}
493
494### Externally visible commands
495
496cmd_debug() {
497 CMAKE_BUILD_TYPE="Debug"
498 cmake_configure "$@"
499 cmake_build_and_test
500}
501
502cmd_release() {
503 CMAKE_BUILD_TYPE="Release"
504 strip_dead_code
505 cmake_configure "$@"
506 cmake_build_and_test
507}
508
509cmd_opt() {
510 CMAKE_BUILD_TYPE="RelWithDebInfo"
511 CMAKE_CXX_FLAGS+=" -DJXL_DEBUG_WARNING -DJXL_DEBUG_ON_ERROR"
512 cmake_configure "$@"
513 cmake_build_and_test
514}
515
516cmd_coverage() {
jpegxl-botf2aeba72021-03-16 12:35:53 +0100517 # -O0 prohibits stack space reuse -> causes stack-overflow on dozens of tests.
518 TEST_STACK_LIMIT="none"
519
jpegxl-botff093712019-12-27 18:12:34 +0100520 cmd_release -DJPEGXL_ENABLE_COVERAGE=ON "$@"
521
522 if [[ "${SKIP_TEST}" -ne "1" ]]; then
523 # If we didn't run the test we also don't print a coverage report.
524 cmd_coverage_report
525 fi
526}
527
528cmd_coverage_report() {
jpegxl-bote3c58a02020-06-15 08:51:22 +0200529 LLVM_COV=$("${CC:-clang}" -print-prog-name=llvm-cov)
jpegxl-botf84edfb2020-04-20 09:48:41 +0200530 local real_build_dir=$(realpath "${BUILD_DIR}")
jpegxl-botff093712019-12-27 18:12:34 +0100531 local gcovr_args=(
532 -r "${real_build_dir}"
533 --gcov-executable "${LLVM_COV} gcov"
534 # Only print coverage information for the jxl and fuif directories. The rest
535 # is not part of the code under test.
536 --filter '.*jxl/.*'
537 --exclude '.*_test.cc'
538 --object-directory "${real_build_dir}"
539 )
540
541 (
542 cd "${real_build_dir}"
543 gcovr "${gcovr_args[@]}" --html --html-details \
544 --output="${real_build_dir}/coverage.html"
545 gcovr "${gcovr_args[@]}" --print-summary |
546 tee "${real_build_dir}/coverage.txt"
547 gcovr "${gcovr_args[@]}" --xml --output="${real_build_dir}/coverage.xml"
548 )
549}
550
551cmd_test() {
jpegxl-botf84edfb2020-04-20 09:48:41 +0200552 export_env
jpegxl-botff093712019-12-27 18:12:34 +0100553 # Unpack tests if needed.
554 if [[ -e "${BUILD_DIR}/tests.tar.xz" && ! -d "${BUILD_DIR}/tests" ]]; then
555 tar -C "${BUILD_DIR}" -Jxvf "${BUILD_DIR}/tests.tar.xz"
556 fi
557 if [[ -e "${BUILD_DIR}/gcno.tar.xz" && ! -d "${BUILD_DIR}/gcno.sentinel" ]]; then
558 tar -C "${BUILD_DIR}" -Jxvf "${BUILD_DIR}/gcno.tar.xz"
559 fi
560 (cd "${BUILD_DIR}"
561 export UBSAN_OPTIONS=print_stacktrace=1
jpegxl-bot56fd0222020-10-06 14:50:49 +0200562 [[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
jpegxl-botf84edfb2020-04-20 09:48:41 +0200563 ctest -j $(nproc --all || echo 1) --output-on-failure "$@")
jpegxl-botff093712019-12-27 18:12:34 +0100564}
565
jpegxl-bot5175d112021-02-23 16:59:45 +0100566cmd_gbench() {
567 export_env
568 (cd "${BUILD_DIR}"
569 export UBSAN_OPTIONS=print_stacktrace=1
570 lib/jxl_gbench \
571 --benchmark_counters_tabular=true \
572 --benchmark_out_format=json \
573 --benchmark_out=gbench.json "$@"
574 )
575}
576
jpegxl-botff093712019-12-27 18:12:34 +0100577cmd_asan() {
jpegxl-bot63349442020-05-25 08:56:34 +0200578 SANITIZER="asan"
jpegxl-botff093712019-12-27 18:12:34 +0100579 CMAKE_C_FLAGS+=" -DJXL_ENABLE_ASSERT=1 -g -DADDRESS_SANITIZER \
580 -fsanitize=address ${UBSAN_FLAGS[@]}"
581 CMAKE_CXX_FLAGS+=" -DJXL_ENABLE_ASSERT=1 -g -DADDRESS_SANITIZER \
582 -fsanitize=address ${UBSAN_FLAGS[@]}"
583 strip_dead_code
jpegxl-botb3a65712020-02-06 13:22:22 +0100584 cmake_configure "$@" -DJPEGXL_ENABLE_TCMALLOC=OFF
jpegxl-botff093712019-12-27 18:12:34 +0100585 cmake_build_and_test
586}
587
588cmd_tsan() {
jpegxl-bot63349442020-05-25 08:56:34 +0200589 SANITIZER="tsan"
jpegxl-botff093712019-12-27 18:12:34 +0100590 local tsan_args=(
591 -DJXL_ENABLE_ASSERT=1
592 -g
593 -DTHREAD_SANITIZER
594 ${UBSAN_FLAGS[@]}
595 -fsanitize=thread
596 )
597 CMAKE_C_FLAGS+=" ${tsan_args[@]}"
598 CMAKE_CXX_FLAGS+=" ${tsan_args[@]}"
599
600 CMAKE_BUILD_TYPE="RelWithDebInfo"
601 cmake_configure "$@" -DJPEGXL_ENABLE_TCMALLOC=OFF
602 cmake_build_and_test
603}
604
605cmd_msan() {
jpegxl-bot63349442020-05-25 08:56:34 +0200606 SANITIZER="msan"
jpegxl-botff093712019-12-27 18:12:34 +0100607 detect_clang_version
608 local msan_prefix="${HOME}/.msan/${CLANG_VERSION}"
609 if [[ ! -d "${msan_prefix}" || -e "${msan_prefix}/lib/libc++abi.a" ]]; then
610 # Install msan libraries for this version if needed or if an older version
611 # with libc++abi was installed.
612 cmd_msan_install
613 fi
614
615 local msan_c_flags=(
616 -fsanitize=memory
617 -fno-omit-frame-pointer
618 -fsanitize-memory-track-origins
619
620 -DJXL_ENABLE_ASSERT=1
621 -g
622 -DMEMORY_SANITIZER
623
624 # Force gtest to not use the cxxbai.
625 -DGTEST_HAS_CXXABI_H_=0
626 )
627 local msan_cxx_flags=(
628 "${msan_c_flags[@]}"
629
630 # Some C++ sources don't use the std at all, so the -stdlib=libc++ is unused
631 # in those cases. Ignore the warning.
632 -Wno-unused-command-line-argument
633 -stdlib=libc++
634
635 # We include the libc++ from the msan directory instead, so we don't want
636 # the std includes.
637 -nostdinc++
638 -cxx-isystem"${msan_prefix}/include/c++/v1"
639 )
640
641 local msan_linker_flags=(
642 -L"${msan_prefix}"/lib
643 -Wl,-rpath -Wl,"${msan_prefix}"/lib/
644 )
645
jpegxl-botff093712019-12-27 18:12:34 +0100646 CMAKE_C_FLAGS+=" ${msan_c_flags[@]} ${UBSAN_FLAGS[@]}"
647 CMAKE_CXX_FLAGS+=" ${msan_cxx_flags[@]} ${UBSAN_FLAGS[@]}"
648 CMAKE_EXE_LINKER_FLAGS+=" ${msan_linker_flags[@]}"
649 CMAKE_MODULE_LINKER_FLAGS+=" ${msan_linker_flags[@]}"
650 CMAKE_SHARED_LINKER_FLAGS+=" ${msan_linker_flags[@]}"
651 strip_dead_code
652 cmake_configure "$@" \
jpegxl-botb3a65712020-02-06 13:22:22 +0100653 -DCMAKE_CROSSCOMPILING=1 -DRUN_HAVE_STD_REGEX=0 -DRUN_HAVE_POSIX_REGEX=0 \
654 -DJPEGXL_ENABLE_TCMALLOC=OFF
jpegxl-botff093712019-12-27 18:12:34 +0100655 cmake_build_and_test
656}
657
658# Install libc++ libraries compiled with msan in the msan_prefix for the current
659# compiler version.
660cmd_msan_install() {
661 local tmpdir=$(mktemp -d)
662 CLEANUP_FILES+=("${tmpdir}")
663 # Detect the llvm to install:
664 export CC="${CC:-clang}"
665 export CXX="${CXX:-clang++}"
666 detect_clang_version
jpegxl-bote3c58a02020-06-15 08:51:22 +0200667 local llvm_tag="llvmorg-${CLANG_VERSION}.0.0"
jpegxl-botff093712019-12-27 18:12:34 +0100668 case "${CLANG_VERSION}" in
669 "6.0")
670 llvm_tag="llvmorg-6.0.1"
671 ;;
672 "7")
673 llvm_tag="llvmorg-7.0.1"
674 ;;
jpegxl-botff093712019-12-27 18:12:34 +0100675 esac
676 local llvm_targz="${tmpdir}/${llvm_tag}.tar.gz"
677 curl -L --show-error -o "${llvm_targz}" \
678 "https://github.com/llvm/llvm-project/archive/${llvm_tag}.tar.gz"
679 tar -C "${tmpdir}" -zxf "${llvm_targz}"
680 local llvm_root="${tmpdir}/llvm-project-${llvm_tag}"
681
682 local msan_prefix="${HOME}/.msan/${CLANG_VERSION}"
683 rm -rf "${msan_prefix}"
684
685 declare -A CMAKE_EXTRAS
686 CMAKE_EXTRAS[libcxx]="\
687 -DLIBCXX_CXX_ABI=libstdc++ \
688 -DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON"
689
690 for project in libcxx; do
691 local proj_build="${tmpdir}/build-${project}"
692 local proj_dir="${llvm_root}/${project}"
693 mkdir -p "${proj_build}"
694 cmake -B"${proj_build}" -H"${proj_dir}" \
695 -G Ninja \
696 -DCMAKE_BUILD_TYPE=Release \
697 -DLLVM_USE_SANITIZER=Memory \
698 -DLLVM_PATH="${llvm_root}/llvm" \
699 -DLLVM_CONFIG_PATH="$(which llvm-config llvm-config-7 llvm-config-6.0 | \
700 head -n1)" \
701 -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS}" \
702 -DCMAKE_C_FLAGS="${CMAKE_C_FLAGS}" \
703 -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}" \
704 -DCMAKE_SHARED_LINKER_FLAGS="${CMAKE_SHARED_LINKER_FLAGS}" \
705 -DCMAKE_INSTALL_PREFIX="${msan_prefix}" \
706 ${CMAKE_EXTRAS[${project}]}
707 cmake --build "${proj_build}"
708 ninja -C "${proj_build}" install
709 done
710}
711
712cmd_fast_benchmark() {
713 local small_corpus_tar="${BENCHMARK_CORPORA}/jyrki-full.tar"
714 mkdir -p "${BENCHMARK_CORPORA}"
715 curl --show-error -o "${small_corpus_tar}" -z "${small_corpus_tar}" \
716 "https://storage.googleapis.com/artifacts.jpegxl.appspot.com/corpora/jyrki-full.tar"
717
718 local tmpdir=$(mktemp -d)
719 CLEANUP_FILES+=("${tmpdir}")
720 tar -xf "${small_corpus_tar}" -C "${tmpdir}"
721
722 run_benchmark "${tmpdir}" 1048576
723}
724
725cmd_benchmark() {
726 local nikon_corpus_tar="${BENCHMARK_CORPORA}/nikon-subset.tar"
727 mkdir -p "${BENCHMARK_CORPORA}"
728 curl --show-error -o "${nikon_corpus_tar}" -z "${nikon_corpus_tar}" \
729 "https://storage.googleapis.com/artifacts.jpegxl.appspot.com/corpora/nikon-subset.tar"
730
731 local tmpdir=$(mktemp -d)
732 CLEANUP_FILES+=("${tmpdir}")
733 tar -xvf "${nikon_corpus_tar}" -C "${tmpdir}"
734
735 local sem_id="jpegxl_benchmark-$$"
736 local nprocs=$(nproc --all || echo 1)
737 images=()
738 local filename
739 while IFS= read -r filename; do
740 # This removes the './'
741 filename="${filename:2}"
742 local mode
743 if [[ "${filename:0:4}" == "srgb" ]]; then
744 mode="RGB_D65_SRG_Rel_SRG"
745 elif [[ "${filename:0:5}" == "adobe" ]]; then
746 mode="RGB_D65_Ado_Rel_Ado"
747 else
748 echo "Unknown image colorspace: ${filename}" >&2
749 exit 1
750 fi
751 png_filename="${filename%.ppm}.png"
752 png_filename=$(echo "${png_filename}" | tr '/' '_')
753 sem --bg --id "${sem_id}" -j"${nprocs}" -- \
754 "${BUILD_DIR}/tools/decode_and_encode" \
755 "${tmpdir}/${filename}" "${mode}" "${tmpdir}/${png_filename}"
756 images+=( "${png_filename}" )
jpegxl-botf84edfb2020-04-20 09:48:41 +0200757 done < <(cd "${tmpdir}"; ${FIND_BIN} . -name '*.ppm' -type f)
jpegxl-botff093712019-12-27 18:12:34 +0100758 sem --id "${sem_id}" --wait
759
760 # We need about 10 GiB per thread on these images.
761 run_benchmark "${tmpdir}" 10485760
762}
763
764get_mem_available() {
765 if [[ "${OS}" == "Darwin" ]]; then
766 echo $(vm_stat | grep -F 'Pages free:' | awk '{print $3 * 4}')
767 else
768 echo $(grep -F MemAvailable: /proc/meminfo | awk '{print $2}')
769 fi
770}
771
772run_benchmark() {
773 local src_img_dir="$1"
774 local mem_per_thread="${2:-10485760}"
775
776 local output_dir="${BUILD_DIR}/benchmark_results"
777 mkdir -p "${output_dir}"
778
779 # The memory available at the beginning of the benchmark run in kB. The number
780 # of threads depends on the available memory, and the passed memory per
781 # thread. We also add a 2 GiB of constant memory.
782 local mem_available="$(get_mem_available)"
783 # Check that we actually have a MemAvailable value.
784 [[ -n "${mem_available}" ]]
785 local num_threads=$(( (${mem_available} - 1048576) / ${mem_per_thread} ))
786 if [[ ${num_threads} -le 0 ]]; then
787 num_threads=1
788 fi
789
790 local benchmark_args=(
791 --input "${src_img_dir}/*.png"
jpegxl-bot131953a2020-11-10 15:30:00 +0100792 --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 +0100793 --output_dir "${output_dir}"
794 --noprofiler --show_progress
795 --num_threads="${num_threads}"
796 )
797 if [[ "${STORE_IMAGES}" == "1" ]]; then
798 benchmark_args+=(--save_decompressed --save_compressed)
799 fi
jpegxl-bot849ebf62020-09-29 16:23:20 +0200800 (
jpegxl-bot56fd0222020-10-06 14:50:49 +0200801 [[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
jpegxl-bot849ebf62020-09-29 16:23:20 +0200802 "${BUILD_DIR}/tools/benchmark_xl" "${benchmark_args[@]}" | \
803 tee "${output_dir}/results.txt"
804
805 # Check error code for benckmark_xl command. This will exit if not.
806 return ${PIPESTATUS[0]}
807 )
jpegxl-botff093712019-12-27 18:12:34 +0100808
809 if [[ -n "${CI_BUILD_NAME:-}" ]]; then
810 { set +x; } 2>/dev/null
811 local message="Results for ${CI_BUILD_NAME} @ ${CI_COMMIT_SHORT_SHA} (job ${CI_JOB_URL:-}):
812
813$(cat "${output_dir}/results.txt")
814"
815 cmd_post_mr_comment "${message}"
816 set -x
817 fi
818}
819
820# Helper function to wait for the CPU temperature to cool down on ARM.
821wait_for_temp() {
822 { set +x; } 2>/dev/null
823 local temp_limit=${1:-37000}
824 if [[ -z "${THERMAL_FILE:-}" ]]; then
825 echo "Must define the THERMAL_FILE with the thermal_zoneX/temp file" \
826 "to read the temperature from. This is normally set in the runner." >&2
827 exit 1
828 fi
829 local org_temp=$(cat "${THERMAL_FILE}")
830 if [[ "${org_temp}" -ge "${temp_limit}" ]]; then
831 echo -n "Waiting for temp to get down from ${org_temp}... "
832 fi
833 local temp="${org_temp}"
834 while [[ "${temp}" -ge "${temp_limit}" ]]; do
835 sleep 1
836 temp=$(cat "${THERMAL_FILE}")
837 done
838 if [[ "${org_temp}" -ge "${temp_limit}" ]]; then
839 echo "Done, temp=${temp}"
840 fi
841 set -x
842}
843
844# Helper function to set the cpuset restriction of the current process.
845cmd_cpuset() {
jpegxl-bot21f5f752020-06-30 13:06:56 +0200846 [[ "${SKIP_CPUSET:-}" != "1" ]] || return 0
jpegxl-botff093712019-12-27 18:12:34 +0100847 local newset="$1"
848 local mycpuset=$(cat /proc/self/cpuset)
849 mycpuset="/dev/cpuset${mycpuset}"
850 # Check that the directory exists:
851 [[ -d "${mycpuset}" ]]
jpegxl-botb3a65712020-02-06 13:22:22 +0100852 if [[ -e "${mycpuset}/cpuset.cpus" ]]; then
853 echo "${newset}" >"${mycpuset}/cpuset.cpus"
854 else
855 echo "${newset}" >"${mycpuset}/cpus"
856 fi
857}
858
859# Return the encoding/decoding speed from the Stats output.
860_speed_from_output() {
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200861 local speed="$1"
862 local unit="${2:-MP/s}"
863 if [[ "${speed}" == *"${unit}"* ]]; then
864 speed="${speed%% ${unit}*}"
865 speed="${speed##* }"
866 echo "${speed}"
867 fi
jpegxl-botff093712019-12-27 18:12:34 +0100868}
869
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200870
jpegxl-botff093712019-12-27 18:12:34 +0100871# Run benchmarks on ARM for the big and little CPUs.
872cmd_arm_benchmark() {
jpegxl-bot9e183e12020-10-29 12:36:26 +0100873 # Flags used for cjxl encoder with .png inputs
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200874 local jxl_png_benchmarks=(
jpegxl-botff093712019-12-27 18:12:34 +0100875 # Lossy options:
jpegxl-bot9e183e12020-10-29 12:36:26 +0100876 "--epf=0 --distance=1.0 --speed=cheetah"
877 "--epf=2 --distance=1.0 --speed=cheetah"
878 "--epf=0 --distance=8.0 --speed=cheetah"
879 "--epf=1 --distance=8.0 --speed=cheetah"
880 "--epf=2 --distance=8.0 --speed=cheetah"
881 "--epf=3 --distance=8.0 --speed=cheetah"
jpegxl-bot131953a2020-11-10 15:30:00 +0100882 "--modular -Q 90"
883 "--modular -Q 50"
jpegxl-botff093712019-12-27 18:12:34 +0100884 # Lossless options:
jpegxl-bot131953a2020-11-10 15:30:00 +0100885 "--modular"
886 "--modular -E 0 -I 0"
887 "--modular -P 5"
888 "--modular --responsive=1"
jpegxl-botff093712019-12-27 18:12:34 +0100889 # Near-lossless options:
jpegxl-bot9e183e12020-10-29 12:36:26 +0100890 "--epf=0 --distance=0.3 --speed=fast"
jpegxl-bot131953a2020-11-10 15:30:00 +0100891 "--modular -N 3 -I 0"
892 "--modular -Q 97"
jpegxl-botff093712019-12-27 18:12:34 +0100893 )
894
jpegxl-bot9e183e12020-10-29 12:36:26 +0100895 # Flags used for cjxl encoder with .jpg inputs. These should do lossless
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200896 # JPEG recompression (of pixels or full jpeg).
897 local jxl_jpeg_benchmarks=(
898 "--num_reps=3"
899 )
900
jpegxl-botff093712019-12-27 18:12:34 +0100901 local images=(
902 "third_party/testdata/imagecompression.info/flower_foveon.png"
903 )
904
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200905 local jpg_images=(
906 "third_party/testdata/imagecompression.info/flower_foveon.png.im_q85_420.jpg"
907 )
908
jpegxl-bot21f5f752020-06-30 13:06:56 +0200909 if [[ "${SKIP_CPUSET:-}" == "1" ]]; then
910 # Use a single cpu config in this case.
911 local cpu_confs=("?")
912 else
913 # Otherwise the CPU config comes from the environment:
914 local cpu_confs=(
915 "${RUNNER_CPU_LITTLE}"
916 "${RUNNER_CPU_BIG}"
917 # The CPU description is something like 3-7, so these configurations only
918 # take the first CPU of the group.
919 "${RUNNER_CPU_LITTLE%%-*}"
920 "${RUNNER_CPU_BIG%%-*}"
921 )
922 # Check that RUNNER_CPU_ALL is defined. In the SKIP_CPUSET=1 case this will
923 # be ignored but still evaluated when calling cmd_cpuset.
924 [[ -n "${RUNNER_CPU_ALL}" ]]
925 fi
jpegxl-botb3a65712020-02-06 13:22:22 +0100926
927 local jpg_dirname="third_party/corpora/jpeg"
928 mkdir -p "${jpg_dirname}"
jpegxl-botb3a65712020-02-06 13:22:22 +0100929 local jpg_qualities=( 50 80 95 )
930 for src_img in "${images[@]}"; do
931 for q in "${jpg_qualities[@]}"; do
932 local jpeg_name="${jpg_dirname}/"$(basename "${src_img}" .png)"-q${q}.jpg"
jpegxl-bot849ebf62020-09-29 16:23:20 +0200933 convert -sampling-factor 1x1 -quality "${q}" \
jpegxl-botb3a65712020-02-06 13:22:22 +0100934 "${src_img}" "${jpeg_name}"
935 jpg_images+=("${jpeg_name}")
936 done
937 done
938
jpegxl-botff093712019-12-27 18:12:34 +0100939 local output_dir="${BUILD_DIR}/benchmark_results"
940 mkdir -p "${output_dir}"
941 local runs_file="${output_dir}/runs.txt"
942
943 if [[ ! -e "${runs_file}" ]]; then
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200944 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 +0100945 tee -a "${runs_file}"
946 fi
947
jpegxl-botb3a65712020-02-06 13:22:22 +0100948 mkdir -p "${BUILD_DIR}/arm_benchmark"
jpegxl-botff093712019-12-27 18:12:34 +0100949 local flags
950 local src_img
jpegxl-botb3a65712020-02-06 13:22:22 +0100951 for src_img in "${jpg_images[@]}" "${images[@]}"; do
jpegxl-botff093712019-12-27 18:12:34 +0100952 local src_img_hash=$(sha1sum "${src_img}" | cut -f 1 -d ' ')
jpegxl-bot9e183e12020-10-29 12:36:26 +0100953 local enc_binaries=("${BUILD_DIR}/tools/cjxl")
jpegxl-botb3a65712020-02-06 13:22:22 +0100954 local src_ext="${src_img##*.}"
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200955 for enc_binary in "${enc_binaries[@]}"; do
956 local enc_binary_base=$(basename "${enc_binary}")
jpegxl-botff093712019-12-27 18:12:34 +0100957
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200958 # Select the list of flags to use for the current encoder/image pair.
959 local img_benchmarks
jpegxl-botc8ce59f2020-10-12 16:06:35 +0200960 if [[ "${src_ext}" == "jpg" ]]; then
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200961 img_benchmarks=("${jxl_jpeg_benchmarks[@]}")
962 else
963 img_benchmarks=("${jxl_png_benchmarks[@]}")
964 fi
jpegxl-botb3a65712020-02-06 13:22:22 +0100965
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200966 for flags in "${img_benchmarks[@]}"; do
967 # Encoding step.
968 local enc_file_hash="${enc_binary_base} || $flags || ${src_img} || ${src_img_hash}"
969 enc_file_hash=$(echo "${enc_file_hash}" | sha1sum | cut -f 1 -d ' ')
970 local enc_file="${BUILD_DIR}/arm_benchmark/${enc_file_hash}.jxl"
971
972 for cpu_conf in "${cpu_confs[@]}"; do
973 cmd_cpuset "${cpu_conf}"
974 # nproc returns the number of active CPUs, which is given by the cpuset
975 # mask.
976 local num_threads="$(nproc)"
977
978 echo "Encoding with: ${enc_binary_base} img=${src_img} cpus=${cpu_conf} enc_flags=${flags}"
979 local enc_output
jpegxl-bot131953a2020-11-10 15:30:00 +0100980 if [[ "${flags}" == *"modular"* ]]; then
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200981 # We don't benchmark encoding speed in this case.
982 if [[ ! -f "${enc_file}" ]]; then
983 cmd_cpuset "${RUNNER_CPU_ALL:-}"
984 "${enc_binary}" ${flags} "${src_img}" "${enc_file}.tmp"
985 mv "${enc_file}.tmp" "${enc_file}"
986 cmd_cpuset "${cpu_conf}"
987 fi
988 enc_output=" ?? MP/s"
989 else
990 wait_for_temp
991 enc_output=$("${enc_binary}" ${flags} "${src_img}" "${enc_file}.tmp" \
992 2>&1 | tee /dev/stderr | grep -F "MP/s [")
jpegxl-botb3a65712020-02-06 13:22:22 +0100993 mv "${enc_file}.tmp" "${enc_file}"
jpegxl-botb3a65712020-02-06 13:22:22 +0100994 fi
jpegxl-bot6b5144c2020-08-24 13:35:47 +0200995 local enc_speed=$(_speed_from_output "${enc_output}")
996 local enc_size=$(stat -c "%s" "${enc_file}")
997
998 echo "Decoding with: img=${src_img} cpus=${cpu_conf} enc_flags=${flags}"
999
1000 local dec_output
jpegxl-botb3a65712020-02-06 13:22:22 +01001001 wait_for_temp
jpegxl-bot9e183e12020-10-29 12:36:26 +01001002 dec_output=$("${BUILD_DIR}/tools/djxl" "${enc_file}" \
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001003 --num_reps=5 --num_threads="${num_threads}" 2>&1 | tee /dev/stderr |
1004 grep -E "M[BP]/s \[")
1005 local img_size=$(echo "${dec_output}" | cut -f 1 -d ',')
1006 local img_size_x=$(echo "${img_size}" | cut -f 1 -d ' ')
1007 local img_size_y=$(echo "${img_size}" | cut -f 3 -d ' ')
1008 local img_size_px=$(( ${img_size_x} * ${img_size_y} ))
1009 local dec_speed=$(_speed_from_output "${dec_output}")
jpegxl-botb3a65712020-02-06 13:22:22 +01001010
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001011 # For JPEG lossless recompression modes (where the original is a JPEG)
1012 # decode to JPG as well.
1013 local jpeg_dec_mps_speed=""
1014 local jpeg_dec_mbs_speed=""
1015 if [[ "${src_ext}" == "jpg" ]]; then
1016 wait_for_temp
1017 local dec_file="${BUILD_DIR}/arm_benchmark/${enc_file_hash}.jpg"
jpegxl-botb1c6fdc2021-03-05 18:32:15 +01001018 dec_output=$("${BUILD_DIR}/tools/djxl" "${enc_file}" \
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001019 "${dec_file}" --num_reps=5 --num_threads="${num_threads}" 2>&1 | \
1020 tee /dev/stderr | grep -E "M[BP]/s \[")
1021 local jpeg_dec_mps_speed=$(_speed_from_output "${dec_output}")
1022 local jpeg_dec_mbs_speed=$(_speed_from_output "${dec_output}" MB/s)
1023 if ! cmp --quiet "${src_img}" "${dec_file}"; then
1024 # Add a start at the end to signal that the files are different.
1025 jpeg_dec_mbs_speed+="*"
1026 fi
1027 fi
jpegxl-botff093712019-12-27 18:12:34 +01001028
jpegxl-bot6b5144c2020-08-24 13:35:47 +02001029 # Record entry in a tab-separated file.
1030 local src_img_base=$(basename "${src_img}")
1031 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}" |
1032 tee -a "${runs_file}"
1033 done
jpegxl-botff093712019-12-27 18:12:34 +01001034 done
1035 done
1036 done
jpegxl-bot21f5f752020-06-30 13:06:56 +02001037 cmd_cpuset "${RUNNER_CPU_ALL:-}"
jpegxl-botff093712019-12-27 18:12:34 +01001038 cat "${runs_file}"
1039
1040 if [[ -n "${CI_BUILD_NAME:-}" ]]; then
1041 load_mr_vars_from_commit
1042 { set +x; } 2>/dev/null
1043 local message="Results for ${CI_BUILD_NAME} @ ${CI_COMMIT_SHORT_SHA} (job ${CI_JOB_URL:-}):
1044
1045\`\`\`
1046$(column -t -s " " "${runs_file}")
1047\`\`\`
1048"
1049 cmd_post_mr_comment "${message}"
1050 set -x
1051 fi
1052}
1053
jpegxl-botf84edfb2020-04-20 09:48:41 +02001054# Generate a corpus and run the fuzzer on that corpus.
1055cmd_fuzz() {
1056 local corpus_dir=$(realpath "${BUILD_DIR}/fuzzer_corpus")
1057 local fuzzer_crash_dir=$(realpath "${BUILD_DIR}/fuzzer_crash")
1058 mkdir -p "${corpus_dir}" "${fuzzer_crash_dir}"
1059 # Generate step.
1060 "${BUILD_DIR}/tools/fuzzer_corpus" "${corpus_dir}"
1061 # Run step:
1062 local nprocs=$(nproc --all || echo 1)
1063 (
1064 cd "${BUILD_DIR}"
1065 "tools/djxl_fuzzer" "${fuzzer_crash_dir}" "${corpus_dir}" \
1066 -max_total_time="${FUZZER_MAX_TIME}" -jobs=${nprocs} \
1067 -artifact_prefix="${fuzzer_crash_dir}/"
1068 )
1069}
1070
jpegxl-botff093712019-12-27 18:12:34 +01001071# Runs the linter (clang-format) on the pending CLs.
1072cmd_lint() {
1073 merge_request_commits
jpegxl-bot31c71b02020-12-24 17:42:41 +01001074 { set +x; } 2>/dev/null
jpegxl-botff093712019-12-27 18:12:34 +01001075 local versions=(${1:-6.0 7 8 9})
1076 local clang_format_bins=("${versions[@]/#/clang-format-}" clang-format)
1077 local tmpdir=$(mktemp -d)
1078 CLEANUP_FILES+=("${tmpdir}")
1079
jpegxl-bot31c71b02020-12-24 17:42:41 +01001080 local ret=0
1081 local build_patch="${tmpdir}/build_cleaner.patch"
1082 if ! "${MYDIR}/tools/build_cleaner.py" >"${build_patch}"; then
1083 ret=1
1084 echo "build_cleaner.py findings:" >&2
1085 "${COLORDIFF_BIN}" <"${build_patch}"
1086 echo "Run \`tools/build_cleaner.py --update\` to apply them" >&2
1087 fi
1088
jpegxl-botff093712019-12-27 18:12:34 +01001089 local installed=()
1090 local clang_patch
1091 local clang_format
1092 for clang_format in "${clang_format_bins[@]}"; do
1093 if ! which "${clang_format}" >/dev/null; then
1094 continue
1095 fi
1096 installed+=("${clang_format}")
1097 local tmppatch="${tmpdir}/${clang_format}.patch"
1098 # We include in this linter all the changes including the uncommited changes
1099 # to avoid printing changes already applied.
1100 set -x
1101 git -C "${MYDIR}" "${clang_format}" --binary "${clang_format}" \
1102 --style=file --diff "${MR_ANCESTOR_SHA}" -- >"${tmppatch}"
1103 { set +x; } 2>/dev/null
1104
1105 if grep -E '^--- ' "${tmppatch}">/dev/null; then
1106 if [[ -n "${LINT_OUTPUT:-}" ]]; then
1107 cp "${tmppatch}" "${LINT_OUTPUT}"
1108 fi
1109 clang_patch="${tmppatch}"
1110 else
1111 echo "clang-format check OK" >&2
jpegxl-bot31c71b02020-12-24 17:42:41 +01001112 return ${ret}
jpegxl-botff093712019-12-27 18:12:34 +01001113 fi
1114 done
1115
1116 if [[ ${#installed[@]} -eq 0 ]]; then
1117 echo "You must install clang-format for \"git clang-format\"" >&2
1118 exit 1
1119 fi
1120
1121 # clang-format is installed but found problems.
1122 echo "clang-format findings:" >&2
1123 "${COLORDIFF_BIN}" < "${clang_patch}"
1124
1125 echo "clang-format found issues in your patches from ${MR_ANCESTOR_SHA}" \
1126 "to the current patch. Run \`./ci.sh lint | patch -p1\` from the base" \
1127 "directory to apply them." >&2
1128 exit 1
1129}
1130
1131# Runs clang-tidy on the pending CLs. If the "all" argument is passed it runs
1132# clang-tidy over all the source files instead.
1133cmd_tidy() {
1134 local what="${1:-}"
1135
1136 if [[ -z "${CLANG_TIDY_BIN}" ]]; then
jpegxl-bot63349442020-05-25 08:56:34 +02001137 echo "ERROR: You must install clang-tidy-7 or newer to use ci.sh tidy" >&2
jpegxl-botff093712019-12-27 18:12:34 +01001138 exit 1
1139 fi
1140
1141 local git_args=()
1142 if [[ "${what}" == "all" ]]; then
1143 git_args=(ls-files)
1144 shift
1145 else
1146 merge_request_commits
1147 git_args=(
1148 diff-tree --no-commit-id --name-only -r "${MR_ANCESTOR_SHA}"
1149 "${MR_HEAD_SHA}"
1150 )
1151 fi
1152
1153 # Clang-tidy needs the compilation database generated by cmake.
1154 if [[ ! -e "${BUILD_DIR}/compile_commands.json" ]]; then
1155 # Generate the build options in debug mode, since we need the debug asserts
1156 # enabled for the clang-tidy analyzer to use them.
1157 CMAKE_BUILD_TYPE="Debug"
1158 cmake_configure
jpegxl-bot63349442020-05-25 08:56:34 +02001159 # Build the autogen targets to generate the .h files from the .ui files.
1160 local autogen_targets=(
1161 $(ninja -C "${BUILD_DIR}" -t targets | grep -F _autogen: |
1162 cut -f 1 -d :)
1163 )
1164 if [[ ${#autogen_targets[@]} != 0 ]]; then
1165 ninja -C "${BUILD_DIR}" "${autogen_targets[@]}"
1166 fi
jpegxl-botff093712019-12-27 18:12:34 +01001167 fi
1168
1169 cd "${MYDIR}"
1170 local nprocs=$(nproc --all || echo 1)
1171 local ret=0
1172 if ! parallel -j"${nprocs}" --keep-order -- \
1173 "${CLANG_TIDY_BIN}" -p "${BUILD_DIR}" -format-style=file -quiet "$@" {} \
1174 < <(git "${git_args[@]}" | grep -E '(\.cc|\.cpp)$') \
1175 >"${BUILD_DIR}/clang-tidy.txt"; then
1176 ret=1
1177 fi
1178 { set +x; } 2>/dev/null
1179 echo "Findings statistics:" >&2
1180 grep -E ' \[[A-Za-z\.,\-]+\]' -o "${BUILD_DIR}/clang-tidy.txt" | sort \
1181 | uniq -c >&2
1182
1183 if [[ $ret -ne 0 ]]; then
1184 cat >&2 <<EOF
1185Errors found, see ${BUILD_DIR}/clang-tidy.txt for details.
1186To automatically fix them, run:
1187
1188 SKIP_TEST=1 ./ci.sh debug
1189 ${CLANG_TIDY_BIN} -p ${BUILD_DIR} -fix -format-style=file -quiet $@ \$(git ${git_args[@]} | grep -E '(\.cc|\.cpp)\$')
1190EOF
1191 fi
1192
1193 return ${ret}
1194}
1195
jpegxl-bot9e183e12020-10-29 12:36:26 +01001196# Print stats about all the packages built in ${BUILD_DIR}/debs/.
1197cmd_debian_stats() {
1198 { set +x; } 2>/dev/null
1199 local debsdir="${BUILD_DIR}/debs"
1200 local f
1201 while IFS='' read -r -d '' f; do
1202 echo "====================================================================="
1203 echo "Package $f:"
1204 dpkg --info $f
1205 dpkg --contents $f
1206 done < <(find "${BUILD_DIR}/debs" -maxdepth 1 -mindepth 1 -type f \
1207 -name '*.deb' -print0)
1208}
1209
1210build_debian_pkg() {
1211 local srcdir="$1"
1212 local srcpkg="$2"
1213
1214 local debsdir="${BUILD_DIR}/debs"
1215 local builddir="${debsdir}/${srcpkg}"
1216
1217 # debuild doesn't have an easy way to build out of tree, so we make a copy
1218 # of with all symlinks on the first level.
1219 mkdir -p "${builddir}"
1220 for f in $(find "${srcdir}" -mindepth 1 -maxdepth 1 -printf '%P\n'); do
1221 if [[ ! -L "${builddir}/$f" ]]; then
1222 rm -f "${builddir}/$f"
1223 ln -s "${srcdir}/$f" "${builddir}/$f"
1224 fi
1225 done
1226 (
1227 cd "${builddir}"
1228 debuild -b -uc -us
1229 )
1230}
1231
1232cmd_debian_build() {
1233 local srcpkg="${1:-}"
1234
1235 case "${srcpkg}" in
1236 jpeg-xl)
1237 build_debian_pkg "${MYDIR}" "jpeg-xl"
1238 ;;
1239 highway)
1240 build_debian_pkg "${MYDIR}/third_party/highway" "highway"
1241 ;;
1242 *)
1243 echo "ERROR: Must pass a valid source package name to build." >&2
1244 ;;
1245 esac
1246}
1247
jpegxl-botff093712019-12-27 18:12:34 +01001248main() {
1249 local cmd="${1:-}"
1250 if [[ -z "${cmd}" ]]; then
1251 cat >&2 <<EOF
1252Use: $0 CMD
1253
1254Where cmd is one of:
1255 opt Build and test a Release with symbols build.
1256 debug Build and test a Debug build (NDEBUG is not defined).
1257 release Build and test a striped Release binary without debug information.
1258 asan Build and test an ASan (AddressSanitizer) build.
1259 msan Build and test an MSan (MemorySanitizer) build. Needs to have msan
1260 c++ libs installed with msan_install first.
1261 tsan Build and test a TSan (ThreadSanitizer) build.
1262 test Run the tests build by opt, debug, release, asan or msan. Useful when
1263 building with SKIP_TEST=1.
jpegxl-bot5175d112021-02-23 16:59:45 +01001264 gbench Run the Google benchmark tests.
jpegxl-botf84edfb2020-04-20 09:48:41 +02001265 fuzz Generate the fuzzer corpus and run the fuzzer on it. Useful after
1266 building with asan or msan.
jpegxl-botff093712019-12-27 18:12:34 +01001267 benchmark Run the benchmark over the default corpus.
1268 fast_benchmark Run the benchmark over the small corpus.
1269
1270 coverage Buils and run tests with coverage support. Runs coverage_report as
1271 well.
1272 coverage_report Generate HTML, XML and text coverage report after a coverage
1273 run.
1274
1275 lint Run the linter checks on the current commit or merge request.
1276 tidy Run clang-tidy on the current commit or merge request.
1277
1278 msan_install Install the libc++ libraries required to build in msan mode. This
1279 needs to be done once.
1280
jpegxl-bot9e183e12020-10-29 12:36:26 +01001281 debian_build <srcpkg> Build the given source package.
1282 debian_stats Print stats about the built packages.
1283
jpegxl-botff093712019-12-27 18:12:34 +01001284You can pass some optional environment variables as well:
1285 - BUILD_DIR: The output build directory (by default "$$repo/build")
1286 - BUILD_TARGET: The target triplet used when cross-compiling.
1287 - CMAKE_FLAGS: Convenience flag to pass both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS.
1288 - CMAKE_PREFIX_PATH: Installation prefixes to be searched by the find_package.
jpegxl-botf84edfb2020-04-20 09:48:41 +02001289 - ENABLE_WASM_SIMD=1: enable experimental SIMD in WASM build (only).
1290 - FUZZER_MAX_TIME: "fuzz" command fuzzer running timeout in seconds.
jpegxl-botff093712019-12-27 18:12:34 +01001291 - LINT_OUTPUT: Path to the output patch from the "lint" command.
jpegxl-bot21f5f752020-06-30 13:06:56 +02001292 - SKIP_CPUSET=1: Skip modifying the cpuset in the arm_benchmark.
jpegxl-botff093712019-12-27 18:12:34 +01001293 - SKIP_TEST=1: Skip the test stage.
1294 - STORE_IMAGES=0: Makes the benchmark discard the computed images.
jpegxl-bot849ebf62020-09-29 16:23:20 +02001295 - TEST_STACK_LIMIT: Stack size limit (ulimit -s) during tests, in KiB.
1296 - STACK_SIZE=1: Generate binaries with the .stack_sizes sections.
jpegxl-botff093712019-12-27 18:12:34 +01001297
1298These optional environment variables are forwarded to the cmake call as
1299parameters:
jpegxl-botf84edfb2020-04-20 09:48:41 +02001300 - CMAKE_BUILD_TYPE
jpegxl-botff093712019-12-27 18:12:34 +01001301 - CMAKE_C_FLAGS
1302 - CMAKE_CXX_FLAGS
jpegxl-bot50bbf272020-06-10 14:59:11 +02001303 - CMAKE_C_COMPILER_LAUNCHER
1304 - CMAKE_CXX_COMPILER_LAUNCHER
jpegxl-botb3a65712020-02-06 13:22:22 +01001305 - CMAKE_CROSSCOMPILING_EMULATOR
jpegxl-botf84edfb2020-04-20 09:48:41 +02001306 - CMAKE_FIND_ROOT_PATH
jpegxl-botff093712019-12-27 18:12:34 +01001307 - CMAKE_EXE_LINKER_FLAGS
jpegxl-bote3c58a02020-06-15 08:51:22 +02001308 - CMAKE_MAKE_PROGRAM
jpegxl-botff093712019-12-27 18:12:34 +01001309 - CMAKE_MODULE_LINKER_FLAGS
1310 - CMAKE_SHARED_LINKER_FLAGS
1311 - CMAKE_TOOLCHAIN_FILE
jpegxl-botff093712019-12-27 18:12:34 +01001312
1313Example:
1314 BUILD_DIR=/tmp/build $0 opt
1315EOF
1316 exit 1
1317 fi
1318
1319 cmd="cmd_${cmd}"
1320 shift
1321 set -x
1322 "${cmd}" "$@"
1323}
1324
1325main "$@"