Exercise Setup
Use GCC 16
Since we’re using some of the latest features of C++, we use the most recent (released) compiler.
This should get you there:
module load gcc/16on
lxplus9.cern.chsource /cvmfs/sft.cern.ch/lcg/contrib/gcc/16.1.0/x86_64-el9/setup.shTo persist this setup for every login, add the file
.bashrc.d/gcc16on lxplus with the same command as above:source /cvmfs/sft.cern.ch/lcg/contrib/gcc/16.1.0/x86_64-el9/setup.shThe default compiler (GCC) on the system comes from the distribution’s package manager. Likewise, the standard library (libstdc++) provided by the distribution matches that GCC version. Note that GCC 16 automatically builds against the libstdc++ headers it ships.
If you need to install GCC 16
Maybe my gcc16 docker image works for you
If you want to build it quicker add
--disable-bootstrapto the GCCconfigureflags.cd $src git clone --depth 1 --single-branch --branch releases/gcc-16 \ git://gcc.gnu.org/git/gcc cd gcc ./contrib/download_prerequisites mkdir build cd build ../configure --prefix=$prefix/gcc16 --enable-languages=c++ --disable-multilib make -j $CMAKE_BUILD_PARALLEL_LEVEL make install export CC=$prefix/gcc16/bin/gcc export CXX=$prefix/gcc16/bin/g++
Set up git and cmake
mkdir -p ~/src/exercises cd ~/src/exercises git initOpen `CMakeLists.txt in your editor and add:
cmake_minimum_required(VERSION 3.30) project(Exercises)Next we’ll set up a dependency to Google Benchmark:
find_package(benchmark 1.9 REQUIRED)In a terminal try
cmake -B build -G NinjaThis fails, since it can’t find the required benchmark library. Instead of installing it, we now use CMake’s
FetchContentto get it automatically and contained in our project. (Note the change fromREQUIREDtoQUIET.)find_package(benchmark 1.9 QUIET) if (NOT benchmark_FOUND) include(FetchContent) FetchContent_Declare( benchmark GIT_REPOSITORY https://github.com/google/benchmark GIT_TAG main) option(BENCHMARK_ENABLE_TESTING "" OFF) option(BENCHMARK_ENABLE_GTEST_TESTS "" OFF) option(BENCHMARK_ENABLE_LIBPFM "" ON) # for performance counters FetchContent_MakeAvailable(benchmark) endif()
Turn on C++26 features
set(CMAKE_CXX_STANDARD 26) set(CMAKE_CXX_STANDARD_REQUIRED ON)
Run the above cmake command again.
Commit to git.
Change the cmake configuration.
Use
ccmaketo see all options:ccmake buildThe key
ttoggles “advanced mode”. If you turn it on, you will see the compiler flags used for the different build modes. We only care aboutCXX_FLAGSvariables.For now, change
CMAKE_CXX_FLAGS_RELEASEto-O2 -DNDEBUGandCMAKE_CXX_FLAGS_RELWITHDEBINFOto-Og -g -DNDEBUG -fhardened.Note that you still need to configure (press
c) and generate (pressg).Also, if this is the setup you want to persist between different build dirs (figure out what you really want, first, though), add these flags to the
CMakeLists.txtrather than callingccmakeevery time.
Why
-O2rather than-O3I am very unhappy about the cmake default. Consider this quote from a GCC developer: “
-O2means ‘optimise well’.-O3means ‘throw everything at it, it may be slower as well, but almost certainlly is way too big’”Defaulting to
-O3is premature optimization, IMHO. Measure, and then decide whether-O3actually helps. Use it only if it measurably improves your program.
Compiler flags
Feel free to experiment with different compiler flags.
Verify with a dummy executable.
Add a
test.cppwith:#include <benchmark/benchmark.h> int main() { }Register with cmake in
CMakeLists.txt:add_executable(test test.cpp) target_link_libraries(test PRIVATE benchmark::benchmark)Build either with
cmake --build buildor
cd build ninja
Optional: Improve LSP support
If you use
clangdas an LSP, add a.clangdfile that points to GCC 16’s libstdc++:CompileFlags: Add: - --gcc-toolchain=/path/to/gcc-16And add
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)toCMakeLists.txt.That way CMake will generate
compile_commands.jsonfile, andclangdknows exactly how to compile your code as you go.(I use the
aleplugin forvim.)