티스토리 뷰
안녕하세요 :) Zedd입니다.
티스토리 앱이 완전히 리뉴얼 됐네요!!
https://apps.apple.com/kr/app/%ED%8B%B0%EC%8A%A4%ED%86%A0%EB%A6%AC-tistory/id906304982
어우 앱 너무 좋구
통계가 정말 좋아진것 같아요~~~~~^^~~~~~~
거기다가 앱에서 이제 블로그 구독까지 가능하다는 사실/!?!?!??!
정말 누가만들었는지..만드실 때 정말 고생하셨을 것 같아요~~!~!~!~!
꼭 다운 받아야겠죠???????????????????
ㅎ
ㅎ
ㅎ
큼큼..
네 아무튼 오늘은 제목에서 볼 수 있듯이
Behind the Scenes of the Xcode Build Process
를 공부해보려고 해요.
저번글에서
https://zeddios.tistory.com/908
Mach-O를 공부했었잖아요!
그리고 이제 막
얘네들을 공부하려고 했는데, 또 막 공부하려고 보니...
뭐가 링킹이 되고 뭐가 복사가 되는데 얘는 뭐 shared고 뭐 어쩌구 저쩌구................
근데 제가 링킹이 정확히 뭔지 잘 모르겠는거에요?!?!?
그래서 어찌어찌하다가 정말 근본적인......이런 Xcode의 빌드 프로세스는 어떻게되냐!! 까지 왔습니다.
WWDC 2018의 Behind the Scenes of the Xcode Build Process
https://developer.apple.com/videos/play/wwdc2018/415/
세션입니다.
간략하게 정리를 해볼려고 합니다 :D 아마 한번에 다 안하고 나눠서 포스팅 하게 될 것 같아요~
그럼 시작!
Behind the Scenes of the Xcode Build Process
일단 2018년이니까 Xcode10이잖아요!?
Xcode10에서 성능과 안정성이 향상된 새로운 Build System이 도입되었다고 합니다.
이 세션은 우리가 Commnd + B를 눌렀을 때 어떤일들이 발생하는지!! 보는 세션입니다.
예를들어,
-
빌드 프로세스는 어떤식으로 구성되는지
-
Xode는 프로젝트 파일의 정보를 사용해서 빌드 프로세스를 모델링하고 조정하는 방법을 어떻게 결정하는지
-
Clang과 Swift가 소스코드를 Object file로 빌드하는 방법 (참고로 Clang은 "클랭"이며, C, C++, Objective-C, Objective-C++ 언어를 위한 컴파일러 프론트엔드라고 합니다. LLVM을 백엔드로 사용하며........어쩌구 저쩌구..아ㅋ....저 이때까지 씨랭이라 읽는줄ㅋ....ㅋㄹ.ㅋ.ㅎ.ㅋㅎ.ㅎ..ㅋㅎ.ㅋ.ㅎ.ㅋㅋㅋㅋ....ㅋ..!!!!!!!!!!!!!!)
-
헤더와 모듈의 작동방식
-
컴파일러가 코드에서 declarations을 찾는 방법
-
Swift compliation model이 C, C++, Objective-C와 근본적으로 어떻게 다른지
-
빌드 프로세스 마지막 중 하나를 수행하는 링커(linker)에 대해
-
Symbol이 무엇이며, 이 Symbol이 소스코드와 어떤 관련이 있는지
-
링커가 컴파일러에 의해 생성된 object file을 어떻게 얻고, 그것들을 결합해서 어떻게 어플리케이션 or 프레임워크의 최종 실행파일을 생성하는지
뭐 이런것들을 살펴보는 세션같아요!? 짜릿하네요
저 용이 도대체 뭔가....하고 봤는데
LLVM이자식....로고도 있었어...?
드래곤의 종류인 와이번이라고 하네요.
그리고
저게 링커의..로고(?)인가봐요!?
오늘 볼 앱은 그냥 아-주 간단한 PetWall이라는 앱인데 걍 애완동물 보여주는 앱임ㅋ
ㄱㅇㅇ
일단! Xcode에서 PetWall과 같은 일반적인 앱을 빌드할 때,
빌드 프로세스가 무엇이고 어떻게 작동하는지 이해해볼거에요.
뭐 걍 우리의 프로젝트 보는 것 같죠?
빨간색 박스는 잘 안보이실까봐 제가..걍 넣어본건데,
Swift파일과 Objc파일이 있고, 앱 타켓, 프레임워크 등을 가지고 있죠.
따라서 앱을 빌드 할 때,
프로젝트의 소스코드, 리소스들에서
배포를 위해 App Store 업로드 하는 패키지까지
여러 단계가 수반됩니다.
먼저,
소스코드를 컴파일하고 링크해야합니다.
그리고
헤더 및 asset카탈로그, 스토리보드와 같은 리소스를 복사하고 처리합니다.
(헤더와 스토리보드도 리소스란 사실!!)
마지막으로
code sign을 하고 make file에서 사용자 지정 작업을 수행할 수도 있습니다
(ex. shell script, 유효성 검사 도구 실행)
빌드 프로세스에서 이러한 대부분의 작업들은 커맨드 라인 툴을 실행하여 수행된다고 합니다.
Clang, LD, AC tool, IB tool, Code sign 등.....이러한 tool들은
Xcode 프로젝트의 configuration에 따라
매우 특정한 argument의 set, 특정 순서로 실행되어야 한다고 해요?
ㅎ
ㅡ
ㅁ...
작업 쩜 많이 하네ㅎ
ㅎㅋ
암튼 빌드시스템이 일 개많이 하자나;;;;;
그래서 이런 빌드를 수행할 때 마다 이런 일들의 조정 및 실행을 자동화해줌.
글고 복잡한 상호 의존성 그래프(graph of interdependencies)나
뭐 엄청 많은 작업들이 빌드 프로세스에 포함될 수 있자나?
그럼 나 그 작업 하나하나 터미널에 치고있어야함?
ㄴㄴ
이런거 다 빌드시스템 시키면됨 ㅇㅇ응 개꿀이야~~
위에서
Xcode 프로젝트의 configuration에 따라
매우 특정한 argument의 set, 특정 순서로 실행되어야 한다
ㄹㅏ고 했자나요
그럼 이 특정 순서는 어떻게 결정되고 이게 왜 중요한지 알아봅시다.
빌드 작업들이 실행되는 순서는
- 종속성 정보(dependency information)
- 작업이 소비하는 입력 및 생성되는 출력
에 따라 결정된다고 합니다.
예를들어 컴파일 작업은
PetController.m과 같은 소스코드 파일을 입력으로 사용하고,
PetController.o와 같은 객체파일을 출력으로 생성합니다.
마찬가지로, 링커작업은
이전 작업에서 컴파일러가 생성한 많은 객체파일을 입력으로 사용하고,
실행파일 또는 라이브러리를 출력합니다.
.app번들에 들어갈 PetWall실행파일 처럼요.
그럼 패턴이 보이자나.
이
그래프 구조를 통해 의존성 정보가 어떻게 흐르는지 알 수 있으며,
결과적으로!! 실행되어야 할 순서를 알려주게 되죠.
이제 그래프에서 컴파일 작업을 일종의 트래픽 lane과 같은 것으로 볼거에요.
위 그림에서 볼 수 있다시피
컴파일 작업이 자체 lane에서 완전히 독립적이므로, 병렬로 실행 할 수 있습니다.
링커작업은 아까 이전 작업에서 컴파일러가 생성한 많은 객체파일을 입력으로 사용한다고 그랬잖아요?
그래서 이 링커작업은 마지막에 와야한다는 것을 알 고 있죠.
따라서 빌드 시스템은 종속성 정보를 사용하여
- 작업을 실행해야하는 순서와
- 병렬로 실행 할 수 있는 작업
을 결정하며
이것을 "dependency order"라고 부른다고 해요.
ㅈ ㅏ!! 이때까지 빌드 프로세스가 어떻게 되는지 무엇인지를 다뤘으니,
"어떻게 작동"하는지를 자세히 살펴봅시다.
1. 빌드 시스템이 build description인 Xcode 프로젝트 파일을 가져옴.
프로젝트의 모든 파일을 Parse하고, Target, dependency관계를 고려합니다.
build settings을 지정하고, directed graph(유향그래프)라고 하는 트리형 구조로 바꿉니다.
이 그래프는 프로젝트의 입력 및 출력파일과
이를 처리하기 위해 실행되는 작업간의 모든 종속성을 나타내는 그래프라고 합니다.
2. 그 다음으로 low-level execution engine이 이 그래프를 처리하고,
종속성 스펙을 보고 실행할 작업을 파악합니다.
(실행해야하는 순서 또는 병렬로 실행할 수 있는 작업) 그런다음 실행을 진행합니다.
저 트리 그래프가 이렇게 작업들이 모아지고, 순서가 정해지게 된 거 보이시죠?
처음에 모여있는것들은 병렬로 실행해도 되는 작업이라고 보면 될 것 같아요.
그리고 아까 Xcode10에서 새로운 빌드시스템이 들어왔다고 그랬죠?
새로운 빌드 시스템을 위한 low-level build execution engine을 llbuild라고 한대요.
오픈소스 && Github이 개발했다고 합니다.
자 아까 이 빌드 시스템이 "어떻게 작동"하는지를 자세히 살펴보자고 했죠?
-> low-level execution engine. 즉 llbuild가 작업간의 모든 종속성을 나타내는 유향 그래프를 보고 실행순서/병렬로 수행 할 수 있는 작업들을 파악한다음 실행한다!
자 그럼 종속성을 발견했어!!
종속성 정보를 너무 많이 가질 수 없으므로(you can never have too much dependency information)
빌드 시스템은 실제로 작업 실행 프로세스중에 더 많은 정보를 발견할 수 있다고 해여ㅛ??
뭔소리지
예를들어
Clang이 Objective-C파일을 컴파일 할 때, object file이 생성됩니다.
근데 다른 파일이 생성될 수 있어요!!!
이렇게.
해당 소스파일(PetController.m)에 포함된 헤더 파일 목록이 포함된 파일..이라고 해요 뭔소리야
다음에 빌드할 ㄸㅐ 빌드시스템은 이 파일의 정보를 사용해서,
포함된 헤더파일을 변경하면 소스파일을 다시 컴파일해야합니다.
그리고
PetController.h, PetController.d, .n을 통해 .o 파일까지의 종속성 경로를 볼 수 있다고 해요..?
ㅎ
ㅡ
ㅁ....
이해안가
그러니까 처음에
1. "종속성 정보를 너무 많이 가질 수 없으므로
(you can never have too much dependency information)
빌드 시스템은 실제로 작업 실행 프로세스중에 더 많은 정보를 발견할 수 있다"
2. PetController.m을 컴파일 했더니 PetController.m에 포함된 헤더파일목록이 포함된 파일이 생김
이 말인 즉슨 작업 실행 중에 실제 그래프에 나타나있는 것 보다 더 많은 정보를 얻음
그러니까 이게 원래 그래프인데, .h, .m, .o로 종속성이 이렇게 나타나지는데, 새로운 정보를 발견해서
.h, .d, .o파일까지의 경로를 추가적으로 알 수 있게 되었다..!!!
이런건가>?
암튼 제 이해는...그렇다...! WWDC에서 더 안알랴줌
틀린거 있으면 꼭 말좀 ㅎ
자...이때까지 빌드 시스템의 주요 작업을 실행하는 방법에 대해서 쭉 이야기 했는데요.
프로젝트가 클수록! 당연히 빌드 프로세스가 오래걸립니다.
이거 개빡친다아님
따라서 빌드할 때 마다 이러한 작업을 모두!!!!!!!!!!!! 모두 실행하고 싶지 않자나???ㅇㅇ
그래서 빌드시스템은 저 그래프에서 태스크의 subset만 실행할 수 있음. 응 개이득이야~~
이를 증분빌드(incremental build)라고 하며,
증분빌드가 정확하고 효율적으로 작동하려면 정확한 종속성 정보를 갖는것이 매우 중요하다고 해요.
ㅇ ㅏ~~~~~ 아 ㅎ
아 증분빌드....증분빌드라는 단어를 저는 Let'Swift 판교에서 첨들었는데...
걍 컨텍스트상 아 전체를 다시 빌드 안하는 그런 느낌적인 느낌을 받고 정확한 정의를 몰랐는데..
그렇군요
증분빌드...!!!!!
다시한번 새깁시다..
증분빌드가 정확하고 효율적으로 작동하려면 정확한 종속성 정보를 갖는것이 매우 중요하다
그럼 빌드시스템은 실제로 변경사항을 어떻게 감지함?
1. 빌드프로세스의 각 작업에는 해당 작업이 가짐 or 관련된 정보로 부터 계산된
hash종류인 associate signature(연관 서명..?)이 있음.
2. 이 정보에는 파일 경로 및 수정 타임스탬프와 같은 작업 입력에 대한 통계 정보가 포함됨
3. 빌드시스템은 현재 빌드와 이전빌드에서 작업의 signature를 추적함
그래서 빌드가 수행될 때마다 작업을 다시 실행할지 여부를 알 수 있는 부분~~
왜냐면 작업의 서명이 이전 빌드에서 있었던 서명과 다르면
빌드시스템은 해당 작업을 다시 실행함 ㄹㄹㅎㅎ
같으면 모겠음
걍 스킵하는거임
이것이 증분빌드가 작동하는 방식의 기본 아이디어임
응 개쉬워~~
아까
빌드 프로세스는 특정 순서로 실행되는 일련의 작업이라고 했잖슴
이러케
근데 사실 빌드는 유향 그래프로 나타내지자나
그니까 이거는 빌드시스템의 작업이기 때문에
내가 이거 알아야 겠어?
내가 알아야겠냐고 야 Xcode 내가 알아야겠냐고
그래서 ^-^ 순서는 생각 ㄴㄴ하고
작업간의 종속성에 대해서 생각하고 빌드 시스템이!!!!!!!!!
그래프의 구조에 따라 작업을 가장 잘 수행할 수 있게 도와주면 좋자나
우리는 그걸 알아야 하는거임
이를통해 빌드시스템이
작업을 순서대로 올바르게 수행하고,
가능한 경우 멀티코어 하드웨어를 최대한 활용할 수 있도록 병렬화 할 수 있단 말임
ㅇㅋ/????
그럼
종속성은 어디서에 온단말임
where do dependencies come from?
저런데서 옴
-
Built in - 특정 작업의 경우, 종속성 정보는 빌드시스템에 내장된 지식(knowledge)에서 옴. 빌드시스템에는 컴파일러, 링커, asset 카탈로그 및 스토리보드 프로세서 등에 대한 규칙(rule)이 제공됨. 이러한 규칙은 어떤 종류의 파일이 입력으로 허용되고 어떤 출력이 생성되는지 정의함.
와 근데 Build rules 진짜 많이 봤을텐데 진짜 뭐라해야하지 인식?한건 처음인것같음zzzzzzzzz
맨날 Build Settings아니면 Build Phases만 드,가니까..
-
Target dependencies - Target이 빌드되는 순서를 대략적으로 결정함. 경우에따라 빌드시스템은 서로 다른 Target 및 병렬의 소스를 컴파일 할 수 있다고 해요?
이전 Xcode에서는 Target을 만들 때, 시작하기전에 전체 종속 Target의 컴파일을 완료해야 했는데,
Xcode10에 들어온 새로운 빌드시스템에서는 더 빨리 빌드를 시작할 수 있다고 합니다.
(= compile sources phase가 병렬화(parallelization)를 제공하기 전에 시작될 수 있음을 의미한다..?)
이게 뭔소리지
그러나 run script phases를 사용하는 경우,
이 병렬화를 적용하려면 해당 스크립트 단계를 완료해야한다고 합니다.
그니까 run script phases를 사용하면 좀 느려질 수 있다는..건가?!?!
당연한건가..
Target dependencies는 여기있는데
Xcode 11에서 진짜 타겟 디펜던시가 어딨어;;.;하고 계속 찾았는데
Xcode 11에서는 걍
Dependencies로 바뀐 듯.....
근데 제가 가진;;프로젝트들을 좀 많이 열어본것 같은데
앱타겟 보면 전부 Dependencies에 아이템이 하나두 없음
테스트번들을 만들면 Dependencies에 내 타겟이 걸리긴함
이건 당연한거겠죠..?!
ㅌㅔ스트번들은 내 타겟에 종속성을 가지고 있는건 당연하니까...!?
-
Implicit dependencies - Target dependencies랑 관련있음ㅇㅇ
이거에대해서 설명을 하는데 도대체 뭔소리지ㅣ..???
ex. binaries build phase를 사용하여 링크 라이브러리에 Target을 나열하고
scheme editor에서 implicit dependencies가 활성화 되어있으면(기본적으로 활성화 되어있음)
빌드시스템은 Target dependencies에 나열되지 않더라도 해당 Target에 대한 implicit dependencies를 설정한다.
먼 소리야..
그니까
Edit scheme > Build 에
흠 진짜 기본적으로 활성화 되어있군
이게 활성화 되어있으면..........
빌드시스템은 Target dependencies에 없어도!!
그니까 이렇게 나열되지 않더라도, 즉 없더라도
해당 Target에 대해
implicit dependencies(implicit dependencies라는 섹션(?)은 없고
implicit dependencies가 나타나는 곳은 저기 Link binary~ 저 섹션)
에 나타남...
ㅎ
ㅡ
ㅁ......
근데 꺼도...비활성화해도 남아있는디? 이미 들어간게 다시 빠지고 이러진 않는건가???
ㅋㅋㅋㅋㅋ.ㅋ....ㅋ.ㅋㅋ.ㅋ.ㅋ.ㅋ. 나에게 궁금증만 안겨주는....디펜던시...
-
Build phase dependencies - 우리가 ㅁ많이 아는 Build phase! 헤더복사, 소스 컴파일, 번들 리소스 복사 등 여러 단계가 있음을 볼 수 있음 ㅇㅇ
저는 이게 순서가 있다는 것도 지인이 알려줘서 얼마전에 알았읍니다..걍 있느건줄 알았자나 ㅎ
암튼 모르셨던 분들을 위해 설명드리자면,
이러한 각 phase들은 일반적으로 phase가 나열된 순서에 따라 그룹을 실행합니다!
근데 빌드시스템이 더 잘 알고있다면?? 이 순서를 무시할 수 있다고 해요.
(But the build system might ignore that order if it knows better.)
그래..니가 더 잘 알개ㅔㅆ지..
But the build system might ignore that order if it knows better.
Like if you have a link library, linked binary with library space ordered before compile sources.
그러니까 지금 위 그림보면 Compile Source가 Link Binary~보다 위에 있으니 순서가 먼저죠?
근데 빌드시스템이 더 잘 안다면? Compile Source 전에 linked binary with library를 먼저 할 수 있다?
뭐 그런식으로 이해하면 될 것 같은..
build phase순서가 잘못되면, 빌드 이슈 또는 실패가 발생할 수 있으니까!!
종속성을 이해하고, build phase가 올바른 순서인지 확인해야한다고 해요.
-
Scheme order dependencies - scheme setting에서 parallelize build 체크박스를 활성화하면
아까
저거 ㅇㅇ 그니까 ㅈㅓ parallelize build를 활성화하면(기본적으로 활성화되어있음)
더 나은 빌드 성능을 얻을 수 있으며, scheme target 순서는 중요하지 않다고 해요.
근데 parallelize build를 끄면 Xcode는!!! 나열된 순서대로 Target을 하나씩 빌드하려고 한대요.
Target dependencies는 아까 "Target이 빌드되는 순서를 대략적으로 결정함. "이라고 그랬죠?
Target dependencies에 뭐 나열되어있으면 빌드를 그 순서대로 하겠지만, 그렇지 않으면 Xcode는
이 순서를 respect한다고 하네요. 이 순서대로 빌드한다는 소리겠죠?
근데 그 순서가 이 순서 아녀?;;
....
암튼 WWDC에서 말하길
dependencies를 올바르게 설정하지 않은 경우에도 예측가능하게 빌드순서를 제공하기 때문에
(그니까 parallelize build끄면 순서대로 ㅎㅏ나씩 빌드한댔자나요 parallelize build를 끈 경우를 말하는거임)
parallelize build를 끄고싶을 수도 있음.
근데!! 이렇게 하면 많은 병렬 처리가 안되자나 그리고 당연히 빌드속도도 느려짐ㅎ
따라서
parallelize build를 활성화 하고
Target dependencies를 올바르게 설정하고
순서에 의존하지 않는것
이 좋다고 합니다.
마지막으로, dependency 정보는 니한테서 나옴
띠용;;;
custom shell script build phases 또는 build rules을 작성하는 경우,
빌드시스템에 input 및 output이 무엇인지 알려주셈
와;;;;
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ Run Script에 Input/Output file을 넣을 수 있는 란?이 있다는거 처음봄
맨날 스크립트 복붙하고......나왔는데...........
ㅋ...
암튼
이렇게 Input/Output을 알려주면 모가 좋음?
- 빌드시스템은 불필요하게 스크립트 작업을 재실행하지 않아도됨
- 올바른 순서로 실행되게 할 수 있음
이러한 파일의 경로는 스크립트에서 환경변수로 사용할 수 있게 됨.
그리고 auto-link에 대한 ㅇㅣ야기를 하는데 도저히 이해못하겠으므로 안쓰겠음!!ㅎㅋ
와 근데 너무 그러니까...
그러니까 정말 많이 본..그런 것들인데
이런 의미들을 알고나니까 재밌네요. :ㅇ
ㅎㅎ놀라운 사실은..
이 내용이 WWDC세션의 13분까지의 ㄴㅐ용입니다...
딱 2번째 목차까지 한것 같아요.
중간중간 이해 안되는 내용도 있긴한데,
계속 읽으면서 이해 해봐야겠어요 XD..
'공부' 카테고리의 다른 글
Xcode ) Custom File Template만들어보기 (1) | 2020.01.04 |
---|---|
Mac에서 Go 시작하기 - 설치와 설정 (0) | 2020.01.03 |
Mach-O (4) | 2019.12.06 |
Xcode canvas 살펴보기 (1) | 2019.12.05 |
SonarQube 삽질기 (2) | 2019.12.04 |
- FLUTTER
- 스위프트 문법
- IOS
- np-hard
- swift delegate
- swift sort
- WWDC
- github
- Accessibility
- 피아노
- iOS delegate
- 스위프트
- np-complete
- SwiftUI
- Swift
- ios 13
- Git
- swift array
- WKWebView
- swift3
- UIBezierPath
- swift tutorial
- Combine
- Xcode
- WidgetKit
- actor
- swift 공부
- 회고
- 제이슨 파싱
- fastlane
- Total
- Today
- Yesterday