ndk-build 가 링크 단계에서 멈췄다. 로그 맨 아래 줄만 보고 도구가 안 깔렸다고 판단했다. 그 라이브러리를 안 쓰는 쪽으로 코드를 돌리니 빌드는 통과했다. 일주일 뒤 다른 화면에서 같은 자리에서 멈췄다.
Table of contents
Open Table of contents
첫 추측이 원인이 아니었다
멈춘 곳 앞에 로그가 수십 줄 있었다. 마지막 줄만 봤다. 앞쪽을 다시 읽으니 다른 것이 있었다.
cannot find -lstdc++
도구가 없는 것이 아니라 링크할 대상을 못 찾은 것이었다. 컴파일러는 정상적으로 돌고 있었다. Application.mk 에 APP_STL 이 없어서 기본값인 system 으로 간 것이 원인이었다. 그 런타임에는 표준 C++ 라이브러리가 거의 없어서 libstdc++ 를 찾을 수 없다. 도구가 없었다면 명령을 못 찾는다는 메시지가 나왔을 텐데 그건 없었다.
우회는 원인을 남겨 둔다
첫 번째 우회는 그 라이브러리를 안 쓰는 것이었다. 그 화면에서는 통했다. 그런데 같은 Application.mk 를 프로젝트 전체가 쓴다. 설정이 원인인 이상 표준 라이브러리를 쓰는 곳마다 같은 자리에서 멈춘다.
우회는 증상 하나를 지운 것이지 원인을 지운 것이 아니다. 원인이 남으면 증상은 다른 얼굴로 다시 나온다. 두 번째로 만났을 때는 첫 우회가 오히려 방해가 됐다. 코드가 이미 비틀려 있어 원래 형태로 되돌리는 일이 먼저였다. APP_STL := gnustl_static 한 줄이 진짜 고침이었다.
로그를 뒤에서 앞으로 읽었다
마지막 줄은 대개 결과다. 원인은 그보다 앞에 있다. 읽는 순서를 정했다.
맨 아래에서 실패를 확인하고 위로 올라가며 처음 나온 오류 줄을 찾는다. 그 줄이 어느 단계에서 나왔는지 보고 그 단계에 들어간 입력을 확인한다. ndk-build V=1 로 돌리면 실제 명령줄이 그대로 나와서 어느 인자가 빠졌는지가 보인다. 오류만 훑으면 뒤쪽 파생 오류만 보이니 경고도 같이 본다.
없는 것과 못 찾는 것
이 둘이 헷갈리기 쉽다. 도구가 없으면 명령을 못 찾는다고 나온다. 도구는 있는데 대상을 못 찾으면 다른 메시지다. 대상은 있는데 형식이 다르면 또 다르다.
셋 다 안 된다로 보인다. 손볼 곳은 설치와 Application.mk 와 Android.mk 의 LOCAL_LDLIBS 로 다르다. 메시지를 안 읽고 첫 번째로 단정하면 나머지 둘에서 설치를 반복한다. 실제로 NDK 를 두 번 지웠다 깔았고 아무것도 안 바뀌었다.
추측을 세웠으면 한 줄로 확인할 방법이 대개 있다. 명령을 쳐 보거나 경로에 파일이 있는지 보거나 설정 값을 출력하면 갈린다. 원인을 찾은 뒤 우회로 비틀어 놓은 코드를 되돌렸다. 이유 없는 형태가 남으면 다음 사람은 이유가 있다고 본다.
정리
- 로그의 마지막 줄은 결과이고 원인은 앞쪽에 있다
ndk-build V=1로 돌리면 실제 명령줄이 보인다- 오류만 훑으면 파생 오류만 보이므로 경고도 같이 본다
APP_STL을 안 주면 기본이system이라libstdc++가 없다- 없다와 못 찾는다는 메시지가 다르고 손볼 곳도 다르다
- 우회는 증상 하나만 지우고 원인이 남으면 다른 곳에서 다시 나온다
- 추측을 세웠으면 한 줄로 확인할 방법을 먼저 찾는다
- 원인을 찾은 뒤 비틀어 놓은 것을 되돌린다