Edk2 compiler cache enabling steps on Linux - shijunjing/edk2 GitHub Wiki
https://ccache.samba.org/. Clean build performance can be improved 60+% and even more!
GCC and CLANG support, based on ccache:Fit for both individual and CI (continue integration) build usage scenario
Useful links
- https://software.intel.com/en-us/articles/accelerating-compilation-part-1-ccache
- https://ccache.samba.org/
- https://github.com/ccache/ccache/blob/master/doc/INSTALL.md
Other Academic solution
- USENIX ATC'17 Best paper: https://www.usenix.org/conference/atc17/technical-sessions/presentation/dietrich
Build ccache
- Download source and build latest ccache-3.5:
-
$ wget ccache-3.5 source https://www.samba.org/ftp/ccache/ccache-3.5.tar.bz2
-
$ tar -xf ccache-3.5.tar.bz2
-
$ cd ccache-3.5
-
$ sudo apt-get install autoconf gperf asciidoc
-
$ ./autogen.sh
-
$ ./configure
-
$ make
-
$ sudo make install (optional)
You can also directly install ccache from your OS distribution
-
$ sudo apt-get install ccache
- Create edk2 build tool bin symbolic links in ccache build folder and map compiler to ccache
-
$ cd ccache-3.5
-
$ ln -s ccache gcc
-
$ ln -s ccache g++
-
$ ln -s ccache clang
-
$ ln -s ccache clang++
-
$ ln -s /usr/bin/objcopy objcopy (check your local path, if you build&install compiler by yourself, you might need ln -s /usr/local/bin/objcopy objcopy. Same for below tool bins)
-
$ ln -s /usr/bin/gcc-ar gcc-ar
-
$ ln -s /usr/bin/ar ar
-
$ ln -s /usr/bin/llvm-ar llvm-ar
- Set edk2 build bin path to ccache build folder. Below is my example. Then build edk2 as normal.
- export CLANG38_BIN=~/wksp_efi/ccache/ccache-3.5/
- export GCC5_BIN=~/wksp_efi/ccache/ccache-3.5/
- export GCC49_BIN=~/wksp_efi/ccache/ccache-3.5/
Frequently asked questions
Does ccache support Compiling In Different Directories and share the same cache for the different directories?
Yes. You can specify a "base directory" by setting the CCACHE_BASEDIR variable to an absolute path to the directory. ccache will then rewrite absolute paths that are under the base directory (i.e., paths that have the base directory as a prefix) to relative paths when constructing the hash. More details see the "Compiling In Different Directories" section in https://linux.die.net/man/1/ccache
Can a group of developers share the cache directory to each other?
Yes. A group of developers can increase the cache hit rate by sharing a cache directory. To share a cache without unpleasant side effects, the following conditions should to be met.More details see the "Sharing A Cache" section in https://linux.die.net/man/1/ccache
- Use the same CCACHE_DIR environment variable setting.
- Unset the CCACHE_HARDLINK environment variable.
- Make sure everyone sets the CCACHE_UMASK environment variable to 002. This ensures that cached files are accessible to everyone in the group.
- Make sure that all users have write permission in the entire cache directory (and that you trust all users of the shared cache).
- Make sure that the setgid bit is set on all directories in the cache. This tells the filesystem to inherit group ownership for new directories. The command "find $CCACHE_DIR -type d | xargs chmod g+s" might be useful for this.
Does ccache support to set different cache folder for different project?
Yes. The CCACHE_DIR environment variable specifies where ccache will keep its cached compiler output. The default is $HOME/.ccache.
Does ccache support to set different maximum size of the files stored in the cache?
Yes. Set option -M, --max-size=SIZE is to set the maximum size of the files stored in the cache. You can specify a value in gigabytes, megabytes or kilobytes by appending a G, M or K to the value.
Build performance data (Build 5 times for every platform, first is ccache disabled, others are ccache enabled.)
CLANG38+NOOPT
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b NOOPT -n 5
- real 1m33.076s
- user 3m12.913s
- sys 0m37.689s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b NOOPT -n 5
- real 2m2.072s
- user 4m4.150s
- sys 0m58.894s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b NOOPT -n 5
- real 0m31.758s
- user 0m39.712s
- sys 0m13.123s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b NOOPT -n 5
- real 0m33.002s
- user 0m39.591s
- sys 0m13.335s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b NOOPT -n 5
- real 0m31.718s
- user 0m39.512s
- sys 0m13.362s
CLANG38+DEBUG
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b DEBUG -n 5
- real 2m2.667s
- user 5m57.243s
- sys 0m39.721s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b DEBUG -n 5
- real 2m27.909s
- user 6m36.979s
- sys 0m57.632s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b DEBUG -n 5
- real 0m59.107s
- user 2m28.691s
- sys 0m14.924s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b DEBUG -n 5
- real 1m2.329s
- user 2m32.836s
- sys 0m15.145s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b DEBUG -n 5
- real 0m58.419s
- user 2m31.057s
- sys 0m14.991s
CLANG38+RELEASE
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b RELEASE -n 5
- real 2m1.673s
- user 5m30.296s
- sys 0m39.266s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b RELEASE -n 5
- real 2m27.049s
- user 6m12.606s
- sys 1m0.264s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b RELEASE -n 5
- real 0m53.605s
- user 2m4.319s
- sys 0m15.554s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b RELEASE -n 5
- real 0m51.757s
- user 2m4.821s
- sys 0m15.136s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t CLANG38 -a IA32 -a X64 -b RELEASE -n 5
- real 0m55.083s
- user 2m10.031s
- sys 0m15.622s
GCC5+NOOPT
- export CCACHE_DISABLE=1
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b NOOPT -n 5
- real 1m35.062s
- user 3m57.638s
- sys 0m30.266s
- export -n CCACHE_DISABLE
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b NOOPT -n 5
- real 2m1.809s
- user 4m56.289s
- sys 0m41.580s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b NOOPT -n 5
- real 0m32.727s
- user 0m37.567s
- sys 0m12.200s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b NOOPT -n 5
- real 0m32.511s
- user 0m37.323s
- sys 0m11.907s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b NOOPT -n 5
- real 0m31.636s
- user 0m37.591s
- sys 0m11.718s
GCC5+DEBUG
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b DEBUG -n 5
- real 2m56.388s
- user 9m30.974s
- sys 0m42.456s
- export -n CCACHE_DISABLE // enable ccache
- ccache -C // clear the cache completely
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b DEBUG -n 5
- real 3m25.597s
- user 10m54.142s
- sys 0m56.322s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b DEBUG -n 5
- real 1m49.702s
- user 5m38.929s
- sys 0m22.409s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b DEBUG -n 5
- real 1m39.818s
- user 5m4.784s
- sys 0m20.968s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b DEBUG -n 5
- real 1m41.136s
- user 5m4.463s
- sys 0m20.925s
GCC5+RELEASE
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b RELEASE -n 5
- real 2m26.923s
- user 7m41.147s
- sys 0m39.726s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b RELEASE -n 5
- real 2m37.894s
- user 8m17.724s
- sys 0m50.524s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b RELEASE -n 5
- real 1m28.608s
- user 4m15.156s
- sys 0m21.183s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b RELEASE -n 5
- real 1m29.328s
- user 4m19.114s
- sys 0m21.348s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC5 -a IA32 -a X64 -b RELEASE -n 5
- real 1m33.035s
- user 4m25.023s
- sys 0m21.752s
GCC49+DEBUG
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b DEBUG -n 5
- real 2m40.643s
- user 7m59.878s
- sys 0m33.698s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b DEBUG -n 5
- real 3m7.480s
- user 9m0.065s
- sys 0m45.559s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b DEBUG -n 5
- real 0m34.040s
- user 0m37.513s
- sys 0m12.291s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b DEBUG -n 5
- real 0m33.151s
- user 0m38.046s
- sys 0m12.518s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b DEBUG -n 5
- real 0m33.084s
- user 0m37.719s
- sys 0m12.602s
GCC49+RELEASE
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b RELEASE -n 5
- real 2m26.955s
- user 7m19.728s
- sys 0m33.801s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b RELEASE -n 5
- real 3m0.185s
- user 8m17.908s
- sys 0m45.666s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b RELEASE -n 5
- real 0m31.884s
- user 0m36.345s
- sys 0m11.683s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b RELEASE -n 5
- real 0m33.044s
- user 0m36.137s
- sys 0m11.900s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b RELEASE -n 5
- real 0m32.632s
- user 0m36.281s
- sys 0m11.774s
GCC49+NOOPT
- export CCACHE_DISABLE=1 // disable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b NOOPT -n 5
- real 1m36.715s
- user 4m5.113s
- sys 0m30.563s
- export -n CCACHE_DISABLE
- ccache -C // clear the cache completely
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b NOOPT -n 5
- real 2m3.280s
- user 4m55.942s
- sys 0m41.884s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b NOOPT -n 5
- real 0m33.510s
- user 0m37.192s
- sys 0m11.953s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b NOOPT -n 5
- real 0m33.033s
- user 0m37.074s
- sys 0m12.325s
- export -n CCACHE_DISABLE // enable ccache
- rm Build -r
- time build -p OvmfPkg/OvmfPkgIa32X64.dsc -t GCC49 -a IA32 -a X64 -b NOOPT -n 5
- real 0m34.066s
- user 0m37.381s
- sys 0m11.759s