헤더의 상수를 고치고 빌드했다. 성공했는데 동작이 그대로였고 CCLOG 를 넣어 보니 옛 값이 찍혔다.
Table of contents
Open Table of contents
컴파일은 다시 됐다
처음에는 헤더를 고쳐도 소스가 다시 안 컴파일되는 줄 알았다. make 는 파일 시각으로 대상을 정한다. 헤더를 고쳐도 소스 시각은 안 바뀐다.
그런데 ndk-build 로그에는 그 상수를 쓰는 파일들이 있었다. 실제로 다시 컴파일되고 있었다. 추측이 먼저였고 로그가 그것을 부정했다.
의존 관계는 이미 잡혀 있었다
찾아보니 ndk-build 의 컴파일 규칙에 -MMD -MP -MF 가 이미 들어 있었다. 컴파일할 때 그 소스가 포함한 헤더 목록이 .d 파일로 같이 나온다. 다음 빌드가 그것을 읽는다.
$(PRIVATE_CC) -MMD -MP -MF $(PRIVATE_DEPS) $(PRIVATE_CFLAGS) ...
그러니 LOCAL_CFLAGS 에 뭘 더 넣을 일이 아니었다. 없다고 생각한 기능이 이미 있는 경우였고 확인이 먼저였다.
결과물이 간 자리
진짜 원인은 다른 데 있었다. ndk-build 는 obj/local/armeabi/ 에서 만든다. 그것을 libs/armeabi/ 로 복사하고 앱에 담기는 것은 뒤쪽이다.
$ ls -l libs/armeabi/libgame.so
$ ls -l obj/local/armeabi/libgame.so
두 파일의 시각이 달랐다. 복사가 안 돼서 앱에는 옛 .so 가 들어가고 있었다. 빌드가 성공한 것과 그 결과물이 실행되는 자리로 간 것은 별개였다.
성공이 무엇을 뜻하나
이 일로 빌드 성공의 뜻을 다시 봤다. 대상으로 잡힌 것들이 성공했다는 뜻이다. 내가 고친 것이 반영됐다는 뜻이 아니다. 대상이 비어 있어도 성공이다.
ndk-build -n 을 주면 실행하지 않고 명령만 출력한다. 고친 헤더를 쓰는 소스가 그 목록에 있는지 먼저 볼 수 있다.
빌드 시각을 결과물에 심는 것도 넣었다. 앱을 켜면 CCLOG 에 그 값이 찍힌다. 방금이 아니면 옛 결과가 도는 것이다. 이 파일만은 매번 다시 컴파일되게 따로 처리했다. 확인 수단이 빌드 안에 있으면 매번 ls 로 시각을 비교할 일이 없다.
정리
- 빌드 성공은 대상으로 잡힌 것이 성공했다는 뜻이다
- 대상이 비어 있어도 성공이다
ndk-build는-MMD -MP로 헤더 의존을 이미 추적한다- 없다고 생각한 기능이 이미 있는지 먼저 확인한다
ndk-build -n으로 무엇이 대상인지 미리 본다- 만드는 자리는
obj/local/이고 앱에 담기는 자리는libs/다 - 결과물이 실행되는 자리로 갔는지까지 확인한다
- 빌드 시각을 결과물에 심으면 옛것이 도는지 바로 안다