Overview
이번 포스트에서는 Github Actions 을 이용한 Flutter CI/CD workflow에서 Ccache 를 적용하여 ios 빌드 성능을 개선하였던 내용에 대해서 다루고 있습니다.
1. 문제 인식
Ccache 를 적용하기 앞서서 먼저 아래 포스트를 참고하시면 좋을 것 같습니다.
위 포스트를 보면 iOS 빌드 속도를 줄이기 위해 firebase-prebuilt library를 사용하고 있었는데요 Firebase 버전을 최신으로 올리면서 해당 Library를 사용하게 되면 앱이 빌드가 안되는 문제가 발견되었습니다. 이 문제는 아직 수정이 되지 않고 있습니다. 해당 문제는 아래 링크를 참고하시면 좋을 것 같습니다.
any version 10.17.0 or higher: Error (Xcode): Undefined symbol
2. Local 환경에서 Ccache 적용
Ccache 는 C/C++ 컴파일러를 위한 캐시 시스템으로 컴파일된 오브젝트 파일을 캐시에 저장하여 다음 빌드 시에 재사용할 수 있도록 해줍니다. 이를 통해서 빌드 시간을 줄일 수 있습니다.
1. Ccache 설치
brew 를 통해서 Ccache 를 설치합니다.
brew install ccache
설치가 완료되면 아래 명령어를 통해서 Ccache 가 잘 설치되었는지 확인합니다.
ccache -V
2. 환경 변수 추가
.bashrc
, .bash_profile
나 .zshrc
파일에 아래와 같이 환경 변수를 추가합니다.
export PATH="/opt/homebrew/opt/ccache/libexec:$PATH"
3. 심볼릭 링크 걸기
아래와 같이 심볼릭 링크를 걸어줍니다.
ln -s $(which ccache) /usr/local/bin/gcc
ln -s $(which ccache) /usr/local/bin/g++
ln -s $(which ccache) /usr/local/bin/cc
ln -s $(which ccache) /usr/local/bin/c++
ln -s $(which ccache) /usr/local/bin/clang
ln -s $(which ccache) /usr/local/bin/clang++
4. 설정 확인
아래 명령어를 통해서 Ccache 설정이 잘 되었는지 확인합니다.
which gcc
정상적으로 설정이 되었다면 아래와 같이 출력이 됩니다.
which gcc
/opt/homebrew/opt/ccache/libexec/gcc
5. ios/Podfile 수정
ios/Podfile 에 아래와 같이 스크립트를 추가합니다.
...
post_install do |installer|
installer.generated_projects.each do |project|
project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings["CC"] = "clang"
config.build_settings["LD"] = "clang"
config.build_settings["CXX"] = "clang++"
config.build_settings["LDPLUSPLUS"] = "clang++"
end
end
end
6. 빌드 시간 측정
아래 명령어를 통해서 빌드 시간을 측정합니다.
flutter build ipa
첫 번째 빌드 시간은 아래와 같이 327,777ms 가 소요되었습니다. 그리고 ccache -s 명령어를 통해서 캐시 효율을 확인해보면 0% 입니다. 왜냐하면 첫 번째 빌드이기 때문에 아직 cache 가 생성되지 않았기 때문입니다.
"flutter ipa" took 327,777ms.
ccache -s
Cacheable calls: 2655 / 2655 (100.0%)
Hits: 0 / 2655 ( 0.00%)
Direct: 0
Preprocessed: 0
Misses: 2655 / 2655 (100.0%)
Local storage:
Cache size (GiB): 0.6 / 5.0 (11.18%)
Hits: 0 / 2655 ( 0.00%)
Misses: 2655 / 2655 (100.0%)
두 번째 빌드 시간은 아래와 같습니다.
"flutter ipa" took 130,970ms.
ccache -s
Cacheable calls: 5310 / 5310 (100.0%)
Hits: 2655 / 5310 (50.00%)
Direct: 2655 / 2655 (100.0%)
Preprocessed: 0 / 2655 ( 0.00%)
Misses: 2655 / 5310 (50.00%)
Local storage:
Cache size (GiB): 0.6 / 5.0 (11.18%)
Hits: 2655 / 5310 (50.00%)
Misses: 2655 / 5310 (50.00%)
시간이 절반으로 줄어들었습니다. 그리고 ccache -s 명령어를 통해서 캐시 효율을 확인해보면 50% 입니다. 즉, 캐시가 잘 생성되었다는 것을 알 수 있습니다. 50%인 이유는 두 번째 빌드 시에는 첫 번째 빌드 시에 생성된 캐시를 사용하기 때문입니다.
자 이제 Github Actions 에서 Ccache 를 적용해보도록 하겠습니다.
3. Github Actions 에서 Ccache 적용
1. 워크플로우 구성
- name: Update env // Ccache 환경 변수 추가
run: |
echo "/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" >> $GITHUB_PATH
echo "CCACHE_SLOPPINESS=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros" >> $GITHUB_ENV
echo "CCACHE_FILECLONE=true" >> $GITHUB_ENV
echo "CCACHE_DEPEND=true" >> $GITHUB_ENV
echo "CCACHE_INODECACHE=true" >> $GITHUB_ENV
- name: Install Ccache // Ccache 설치
uses: hendrikmuhs/ccache-action@v1.2
with:
key: $-v2
max-size: 5G
- name: Build ipa // 빌드
run: flutter build ipa
2. 확인
workflow 를 실행하면 최초 빌드 시 캐시가 없기 때문에 시간이 오래 걸리지만 두 번째 빌드 시에는 캐시를 사용함으로써 빌드 시간이 단축되었습니다. 그리고 workflow 의 출력을 통해 Ccahe의 캐시 효율을 확인해볼수 있습니다.
3. 결과
Ccache 를 적용한 결과 빌드 시간은 약간 유동적이긴 하지만 분명히 빌드 시간을 크게 줄이는 데 성공했습니다.
댓글남기기