Skip to content

How to use this project as a template

d-e-e-p edited this page Apr 19, 2023 · 8 revisions

Lets say our new project is called facto and we're going to define a class that computes factorial of small integers.

[] Step0 : Replicate!

Clone or fork fixed-size-string-buffer and first validate that without any modifications make all works. You might have to get your environment to resemble one of the Windows/Ubuntu or MacOS runners. See runner supported software.

gh repo fork --clone --fork-name facto https://github.com/d-e-e-p/fixed-size-string-buffer
cd facto
make all

Making any change and running git push will run the actions using .github/workflows/ci.yml. Results from ci.yml should be checked after every step below.

[] Step1 : Create examples/include files

  • Edit cmake/common.cmake with updated project name and version.
  • Add factorial.h, factorial.cpp and demo.cpp to look something like:
  • No change is needed in examples/CMakeLists.txt if libraries don't have external dependencies.
  • No change is needed in Makefile if one of the standalone examples is still called demo.cpp.
├── Makefile
├── cmake
│   └── common.cmake ├── include │   └── lmath │   └── factorial.h ├── src
│   └── lmath │   └── factorial.cpp └── examples . ├── CMakeLists.txt . └── src . └── main.cpp

if demo.cpp needs external libraries, they need to be found and added to CMakeLists.txt using find_package or CPMAddPackage After these changes, make debug should produce something like:

> make debug
rm -rf ./build/debug/CMakeCache.txt
cmake -S examples -B build/debug -DCMAKE_BUILD_TYPE=Debug
...
-- enable_sanitizers: adding flags -fsanitize=address;-fsanitize-address-use-after-scope;-fsanitize=undefined;-fsanitize=integer;-fsanitize=nullability
-- enable_warnings: adding compiler flags -Wall;-Wextra;-Wshadow;-Wnon-virtual-dtor;-Wold-style-cast;-Wcast-align;-Wunused;-Woverloaded-virtual;-Wpedantic;-Wconversion;-Wsign-conversion;-Wnull-dereference;-Wdouble-promotion;-Wformat=2;-Wno-narrowing
--  enable_analyzers: clang-tidy -extra-arg=-Wno-unknown-warning-option;-extra-arg=-std=c++17
--  enable_analyzers: cppcheck --suppress=missingInclude;--enable=all;--inline-suppr;--inconclusive;--std=c++17
--  enable_analyzers: cpplint
--  enable_analyzers: include-what-you-use -Xiwyu;--cxx17ns;-Xiwyu;--no_fwd_decls;-Xiwyu;--max_line_length=132;-Xiwyu;--verbose=1
--  adding lib factorial from /U/d/facto/examples/../src/lmath/factorial.cpp
--  adding exe demo from /U/d/facto/examples/src/demo.cpp
-- Configuring done
-- Generating done
...
Checking /U/d/facto/examples/src/demo.cpp ...
/U/d/facto/examples/src/demo.cpp:12:13: warning: use of old-style cast [-Wold-style-cast]
      num = (uint32_t) atoi(argv[1]);
            ^          ~~~~~~~~~~~~~
1 warning generated.
[100%] Linking CXX executable bin/demo
[100%] Built target demo
./build/debug/bin/demo
max int is: 2147483647
 0! = 1
 1! = 1
 2! = 2
...

[] Step2 : Build testbench

Lets use Catch2 instead of GoogleTest for running the testbench. Setup the test dir to look like this, including the changes in these 2 files:

└── test
.   ├── CMakeLists.txt
.   └── src
.       └── 010-TestCase.cpp

Really the only lines that need alterations in CMakeLists.txt are:

CPMAddPackage("gh:catchorg/[email protected]")
...
target_link_libraries(${PROJECT_NAME} Catch2::Catch2WithMain ${libs})

make test should pass with something like:

1: ===============================================================================
1: All tests passed (5 assertions in 2 test cases)
1:
1/1 Test #1: tests ............................   Passed    0.15 sec

[] Step3 : Run benchmark

Again, just for variety, Catch2 is used for benchmarking. this requires a small change in Makefile where the unit_bench command has to be given name of test to run, eg unit_bench "*" runs all tests.

boost is commented out as requirement as in CMakeLists.txt :

├── bench
│   ├── CMakeLists.txt
│   └── src
│       └── bench_fib.cpp

make bench should spit out something like:

./build/bench/bin/unit_bench "*"
Filters: "*"
Randomness seeded to: 737927885

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
unit_bench is a Catch2 v3.3.2 host application.
Run with -? for options

-------------------------------------------------------------------------------
Benchmark Fibonacci
-------------------------------------------------------------------------------
/U/d/f.wiki/bench/src/bench_fib.cpp:10
...............................................................................

benchmark name                       samples       iterations    estimated
                                     mean          low mean      high mean
                                     std dev       low std dev   high std dev
-------------------------------------------------------------------------------
fibonacci 10                                   100         54645          0 ns
                                       0.310592 ns   0.310278 ns   0.311217 ns
                                     0.00217671 ns 0.00129762 ns 0.00369103 ns

...

[] Step4 : Run Coverage

make coverage should run correctly using test infrastructure to produce:

Directory        Line Coverage      Functions coverage
include/lmath	 100.0 %	2 / 2	100.0 %	1 / 1 
test/src	     100.0 %	9 / 9	100.0 %	4 / 4

Good luck getting that on a real project.

[] Step5: Setup cmake install process

Update install/CMakeLists.txt with any dependencies and run make install

For a header-only or static library there are no changes needed: see PackageProject.cmake for all the settings.

[] Step6: Validate install

create a simple example and remove some checkout stuff from CMakeLists.txt to resemble:

validate/
├── CMakeLists.txt
└── src
.   └── basic_example.cpp

Running make validate runs this basic_example.cpp against the library installed by make install.

[] Step7: Generate Documentation

Update 'CMakeLists.txt' with project info. You might have to change last line of Doxyfile from M_SHOW_UNDOCUMENTED = NO to M_SHOW_UNDOCUMENTED = YES to see all the files that don't have the special \\\ @ type tags.

docs/
├── CMakeLists.txt
├── Doxyfile
├── conf.py
└── pages
.   └── about.dox

[] Step8: Modify dot files

There are some dot files in the project that help with error detection and formatting:

You might have to modify them to supress false warnings.

[] The End