C.W.K.
Stream
Lesson 01 of 05 · published

swift build 는 배포 증명이 아냐

~12 min · self-contained, deployment, dylib, build

Level 0릴 입문자
0 XP0/39 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"성공한 swift build 는 배포 증명이 아냐."

제일 비싼 초록 체크마크

swift build 를 돌려, 성공해, 그리고 네 뇌 속 뭔가가 그 작업을 완료로 분류해. 큰 C 라이브러리를 embed 하는 네이티브 앱한텐, 그 본능이 시한이 달린 함정이야. 초록 빌드는 네 환경에서 코드가 컴파일되고 링크됐다는 걸 증명해. 앱이 네 것 아닌 Mac 에서 실행되기라도 할지에 대해선 아무 말도 안 해.

이유는 링커가 libmpv 를 어디서 찾았느냐야. 네 개발 머신에선 Homebrew 가 걜 깔끔한 경로에 두고, 빌드가 신나게 거기 링크해. 그 정확한 바이너리를 Homebrew 없는 깨끗한 Mac 에 배포하면, 없는 dylib 을 찾다 실행 시 죽어. 빌드는 정직했어 — 찾은 걸 링크했지. 찾은 게 그냥 여행을 안 할 뿐이야.

초록 빌드는 약속이고; 설치된 아티팩트가 증명이야. 컴파일하고 링크하는 건 한 단계; 타겟에서 도는 걸 만드는 건 다른 단계야. 첫 번째의 만족스러운 체크마크가 두 번째를 했다고 널 설득하게 두지 마.

함정은 명령 하나로 보여 — 빌드된 바이너리한테 의존성이 어디 산다고 생각하는지 물어봐:

'내 머신에서 돌아' 는 네이티브 앱 질병이지, 그냥 농담이 아냐. 네 Mac 은 네가 가진 제일 오염된 테스트 환경이야: 네 Homebrew, 네 도구, 네 경로, 네 인증서가 있어. 자립 번들의 핵심은 그 오염에 의존하기를 멈추는 거야. 깨끗한 타겟에서 테스트해, 아니면 네 머신의 난장판을 테스트하는 거야.

Build, Release, Run 은 세 다른 것이야

제일 깔끔한 사고 모델은 twelve-factor 규율에서 빌려: build, release, run 은 별도 단계야. build 는 소스를 아티팩트로 바꿔. release 는 그 아티팩트를 자립하고 버전 붙은 뭔가로 패키징해. run 은 그 release 가 진짜 타겟에서 실행되는 거야. Ashen Reel 은 일부러 걜 별개로 취급해 — build 는 바이너리를 만들고, 스크립트된 release 는 전체 의존성 closure 를 번들하고 서명하고, run 은 실제 설치된 앱에서 증명돼. 걜 합치는 게 딱, dev 전용 dylib 경로가 사용자의 실행 실패까지 쭉 항해하는 방식이야.

Code

초록 빌드가 dev 전용 경로를 숨겨 — 명령 하나가 드러냄·bash
# 'It builds!' -- but where does the binary think libmpv lives?
swift build            # succeeds. feels done. is not done.

otool -L .build/debug/AshenReel | grep -i mpv
#   /opt/homebrew/opt/mpv/lib/libmpv.2.dylib   <-- a DEV-ONLY path
#
# That path exists on YOUR Mac (via Homebrew) and NOWHERE on a clean target.
# swift build proved the code links in your environment. It proved nothing
# about whether the installed app carries libmpv with it. Those are different
# claims, and only the second one is 'deployable'.

External links

Exercise

네가 배포하는 뭔가에 대해, 네 빌드 단계가 실제로 증명하는 것 대 배포가 요구하는 것을 나열해. 빌드가 네 로컬 환경에서 해석하는 의존성 하나를 찾아 — 시스템 라이브러리, 설치된 도구, 환경 변수, 경로. 물어봐: 그 의존성이 아티팩트랑 여행해, 타겟에 있다고 가정돼? 가정되면, 그게 첫 깨끗한 머신을 기다리는 실행 실패야.
Hint
네 'otool -L' 등가물(나 ldd, 의존성 검사기)을 빌드된 아티팩트에 겨누고 런타임에 뭘 찾길 기대하는지 읽어. '네' 머신 특유의 경로나 도구로 해석되는 모든 항목이 빌드가 절대 안 알려줄 배포 구멍이야 — 빌드 관점에선 전부 바로 거기 있었으니까.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.