Ccache makes compilation very fast because it caches previous compilations and detects when these are being recompiled. It is free software that supports C, C++, Objective-C and Objective-C++. It manages the cache size automatically, is an easy install and has low overheads.
The process of building large projects that have C/C++ sources is time-consuming. Packages such as the Linux kernel, OpenSSH and FFmpeg take a lot of time to build, making it an expensive process. We do have the ‘make’ utility to optimise the build process, but there are times when it is ineffective (like when we ‘make clean’ and build from scratch). So ‘make’ does not take care of such cases. Also, when we extract sources from a tarball, a rebuild happens every time we do so.
A rebuild of sources is inefficient if we have already built the same sources earlier. This duplication of work causes a waste of CPU resources and development time.
The solution is ccache, a persistent (on-disk) C/C++ compiler cache that achieves fast compilation. It is an open source tool to optimise the build process of source code. It supports C/C++ and the Objective-C/C++ languages.
The features of ccache are:
- Provides statistics on hits/misses
- Transparent usage
- No side-effects on compilation output
- Flexibility with cache size management
- Simple installation and usage
- Low overhead
How it works
Ccache keeps track of the compilation of the source code. It caches the compilation of a single C/C++/Obj-C/Obj-C++ file and reuses the compiled output instead of recompiling the same source file. It uses many pieces of information to keep track of the uniqueness of the compiled code such as:
- Source file name
- Compiler name
- Compiler size and modification time
- The current directory
- Command line options
Ccache maintains a persistent HashMap of the metadata and corresponding compiled code. Before compiling a source file, it checks its HashMap for the same file. It uses precompiled code whenever there is a match in the hash table. If it is a miss, ccache adds it to its hash.
Use the following code to install ccache:
$ sudo apt-get install ccache
There are two ways to use ccache:
1. You can either prefix your compilation commands with ccache, or…
2. Mask the compiler by creating a symbolic link (named as the compiler) to ccache.
Let’s use the second method on Ubuntu. We need to prefix /usr/lib/ccache to the PATH environment variable. Please run the following on bash shell.
The path /usr/lib/ccache contains symlinks for all the compilers currently installed as Debian packages.
On Ubuntu, you will see the following code:
$ cd /usr/lib/ccache/ $ ll total 24 drwxr-xr-x 2 root root 4096 May 2 13:33 ./ drwxr-xr-x 157 root root 20480 May 6 15:07 ../ lrwxrwxrwx 1 root root 16 May 2 13:33 c++ -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 c89-gcc -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 c99-gcc -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 cc -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 g++ -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 g++-5 -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 gcc -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 gcc-5 -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 x86_64-linux-gnu-g++ -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 x86_64-linux-gnu-g++-5 -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 x86_64-linux-gnu-gcc -> ../../bin/ccache* lrwxrwxrwx 1 root root 16 May 2 13:33 x86_64-linux-gnu-gcc-5 -> ../../bin/ccache*
After installing and updating PATH variable, let’s check the correctness of the compilers, as follows:
$ which gcc /usr/lib/ccache/gcc $ which g++ /usr/lib/ccache/g++
Let’s check ccache stats:
$ ccache -s cache directory /home/vkanaujia/.ccache primary config /home/vkanaujia/.ccache/ccache.conf secondary config (readonly) /etc/ccache.conf cache hit (direct) 0 cache hit (preprocessed) 0 cache miss 0 files in cache 0 cache size 0.0 kB max cache size 10.0 GB
It has stored the compiled output in the /home/vkanaujia/.ccache directory. We can configure ccache to store cached data in any place.
Let’s check ccache’s effectiveness with a sample compilation of FFmpeg code. FFmpeg is an open source library for video transcoding.
1. Download the FFmpeg source code.
$ wget http://ffmpeg.org/releases/ffmpeg-3.0.2.tar.bz2
2. Build it and time the build process.
$ bunzip2 ffmpeg-3.0.2.tar.bz2 $ tar xvf ffmpeg-3.0.2.tar $ cd ffmpeg-3.0.2/ $ time make real 12m18.544s user 10m34.876s sys 1m12.988s $ ccache -s cache directory /home/vkanaujia/.ccache primary config /home/vkanaujia/.ccache/ccache.conf secondary config (readonly) /etc/ccache.conf cache hit (direct) 0 cache hit (preprocessed) 0 cache miss 1507 called for link 4 files in cache 4538 cache size 239.6 MB max cache size 10.0 GB
3. Now, we will do a ‘clean’ to delete all compiled object files, as follows:
$ make clean
4. Let’s rebuild sources and time the ‘make’, as follows:
$ time make real 1m20.949s user 1m4.824s sys 0m5.924s
Here we see that with ccache, compilation is 800 per cent faster!
Vishal Kanaujia is Senior Software Engineer at Netapp, Bangalore, India. He is a shutterbug, and almost always carries his Canon camera.