Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
franneck94 committed Mar 10, 2024
1 parent 486f71d commit df49a4a
Show file tree
Hide file tree
Showing 25 changed files with 655 additions and 236 deletions.
24 changes: 14 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.21)
cmake_minimum_required(VERSION 3.22)

project(
"CTemplate"
Expand All @@ -12,6 +12,10 @@ set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Options
option(USE_CONAN "Whether to use Conan." OFF)
option(USE_VCPKG "Whether to use VCPKG." OFF)
option(USE_CPM "Whether to use CPM." ON)

option(ENABLE_WARNINGS "Enable to add warnings to a target." ON)
option(ENABLE_WARNINGS_AS_ERRORS "Enable to treat warnings as errors." OFF)

Expand All @@ -25,15 +29,12 @@ option(ENABLE_SANITIZE_UNDEF "Enable undefined sanitize." OFF)
option(ENABLE_SANITIZE_LEAK "Enable leak sanitize (Gcc/Clang only)." OFF)
option(ENABLE_SANITIZE_THREAD "Enable thread sanitize (Gcc/Clang only)." OFF)

option(ENABLE_CLANG_FORMAT "Enable to add clang-format." ON)
option(ENABLE_CMAKE_FORMAT "Enable to add cmake-format." ON)
option(ENABLE_CLANG_FORMAT "Enable to add clang-format." OFF)
option(ENABLE_CMAKE_FORMAT "Enable to add cmake-format." OFF)

option(ENABLE_LTO "Enable to add Link Time Optimization." ON)

# Project/Library Names
set(LIBRARY_NAME "lib")
set(UNIT_TEST_NAME "unit_tests")
set(EXECUTABLE_NAME "main")

# CMAKE MODULES
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/)
Expand Down Expand Up @@ -75,18 +76,21 @@ add_subdirectory(configured)
add_subdirectory(external)
add_subdirectory(src)
add_subdirectory(app)
add_subdirectory(tests)
if(ENABLE_TESTING)
include(CTest)
enable_testing()
add_subdirectory(tests)
endif()

# INSTALL TARGETS

install(
TARGETS ${EXECUTABLE_NAME}
EXPORT ${LIBRARY_NAME}
TARGETS "main"
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)

install(
TARGETS ${LIBRARY_NAME}
TARGETS "LibFoo" "LibBar"
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib)
31 changes: 16 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Template For C Projects

![C](https://img.shields.io/badge/C-89%2F99%2F11%2F17-blue)
![C++](https://img.shields.io/badge/C%2B%2B-11%2F14%2F17%2F20%2F23-blue)
![License](https://camo.githubusercontent.com/890acbdcb87868b382af9a4b1fac507b9659d9bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)
![Build CI Test](https://github.com/franneck94/CProjectTemplate/workflows/Ubuntu%20CI%20Test/badge.svg)
[![codecov](https://codecov.io/gh/franneck94/CProjectTemplate/branch/master/graph/badge.svg)](https://codecov.io/gh/franneck94/CProjectTemplate)
![Linux Build](https://github.com/franneck94/CppProjectTemplate/workflows/Ubuntu%20CI%20Test/badge.svg)

This is a template for C projects. What you get:
This is a template for C++ projects. What you get:

- Library, executable and test code separated in distinct folders.
- Use of modern CMake for building and compiling.
Expand All @@ -14,17 +13,17 @@ This is a template for C projects. What you get:
- General purpose libraries:
- [log](https://github.com/rxi/log.c)
- [argparse](https://github.com/cofyc/argparse)
- Continuous integration testing with Github Actions.
- Code coverage reports, including automatic upload to [Codecov](https://codecov.io).
- Continuous integration testing and coverage reports with Github Actions.
- Code documentation with [Doxygen](http://www.stack.nl/~dimitri/doxygen/).
- Tooling: Clang-Format, Cmake-Format, Clang-tidy, Sanitizers

## Structure

``` text
├── CMakeLists.txt
├── app
│ ├── CMakesLists.txt
│ └── main.c
│ └── main.cc
├── cmake
│ └── cmake modules
├── docs
Expand All @@ -33,10 +32,10 @@ This is a template for C projects. What you get:
├── external
│ ├── CMakesLists.txt
│ ├── ...
├── src/my_lib
├── src
│ ├── CMakesLists.txt
│ ├── my_lib.h
│ └── my_lib.c
│ ├── foo/
│ └── bar/
└── tests
├── CMakeLists.txt
└── main.c
Expand All @@ -46,18 +45,20 @@ Library code goes into [src/](src/), main program code in [app/](app) and tests

## Software Requirements

- CMake 3.16+
- CMake 3.21+
- GNU Makefile
- Doxygen
- MSVC 2017 (or higher), GCC 9 (or higher), Clang 9 (or higher)
- Code Coverage (only on GNU|Clang): lcov, gcovr
- Conan or VCPKG
- MSVC 2017 (or higher), G++9 (or higher), Clang++9 (or higher)
- Optional: Code Coverage (only on GNU|Clang): gcovr
- Optional: Makefile, Doxygen, Conan, VCPKG

## Building

First, clone this repo and do the preliminary work:

```shell
git clone --recursive https://github.com/franneck94/CProjectTemplate
git clone --recursive https://github.com/franneck94/CppProjectTemplate
make prepare
```

Expand Down Expand Up @@ -97,4 +98,4 @@ cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON ..
cmake --build . --config Debug --target coverage
```

For more info about CMake see [here](./CMakeGuide.md).
For more info about CMake see [here](./README_cmake.md).
162 changes: 162 additions & 0 deletions README_cmake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# CMake Tutorial

## Generating a Project

```bash
cmake [<options>] -S <path-to-source> -B <path-to-build>
```

Assuming that a CMakeLists.txt is in the root directory, you can generate a project like the following.

```bash
mkdir build
cd build
cmake -S .. -B . # Option 1
cmake .. # Option 2
```

Assuming that you have already built the CMake project, you can update the generated project.

```bash
cd build
cmake .
```

## Generator for GCC and Clang

```bash
cd build
cmake -S .. -B . -G "Unix Makefiles" # Option 1
cmake .. -G "Unix Makefiles" # Option 2
```

## Generator for MSVC

```bash
cd build
cmake -S .. -B . -G "Visual Studio 16 2019" # Option 1
cmake .. -G "Visual Studio 16 2019" # Option 2
```

## Specify the Build Type

Per default, the standard type is in most cases the debug type.
If you want to generate the project, for example, in release mode you have to set the build type.

```bash
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
```

## Passing Options

If you have set some options in the CMakeLists, you can pass values in the command line.

```bash
cd build
cmake -DMY_OPTION=[ON|OFF] ..
```

## Specify the Build Target (Option 1)

The standard build command would build all created targets within the CMakeLists.
If you want to build a specific target, you can do so.

```bash
cd build
cmake --build . --target ExternalLibraries_Executable
```

The target *ExternalLibraries_Executable* is just an example of a possible target name.
Note: All dependent targets will be built beforehand.

## Specify the Build Target (Option 2)

Besides setting the target within the cmake build command, you could also run the previously generated Makefile (from the generating step).
If you want to build the *ExternalLibraries_Executable*, you could do the following.

```bash
cd build
make ExternalLibraries_Executable
```

## Run the Executable

After generating the project and building a specific target you might want to run the executable.
In the default case, the executable is stored in *build/5_ExternalLibraries/app/ExternalLibraries_Executable*, assuming that you are building the project *5_ExternalLibraries* and the main file of the executable is in the *app* dir.

```bash
cd build
./bin/ExternalLibraries_Executable
```

## Different Linking Types

```cmake
target_link_libraries(A PUBLIC fmt)
target_link_libraries(B PRIVATE spdlog)
```

```cmake
target_link_libraries(C PUBLIC/PRIVATE A)
target_link_libraries(C PUBLIC/PRIVATE B)
```

### PUBLIC

When A links fmt as *PUBLIC*, it says that A uses fmt in its implementation, and fmt is also used in A's public API.
Hence, C can use fmt since it is part of the public API of A.

### PRIVATE

When B links spdlog as *PRIVATE*, it is saying that B uses spdlog in its
implementation, but spdlog is not used in any part of B's public API.

### INTERFACE

```cmake
add_library(D INTERFACE)
target_include_directories(D INTERFACE {CMAKE_CURRENT_SOURCE_DIR}/include)
```

In general, used for header-only libraries.

## Different Library Types

### Shared

Shared libraries reduce the amount of code that is duplicated in each program that makes use of the library, keeping the binaries small. It also allows you to replace the shared object with one that is functionally equivalent, without needing to recompile the program that makes use of it. Shared libraries will however have a small additional cost for the execution.

### Static

Static libraries increase the overall size of the binary, but it means that you don't need to carry along a copy of the library that is being used. As the code is connected at compile time there are not any additional run-time loading costs. The code is simply there.

## Cross Compilation with Toolchain Files

## ARM 32 Cross

```shell
cmake -B build_arm32 -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm32-cross-toolchain.cmake
cmake --build build_arm32 -j8
```

## ARM 32 Native

```shell
cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm32-native-toolchain.cmake
cmake --build build -j8
```

## x86 64 MingW

```shell
cmake -B build_mingw -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86-64-mingw-toolchain.cmake
cmake --build build_mingw -j8
```

## x86 64 Native

```shell
cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86-64-native-toolchain.cmake
cmake --build build -j8
```
69 changes: 69 additions & 0 deletions README_install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Software Installation

## How to install VCPKG

Official Link: <https://vcpkg.io/en/index.html>

```cmd
cd external
git clone https://github.com/Microsoft/vcpkg.git
.\vcpkg\bootstrap-vcpkg.bat # windows
./vcpkg/bootstrap-vcpkg.sh # Unix
```

## How to install the Conan Package Manager

Official installation guide is [here](https://docs.conan.io/2/).

The conan database is [here](https://conan.io/center/).

### Installation Steps

1. Install Python (3.7+)
2. Type ``pip install --user -U conan`` into the terminal
1. Unix: Append conan to the PATH by: ``source ~/.profile``
3. Run the conan command: ``conan``
4. conan profile detect --force
5. conan profile path default

## Formatter and Static Analyzer

### Tooling

Clang-Format: Formatting tool for your C/C++ code:

- Documentation for Clang-Format: [Link](https://clang.llvm.org/docs/ClangFormat.html)

Clang-Tidy: Static linting tool for your C/C++ code:

- Documentation for Clang-Tidy: [Link](https://clang.llvm.org/extra/clang-tidy/)

Cmake-Format:

```bash
pip install cmake-format # python 3.7+
```

### Install Clang Tools

It's included in the LLVM toolchain, but also installable by apt, brew, winget etc.

https://github.com/llvm/llvm-project/releases/tag/llvmorg-16.0.0

## Cross Compiler as an Example

### Install ARM Compiler on x86 64 Ubuntu

```shell
sudo apt update
sudo apt install libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi libncurses5-dev build-essential bison flex libssl-dev bc

sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
sudo apt install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi
```

### Install MingW Cross Compiler on x86 64 Ubuntu

```shell
sudo apt-get install mingw-w64
```
10 changes: 10 additions & 0 deletions README_tools.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Tools

To sum up all the tools we use:

- Compiler warnings: fast checks while compiling the code, for the all target.
- Clang-tidy, CppCheck: linters, can be manually run at any time after their specific targets are built.
- Sanitizers: shows memory leaks in runtime. Built with the all target.
- LTO: applies linking optimization in release mode. Automatically works at compile/linking time for all target
- Doxygen: generates HTML documentation. It can be run apart after build its specific target.
- Clang-format and Cmake-format: allows automatically format the code and CMake files. They can be run apart after build their specific targets.
Loading

0 comments on commit df49a4a

Please sign in to comment.