OpenWrt tools/elfutils 빌드 실패에서 첫 compiler 오류를 분리하는 법

마지막 make 줄보다 먼저 나온 오류를 찾는다

OpenWrt build log의 끝에는 여러 단계의 make[...] Error가 연속으로 나타납니다. 마지막 줄은 상위 target이 실패했다는 결과일 뿐, compiler가 처음 거부한 header, symbol, option을 설명하지 않는 경우가 많습니다. 전체 world build를 반복하기 전에 실패 target만 직렬에 가깝게 다시 실행하고 verbose log를 보존해야 합니다.

tools/elfutils는 target router용 package가 아니라 build host에서 사용하는 도구 단계입니다. 따라서 router target의 runtime package 문제보다 host compiler, prerequisite, source revision, stale build artifact를 먼저 봅니다.

재현 보고서에 반드시 들어갈 기준선

기준선남길 값이유
sourcebranch, commit, git status다른 revision의 오류를 같은 문제로 묶지 않습니다.
hostdistribution, compiler, prerequisitebuild host 조합을 재현할 수 있습니다.
configdiffconfig와 target전체 .config를 공개하지 않고 선택을 보존합니다.
feedsupdate/install 시각과 변경 여부source tree와 feed 조합을 고정합니다.
first error첫 compiler 또는 configure 실패와 앞 문맥상위 make 실패가 아닌 원인을 봅니다.
umask 077
DIAG_DIR=$(mktemp -d "${TMPDIR:-/tmp}/elfutils-diag.XXXXXXXX") || exit 1
git status --short
git rev-parse HEAD
test -f .config || exit 1
cp -p .config "$DIAG_DIR/config-before" || exit 1
./scripts/diffconfig.sh >"$DIAG_DIR/diffconfig-before.txt" || exit 1
gcc --version
# Do not run make defconfig just to capture the current failure.

OpenWrt 문서는 root나 sudo로 build하지 말고, build 경로에 공백을 두지 말라고 안내합니다. source tree의 owner가 섞였거나 network filesystem이 Unix permission을 보존하지 못하면 다른 오류가 이어질 수 있으므로 path와 permission도 기준선에 포함합니다.

target만 clean하고 verbose로 다시 만든다

make -j1 tools/elfutils/clean V=s >"$DIAG_DIR/clean.log" 2>&1 || exit 1
# Bash; keep full build output private.
set -o pipefail
set +e
make -j1 tools/elfutils/compile V=s 2>&1 | tee "$DIAG_DIR/elfutils-build.log" >/dev/null
build_status=("${PIPESTATUS[@]}")
printf 'make=%s tee=%s\n' "${build_status[0]}" "${build_status[1]}"
if (( build_status[0] != 0 || build_status[1] != 0 )); then
  printf '%s\n' 'STOP: inspect the private log; build did not succeed' >&2
  exit 1
fi

Bash에서 make와 tee의 종료 코드를 파이프라인 직후 PIPESTATUS로 함께 기록합니다. tee가 로그를 저장했다고 make까지 성공한 것은 아닙니다. 실패 시 private 로그에서 첫 compiler 오류와 문맥을 확인합니다. -j1은 출력 순서를 좁히는 조건이지 compiler 결함의 수정이 아닙니다. 모의 make 종료 7·tee 종료 0에서 중단되는 셸 동작만 확인했고 실제 OpenWrt 빌드는 재현하지 않았습니다.

첫 오류 종류에 따라 조치 범위를 정한다

  • header 또는 host library 없음: 현재 OpenWrt branch의 build system setup 문서에서 host distribution prerequisite를 확인합니다. package 이름은 distribution과 release에 따라 다르므로 다른 OS의 설치 명령을 그대로 쓰지 않습니다.
  • compiler option을 인식하지 못함: host compiler version과 source branch 지원 범위를 비교합니다. 임의로 option을 삭제하면 다음 단계에서 잘못된 tool을 만들 수 있습니다.
  • download 또는 checksum 실패: compiler 문제로 분류하지 않습니다. URL, download cache, proxy, 저장 공간을 별도 경로로 확인합니다.
  • stale object 의심: 먼저 tools/elfutils target만 clean합니다. toolchain 전체와 config를 지우는 broad clean은 마지막 수단입니다.
  • source 수정 또는 local patch가 있음: git status와 diff를 보존합니다. clean checkout에서 재현되는지 별도 worktree로 비교하고 기존 수정을 지우지 않습니다.

feeds와 config를 동시에 흔들지 않는다

OpenWrt 문서는 source와 feeds를 업데이트한 뒤 install하고 make defconfig로 outdated config를 정리하는 흐름을 안내합니다. 하지만 오류를 조사하면서 branch, feeds, host package, config를 한꺼번에 바꾸면 어떤 변경이 해결했는지 알 수 없습니다. 현재 조합의 log를 먼저 남기고 한 단계씩 바꿉니다.

# Separate change after preserving the original failure and feed revisions.
./scripts/feeds update -a || exit 1
./scripts/feeds install -a || exit 1
make defconfig || exit 1
# Bash; keep full build output private.
set -o pipefail
set +e
make -j1 tools/elfutils/compile V=s 2>&1 | tee "$DIAG_DIR/elfutils-build-after.log" >/dev/null
build_status=("${PIPESTATUS[@]}")
printf 'make=%s tee=%s\n' "${build_status[0]}" "${build_status[1]}"
if (( build_status[0] != 0 || build_status[1] != 0 )); then
  printf '%s\n' 'STOP: inspect the private log; build did not succeed' >&2
  exit 1
fi

dirclean과 distclean의 경계

make dirclean은 build tools와 toolchain까지 넓게 지우고, make distclean은 config와 feeds를 포함한 더 많은 상태를 제거합니다. 공식 문서도 distclean을 build system의 factory reset에 가깝게 설명합니다. diffconfig, patch, download cache와 재현 log를 보존하지 않은 상태에서 먼저 실행하면 원인 조사 자료가 사라집니다.

target clean, prerequisite 보완, 동일 revision 재시험으로도 해결되지 않을 때만 넓은 clean을 계획합니다. clean 전후 commit과 diffconfig를 같게 유지해야 stale artifact 효과를 판단할 수 있습니다.

성공 판정과 보고

tools/elfutils/compile 성공은 해당 host tool 단계가 통과했다는 의미이지 firmware 전체 성공은 아닙니다. 이후 world build에서 다른 target이 실패하면 새 첫 오류로 분리합니다. 보고서에는 전체 log를 첨부하되 home path, token이 포함된 feed URL, private repository 주소를 제거합니다.

성공 후에는 diffconfig-before.txt와 현재 diffconfig를 비교해 의도하지 않은 target 또는 package 선택 변화가 없었는지 확인합니다. 단순히 image 파일이 생성됐다는 사실만으로 원래 profile이 유지됐다고 가정하지 않습니다.

공식 문서 및 확인 기준

이 글에 남아 있던 이전 검증 기록

검증 수준: 공식 문서 대조

OpenWrt build target, verbose log와 clean 범위를 공식 문서로 확인했습니다. 특정 compiler 오류를 재현하지 않았으므로 elfutils의 단일 원인이나 수정 patch를 주장하지 않습니다.

작성 방식과 수정 정책 · 오류 제보