In this example, we will walk through a simple C++ app that uses CMake.
Let's assume our code is structured as follows:
.├── Earthfile└── src├── CMakeLists.txt├── fib.cpp├── fib.h└── main.cpp
Our program will be split between two different cpp files; the main.cpp file:
#include <iostream>#include "fib.h"int main(int argc, char *argv[]) {for( int i = 0; i < 5; i++ ) {std::cout << "fib(" << i << ") = " << fib(i) << std::endl;}return 0;}
and a file containing our fibonacci function:
#include "fib.h"int fib(int n){if( n <= 0 ) {return 0;}if( n == 1 ) {return 1;}return fib(n-1) + fib(n-2);}
We will use CMake to manage the build process of the c++ code, with the following CMakeList.txt file:
cmake_minimum_required(VERSION 2.8.9)project (fibonacci)add_executable(fibonacci main.cpp fib.cpp)
CMake caches object files under CMakeFiles which allows CMake to only recompile objects when the corresponding source code changes. We will use a mount-based cache to cache these temporary files to allow for faster builds on a local machine. Here's a sample Earthfile
:
# EarthfileFROM ubuntu:20.10# configure apt to be noninteractiveENV DEBIAN_FRONTEND noninteractiveENV DEBCONF_NONINTERACTIVE_SEEN true# install dependenciesRUN apt-get update && apt-get install -y build-essential cmakeWORKDIR /codecode:COPY src srcbuild:FROM +codeRUN cmake src# cache cmake temp files to prevent rebuilding .o files# when the .cpp files don't changeRUN --mount=type=cache,target=/code/CMakeFiles makeSAVE ARTIFACT fibonacci AS LOCAL fibonaccidocker:COPY +build/fibonacci /bin/fibonacciENTRYPOINT ["/bin/fibonacci"]SAVE IMAGE --push earthly/examples:cpp
If you run earthly +build
for the first time you should see:
...+build | Scanning dependencies of target fibonacci+build | [ 33%] Building CXX object CMakeFiles/fibonacci.dir/main.cpp.o+build | [ 66%] Building CXX object CMakeFiles/fibonacci.dir/fib.cpp.o+build | [100%] Linking CXX executable fibonacci+build | [100%] Built target fibonacci...
However on the next run since the object files were cached you should only see
...+build | Scanning dependencies of target fibonacci+build | [100%] Linking CXX executable fibonacci+build | [100%] Built target fibonacci...
If you need to force a full rebuild, you can run earthly --no-cache +build
to trigger a clean build; however this will also rebuild the entire base docker images.
And finally, the fibonacci program can be run via docker:
~/workspace/earthly/examples/cpp ❯ docker run --rm earthly/examples:cppfib(0) = 0fib(1) = 1fib(2) = 1fib(3) = 2fib(4) = 3
For the complete code see the examples/cpp GitHub directory.