0% found this document useful (0 votes)
26 views46 pages

17 Ecosystem

Uploaded by

Kamalesh Pantra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views46 pages

17 Ecosystem

Uploaded by

Kamalesh Pantra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

Modern C++

Programming
16. C++ Ecosystem
Cmake and Other Tools

Federico Busato
2024-11-05
Table of Contents

1 CMake
ctest

2 Code Documentation
doxygen

3 Code Statistics
Count Lines of Code
Cyclomatic Complexity Analyzer

1/41
Table of Contents

4 Other Tools
Code Formatting - clang-format
Compiler Explorer
Code Transformation - CppInsights
AI-Powered Code Completion
Local Code Search - ugrep, ripgrep, hypergrep
Code Search Engine - searchcode, grep.app
Code Benchmarking - Quick-Bench
Font for Coding

2/41
CMake
CMake Overview

CMake is an open-source, cross-platform family of tools designed to build,


test and package software

CMake is used to control the software compilation process using simple platform and
compiler independent configuration files, and generate native Makefile/Ninja and
workspaces that can be used in the compiler environment of your choice
CMake features:
• Turing complete language (if/else, loops, functions, etc.)
• Multi-platform (Windows, Linux, etc.)
• Open-Source
• Generate: makefile, ninja, etc.
• Supported by many IDEs: Visual Studio, Clion, Eclipse, etc.
3/41
CMake Books

Professional CMake: A Practical Guide Modern CMake for C++ (2nd)


(14th) R. Świdziński, 2024
C. Scott, 2023

4/41
CMake - References

• 19 reasons why CMake is actually awesome

• An Introduction to Modern CMake

• Effective Modern CMake

• Awesome CMake

• Useful Variables

5/41
Install CMake

Using PPA repository

$ wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null |


gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
$ sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' # bionic, xenial
$ sudo apt update
$ sudo apt install cmake cmake-curses-gui

Using the installer or the pre-compiled binaries: cmake.org/download/

# download the last cmake package, e.g. cmake-x.y.z-linux-x86_64.sh


$ sudo sh cmake-x.y.z-linux-x86_64.sh

6/41
A Minimal Example

CMakeLists.txt:

project(my_project) # project name

add_executable(program program.cpp) # compile command

# we are in the project root dir


$ mkdir build # 'build' dir is needed for isolating temporary files
$ cd build
$ cmake .. # search for CMakeLists.txt directory
$ make # makefile automatically generated

Scanning dependencies of target program


[100%] Building CXX object CMakeFiles/out_program.dir/program.cpp.o
Linking CXX executable program
[100%] Built target program 7/41
Parameters and Message

CMakeLists.txt:
project(my_project)
add_executable(program program.cpp)

if (VAR)
message("VAR is set, NUM is ${NUM}")
else()
message(FATAL_ERROR "VAR is not set")
endif()

$ cmake ..
VAR is not set
$ cmake -DVAR=ON -DNUM=4 ..
VAR is set, NUM is 4
...
[100%] Built target program 8/41
Language Properties

project(my_project
DESCRIPTION "Hello World"
HOMEPAGE_URL "github.com/"
LANGUAGES CXX)

cmake_minimum_required(VERSION 3.15)

set(CMAKE_CXX_STANDARD 14) # force C++14


set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) # no compiler extensions

add_executable(program ${PROJECT_SOURCE_DIR}/program.cpp) #$
# PROJECT_SOURCE_DIR is the root directory of the project

9/41
Target Commands

add_executable(program) # also add_library(program)

target_include_directories(program
PUBLIC include/
PRIVATE src/)
# target_include_directories(program SYSTEM ...) for system headers

target_sources(program # best way for specifying


PRIVATE src/program1.cpp # program sources and headers
PRIVATE src/program2.cpp
PUBLIC include/header.hpp)

target_compile_definitions(program PRIVATE MY_MACRO=ABCEF)

target_compile_options(program PRIVATE -g)

target_link_libraries(program PRIVATE boost_lib)

target_link_options(program PRIVATE -s) 10/41


Build Types

project(my_project) # project name


cmake_minimum_required(VERSION 3.15) # minimum version

add_executable(program program.cpp)

if (CMAKE_BUILD_TYPE STREQUAL "Debug") # "Debug" mode


# cmake already adds "-g -O0"
message("DEBUG mode")
if (CMAKE_COMPILER_IS_GNUCXX) # if compiler is gcc
target_compile_options(program "-g3")
endif()
elseif (CMAKE_BUILD_TYPE STREQUAL "Release") # "Release" mode
message("RELEASE mode") # cmake already adds "-O3 -DNDEBUG"
endif()

$ cmake -DCMAKE_BUILD_TYPE=Debug ..

11/41
Custom Targets and File Managing

project(my_project)
add_executable(program)

add_custom_target(echo_target # makefile target name


COMMAND echo "Hello" # real command
COMMENT "Echo target")

# find all .cpp file in src/ directory


file(GLOB_RECURSE SRCS ${PROJECT_SOURCE_DIR}/src/*.cpp)
# compile all *.cpp file
target_sources(program PRIVATE ${SRCS}) # prefer the explicit file list instead

$ cmake ..
$ make echo_target

12/41
Local and Cached Variables

Cached variables can be reused across multiple runs, while local variables are only
visible in a single run. Cached FORCE variables can be modified only after the
initialization

project(my_project)

set(VAR1 "var1") # local variable


set(VAR2 "var2" CACHE STRING "Description1") # cached variable
set(VAR3 "var3" CACHE STRING "Description2" FORCE) # cached variable
option(OPT "This is an option" ON) # boolean cached variable
# same of var2
message(STATUS "${VAR1}, ${VAR2}, ${VAR3}, ${OPT}")

$ cmake .. # var1, var2, var3, ON


$ cmake -DVAR1=a -DVAR2=b -DVAR3=c -DOPT=d .. # var1, b, var3, d
13/41
Manage Cached Variables

$ ccmake . # or 'cmake-gui'

14/41
Find Packages

project(my_project) # project name


cmake_minimum_required(VERSION 3.15) # minimum version

add_executable(program program.cpp)
find_package(Boost 1.36.0 REQUIRED) # compile only if Boost library
# is found
if (Boost_FOUND)
target_include_directories("${PROJECT_SOURCE_DIR}/include" PUBLIC ${Boost_INCLUDE_DIRS})
else()
message(FATAL_ERROR "Boost Lib not found")
endif()

15/41
Compile Commands

Generate JSON compilation database (compile commands.json)


It contains the exact compiler calls for each file that are used by other tools

project(my_project)
cmake_minimum_required(VERSION 3.15)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # <--

add_executable(program program.cpp)

Change the C/C++ compiler:

CC=clang CXX=clang++ cmake ..

16/41
ctest 1/2

CTest is a testing tool (integrated in CMake) that can be used to automate updating,
configuring, building, testing, performing memory checking, performing coverage
project(my_project)
cmake_minimum_required(VERSION 3.5)
add_executable(program program.cpp)

enable_testing()

add_test(NAME Test1 # check if "program" returns 0


WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build
COMMAND ./program <args>) # command can be anything

add_test(NAME Test2 # check if "program" print "Correct"


WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/build
COMMAND ./program <args>)

set_tests_properties(Test2
PROPERTIES PASS_REGULAR_EXPRESSION "Correct") 17/41
ctest 2/2

Basic usage (call ctest):

$ make test # run all tests

ctest usage:

$ ctest -R Python # run all tests that contains 'Python' string


$ ctest -E Iron # run all tests that not contain 'Iron' string
$ ctest -I 3,5 # run tests from 3 to 5

Each ctest command can be combined with other tools (e.g. valgrind)

18/41
ctest with Different Compile Options

It is possible to combine a custom target with ctest to compile the same code with
different compile options

add_custom_target(program-compile
COMMAND mkdir -p test-release test-ubsan test-asan # create dirs
COMMAND cmake .. -B test-release # -B change working dir
COMMAND cmake .. -B test-ubsan -DUBSAN=ON
COMMAND cmake .. -B test-asan -DASAN=ON
COMMAND make -C test-release -j20 program # -C run make in a
COMMAND make -C test-ubsan -j20 program # different dir
COMMAND make -C test-asan -j20 program)

enable_testing()

add_test(NAME Program-Compile
COMMAND make program-compile)

19/41
CMake Alternatives - xmake

xmake is a cross-platform build utility based on


Lua.

Compared with makefile/CMakeLists.txt, the configuration syntax is more concise


and intuitive. It is very friendly to novices and can quickly get started in a short time.
Let users focus more on actual project development

Comparison: xmake vs cmake

20/41
Code
Documentation
doxygen 1/6

Doxygen is the de facto standard tool for generating documentation from annotated
C++ sources
Doxygen usage
• comment the code with /// or /** comment */
• generate doxygen base configuration file

$ doxygen -g

• modify the configuration file Doxyfile


• generate the documentation

$ doxygen <config_file>

21/41
doxygen 2/6

22/41
doxygen 3/6

Doxygen requires the following tags for generating the documentation:

• @file Document a file

• @brief Brief description for an entity

• @param Run-time parameter description

• @tparam Template parameter description

• @return Return value description

23/41
doxygen - Features 4/6

• Automatic cross references between functions, variables, etc.

• Specific highlight. Code `<code>` , input/output parameters


@param[in] <param>

• Latex/MathJax $<code>$

• Markdown (Markdown Cheatsheet link), Italic text *<code>* , bold text


**<code>** , table, list, etc.

• Call/Hierarchy graph can be useful in large projects (requires graphviz)


HAVE DOT = YES
GRAPHICAL HIERARCHY = YES
CALL GRAPH = YES
CALLER GRAPH = YES 24/41
doxygen - Example 5/6
/** /**
* @file * @brief "What the function does?"
* @copyright MyProject * @details "Some additional details",
* license BSD3, Apache, MIT, etc. * Latex/MathJax: $\sqrt a$
* @author MySelf * @tparam T Type of input and output
* @version v3.14159265359 * @param[in] input Input array
* @date March, 2018 * @param[out] output Output array
*/ * @return `true` if correct,
* `false` otherwise
/// @brief Namespace brief description * @remark it is *useful* if ...
namespace my_namespace { * @warning the behavior is **undefined** if
* @p input is `nullptr`
/// @brief "Class brief description" * @see related_function
/// @tparam R "Class template for" */
template<typename R> template<typename T>
class A { bool my_function(const T* input, T* output);

/// @brief
void related_function(); 25/41
doxygen - Call Graph 6/6

26/41
Doxygen Alternatives

M.CSS Doxygen C++ theme

Doxypress Doxygen fork

clang-doc LLVM tool

Sphinx Clear, Functional C++ Documentation with Sphinx + Breathe


+ Doxygen + CMake

standardese The nextgen Doxygen for C++ (experimental)

HDoc The modern documentation tool for C++ (alpha)

Adobe Hyde Utility to facilitate documenting C++


27/41
Code Statistics
Count Lines of Code - cloc

cloc counts blank lines, comment lines, and physical lines of source code in many
programming languages

$cloc my_project/

4076 text files.


3883 unique files.
1521 files ignored.

http://cloc.sourceforge.net v 1.50 T=12.0 s (209.2 files/s, 70472.1 lines/s)


-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C 135 18718 22862 140483
C/C++ Header 147 7650 12093 44042
Bourne Shell 116 3402 5789 36882

Features: filter by-file/language, SQL database, archive support, line count diff, etc. 28/41
Cyclomatic Complexity Analyzer - lyzard 1/3

Lizard is an extensible Cyclomatic Complexity Analyzer for many programming


languages including C/C++
Cyclomatic Complexity: is a software metric used to indicate the complexity of a program. It
is a quantitative measure of the number of linearly independent paths through a program
source code
$lizard my_project/
==============================================================
NLOC CCN token param function@line@file
--------------------------------------------------------------
10 2 29 2 start_new_player@26@./html_game.c
6 1 3 0 set_shutdown_flag@449@./httpd.c
24 3 61 1 server_main@454@./httpd.c
--------------------------------------------------------------

• CCN: cyclomatic complexity (should not exceed a threshold)


• NLOC: lines of code without comments
29/41
• token: Number of conditional statements
Cyclomatic Complexity Analyzer - lyzard 2/3

CCN = 3

30/41
Cyclomatic Complexity Analyzer - lyzard 3/3

CC Risk Evaluation
1-10 a simple program, without much risk
11-20 more complex, moderate risk
21-50 complex, high risk
> 50 untestable program, very high risk

CC Guidelines
1-5 The routine is probably fine
6-10 Start to think about ways to simplify the routine
> 10 Break part of the routine

Risk: Lizard: 15, OCLint: 10


• www.microsoftpressstore.com/store/code-complete-9780735619678
31/41
• blog.feabhas.com/2018/07/code-quality-cyclomatic-complexity
Other Tools
Code Formatting - clang-format

clang-format is a tool to automatically format C/C++ code (and other languages)

$ clang-format <file/directory>

clang-format searches the configuration file .clang-format file located in the


closest parent directory of the input file
clang-format example:
IndentWidth: 4
UseTab: Never
BreakBeforeBraces: Linux
ColumnLimit: 80
SortIncludes: true

32/41
Compiler Explorer (assembly and execution)

Compiler Explorer is an interactive tool that lets you type source code and see
assembly output, control flow graph, optimization hint, etc.

Key features: support multiple architectures and compilers


33/41
Code Transformation - CppInsights

CppInsights See what your compiler does behind the scenes

34/41
AI-Powered Code Completion 1/2

AI-Powered Code Completion tools help writing code faster by drawing context
from comments and code to suggest individual lines and whole functions
Common features:

• Semantic completion
• Recognize common language patterns
• Use the documentation to infer this function name, return type, and arguments
• Suggest bug fixes
• Generate comments, documentation, and even Pull Request text

35/41
AI-Powered Code Completion 2/2

They are commonly provided as plug-in for the most popular editors and IDE

• CoPilot
• TabNine
• Codeium
• Replit Ghostwriter
• CodeWhisperer

36/41
Local Code Search - ugrep, ripgrep, hypergrep

ugrep , Ripgrep , Hypergrep are code-searching-oriented tools for regex pattern


Features:
• Default recursively searches
• Skip .gitignore patterns, binary and hidden files/directories
• Windows, Linux, Mac OS support
• Up to 100x faster than GNU grep

37/41
Code Search Engine - searchcode

Searchcode is a free source code search engine


Features:
• Search over 20 billion lines of code from 7,000,000 projects
• Search sources: github, bitbucket, gitlab, google code, sourceforge, etc.

38/41
Code Search Engine - grep.app

grep.app searches across a half million GitHub repos

39/41
Code Benchmarking - Quick-Bench

Quick-benchmark is a micro benchmarking tool intended to quickly and simply


compare the performances of two or more code snippets. The benchmark runs on a
pool of AWS machines

40/41
Font for Coding

Many editors allow adding optimized fonts for programming which improve legibility
and provide extra symbols (ligatures)

Some examples:
• JetBrain Mono
• Fira Code
• Microsoft Cascadia
• Consolas Ligaturized
41/41

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy