Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*
!src
!interfaces
!src
!tests
!example
!cmake
!CMakeLists.txt
83 changes: 83 additions & 0 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake on multiple platforms

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
matrix:
os: [ubuntu-latest, windows-latest]
build_type: [Release]
c_compiler: [gcc, clang, cl]
include:
- os: windows-latest
c_compiler: cl
cpp_compiler: cl
- os: ubuntu-latest
c_compiler: gcc
cpp_compiler: g++
- os: ubuntu-latest
c_compiler: clang
cpp_compiler: clang++
exclude:
- os: windows-latest
c_compiler: gcc
- os: windows-latest
c_compiler: clang
- os: ubuntu-latest
c_compiler: cl

steps:
- uses: actions/checkout@v4

- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-S ${{ github.workspace }}

- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}

- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --build-config ${{ matrix.build_type }}

- name: Upload results to path
uses: actions/upload-artifact@v4
if: failure()
with:
name: error-log
path: ${{ steps.strings.outputs.build-output-dir }}/Testing/Temporary/LastTest.log
if-no-files-found: ignore
37 changes: 14 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,34 +1,25 @@
cmake_minimum_required(VERSION 3.3.2)
cmake_minimum_required(VERSION 3.5)
cmake_policy(SET CMP0077 NEW)

project(skeleton
VERSION 0.1
DESCRIPTION "skeleton c++ project template"
LANGUAGES CXX
)

include(CTest)
option(SKELETON_BUILD_TESTS "Build test program" ON)
option(SKELETON_BUILD_EXAMPLE "Build example" ON)

set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
# Build without tchar = wchar_t
set(UNICODE OFF CACHE INTERNAL "" FORCE)

include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)

# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory(src)

FetchContent_MakeAvailable(googletest)
if (SKELETON_BUILD_EXAMPLE)
add_subdirectory(example)
endif (SKELETON_BUILD_EXAMPLE)

#include(DownloadProject.cmake)
#download_project(PROJ googletest
# GIT_TAG release-1.10.0
# GIT_REPOSITORY https://github.com/google/googletest
# PREFIX .cmakeDownload
# BINARY_DIR ${CMAKE_BINARY_DIR}/googletest-build
# ${UPDATE_DISCONNECTED_IF_AVAILABLE}
#)
add_subdirectory(log4cplus)
add_subdirectory(src)
if (SKELETON_BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif (SKELETON_BUILD_TESTS)
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM ubuntu:22.04

RUN apt-get update
RUN apt-get install build-essential -y
RUN apt-get install cmake -y
RUN apt-get install git -y

LABEL org.opencontainers.image.title="Ubuntu cmake build" \
org.opencontainers.image.description="Build cmake based application" \
org.opencontainers.image.authors="@justtuomas"

# Create directory in container image for app code
RUN mkdir -p /usr/src/app/build

# Copy app code (..) to /usr/src/app in container image
COPY . /usr/src/app

# Set working directory context
WORKDIR /usr/src/app/build

RUN cmake ..

RUN cmake --build .
111 changes: 52 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,62 @@
# Preparations
This guideline was written on Ubuntu 20.04 TLS.
The example uses ~/build as the base path.
# cpp-skeleton
The initial purpose of this project was to produce working example of building a cpp application with logging (l0g4cplus).

## Required build tools
The cpp-skeleton application software requires cmake v3.3.2 to build.
During initial testing g++-10 compiler was used but the ubuntu default g++-9 should work just fine.
The future vision is to serve as a skeleton for cpp application with configurable modules.

Following is the list of tool identified reconstruct the build setup on stock ubuntu.
The modules could be something like:
</br>
SKELETON_USE_LOG4CPLUS
</br>
SKELETON_USE_SOMEMODULE

```bash
sudo apt-get update
sudo apt-get install autoconf autogen automake cmake curl git libtool g++ make unzip
```
### About Used DownloadProject
The https://github.com/Crascit/DownloadProject cmake files are used to download googletest at CMake's configure step.
## Build instructions
You can build any tool supporting digesting the `CMakeLists.txt` including vscode or vstudio but the workflow and configuration is tool specific.

And I quote from the repository README.md:
> The primary advantage of this is that the project's source code can then be included directly in the main CMake build using the add_subdirectory() command, making all of the external project's targets, etc. available without any further effort.
The following is the instructions on how to build using docker and ubuntu.
The ubuntu example is based on the docker build and is basically just overview of it.

## Build log4cplus (REL_2_1_0)
Opting to use version tagged `REL_2_1_0` as the master head version (3.0.0) requires a compiler with c++20 features and is a bit picky while at it.
For example the g++-10 (10.3) compiler accepts the flag -std=c++20 and __cplusplus evaluates to 201707L.
The log4cplus compiler test still fails while processing following version checking line.
```
#https://github.com/log4cplus/log4cplus/blob/d9521ad97ba781b8b97f5aa29b0f4476074db866/m4/ax_cxx_compile_stdcxx.m4#L990
#elif __cplusplus < 202002L && !defined _MSVER
```
#### Run the following commands:
```bash
mkdir -p ~/build/3rdparty && cd ~/build/3rdparty
git clone --branch REL_2_1_0 https://github.com/log4cplus/log4cplus.git
cd log4cplus
git submodule update --init --recursive
./configure
# running the make twice due to error on the first run
# configure.ac:453: error: possibly undefined macro: AC_CHECK_INCLUDES_DEFAULT
make -j4 || make -j4
sudo make install
sudo ldconfig
# verify installed
pkg-config --debug log4cplus
```
# Skeleton application and tests
### Downloading the source
```bash
mkdir -p ~/build/application-software && cd ~/build/application-software
## Preparations
This guideline was written on Windows 10.

### Required build tools
Docker installed.
[docker-windows](https://docs.docker.com/desktop/setup/install/windows-install/)
Git installed
[git-windows](https://git-scm.com/downloads/win)
#### Docker build and run example:
```shell
git clone https://github.com/head5man/cpp-skeleton.git
cd cpp-skeleton
# Build the image defined in ./Dockerfile
docker build -t build_image_name .
# Run container with interactive terminal
docker run -it --name=build_container_name build_image_name /bin/bash
# To run test executable
build_container_name:/usr/src/app/build# ./tests/skeleton-test
# To run application example
build_container_name:/usr/src/app/build# cd example && ./skeleton-example
# Exit and delete container and image
build_container_name:/usr/src/app/build# exit
docker rm build_container_name
docker rmi build_image_name
```
### Running the build:
```bash
mkdir -p build && cd build
cmake ..
make
```
### Running the application
```bash
#Run the skeleton executable
src/skeleton
```
### Running the tests

#### Ubuntu 22.04 build and run example
```bash
#Run the skeleton-test executable
src/skeleton-test
#Run CTest alternative reporting only module level results
make test
```
apt-get update
apt-get install build-essential -y
apt-get install cmake -y
apt-get install git -y

# Clone repository to home and build
cd ~
git clone https://github.com/head5man/cpp-skeleton.git
cmake -S cpp-skeleton -B cpp-skelton/build
cmake --build cpp-skeleton/build

# To run test executable
cpp-skeleton/build/tests/skeleton-test

# To run application example
cd cpp-skeleton/build/example && ./skeleton-example
```
19 changes: 19 additions & 0 deletions cmake/common.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
include(CMakePrintHelpers)

macro (print_target_properties NAME)
cmake_print_properties(
TARGETS ${NAME}
PROPERTIES ${ARGN}
)
endmacro()

macro(copy_target_runtime_dlls NAME)
add_custom_command(TARGET ${NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:${NAME}> $<TARGET_FILE_DIR:${NAME}>
COMMAND_EXPAND_LISTS
)
endmacro()

macro(silence_msvc_warnings NAME)
target_compile_definitions(${NAME} PRIVATE "" _CRT_SECURE_NO_WARNINGS)
endmacro()
22 changes: 22 additions & 0 deletions cmake/googletest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.5)

# A separate subdirectory for building Google Test so that C++ is not
# globally enabled

enable_language(CXX)

include(FetchContent)
set(FETCHCONTENT_QUIET FALSE)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.16.0
# URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)

set (BUILD_SHARED_LIBS FALSE)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS OFF)

FetchContent_MakeAvailable(googletest)
19 changes: 19 additions & 0 deletions cmake/log4cplus.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.5)

set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
set(LOG4CPLUS_BUILD_TESTING OFF CACHE INTERNAL "" FORCE)

include(FetchContent)

FetchContent_Declare(log4cplus
GIT_REPOSITORY https://github.com/log4cplus/log4cplus.git
GIT_TAG 2.1.x
GIT_PROGRESS TRUE
)

FetchContent_MakeAvailable(log4cplus)

print_target_properties(log4cplus::log4cplus
LINK_LIBRARIES
COMPILE_DEFINITIONS
)
41 changes: 41 additions & 0 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# cmake list called from root/CMakeLists.txt
# requires: skeleton-lib to be available
cmake_minimum_required(VERSION 3.5)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)

include(${CMAKE_CURRENT_LIST_DIR}/../cmake/common.cmake)

# TODO: relocate includes to appropriate folders
include_directories(${CMAKE_CURRENT_LIST_DIR}/.. ${CMAKE_CURRENT_LIST_DIR}/../src)

# create custom target copying the logger configuration
# to the binary folder
set (LOG_CONF "log.conf")
if (MSVC)
set (LOG_PFX "$<CONFIG>/")
endif()

set (TARGET_LOG_CONF "${LOG_PFX}${LOG_CONF}")

add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_LOG_CONF}"
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_LIST_DIR}/${LOG_CONF}" "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_LOG_CONF}"
DEPENDS "${CMAKE_CURRENT_LIST_DIR}/${LOG_CONF}"
)

add_custom_target(configuration ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_LOG_CONF}")

# skeleton example executable
add_executable(${PROJECT_NAME}-example ${CMAKE_CURRENT_LIST_DIR}/main.cpp)
silence_msvc_warnings(${PROJECT_NAME}-example)
target_include_directories(${PROJECT_NAME}-example PUBLIC ${log4cplus_SOURCE_DIR}/include)
target_link_libraries(${PROJECT_NAME}-example ${log4cplus} ${PROJECT_NAME}-lib)
if (MSVC)
copy_target_runtime_dlls(${PROJECT_NAME}-example)
endif()
print_target_properties(${PROJECT_NAME}-example COMPILE_DEFINITIONS)

cmake_print_variables(CMAKE_CURRENT_BINARY_DIR LOG_CONF TARGET_LOG_CONF)

Loading