C++ Meson Library Project
This commit is contained in:
7
.devcontainer/.bashrc
Normal file
7
.devcontainer/.bashrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;91m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
|
||||||
|
umask 022
|
||||||
|
export LS_OPTIONS='--color=auto'
|
||||||
|
eval "`dircolors`"
|
||||||
|
alias ls='ls $LS_OPTIONS'
|
||||||
9
.devcontainer/Dockerfile
Normal file
9
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM debian:buster
|
||||||
|
|
||||||
|
RUN apt update && apt install -y build-essential crossbuild-essential-amd64 crossbuild-essential-armhf mingw-w64 \
|
||||||
|
python3 python3-pip python3-setuptools python3-wheel ninja-build \
|
||||||
|
wget cmake xxd valgrind gcovr lcov git cppcheck gdb \
|
||||||
|
&& pip3 install meson
|
||||||
|
|
||||||
|
COPY meson /usr/local/share/meson
|
||||||
|
COPY .bashrc /root/.bashrc
|
||||||
18
.devcontainer/devcontainer.json
Normal file
18
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "C++",
|
||||||
|
"dockerFile": "Dockerfile",
|
||||||
|
|
||||||
|
"runArgs": [
|
||||||
|
"--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"
|
||||||
|
],
|
||||||
|
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.shell.linux": "/bin/bash"
|
||||||
|
},
|
||||||
|
|
||||||
|
"extensions": [
|
||||||
|
"ms-vscode.cpptools",
|
||||||
|
"yzhang.markdown-all-in-one",
|
||||||
|
"asabil.meson"
|
||||||
|
]
|
||||||
|
}
|
||||||
11
.devcontainer/meson/cross/arm-linux-gnueabihf
Normal file
11
.devcontainer/meson/cross/arm-linux-gnueabihf
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[binaries]
|
||||||
|
c = 'arm-linux-gnueabihf-gcc'
|
||||||
|
cpp = 'arm-linux-gnueabihf-g++'
|
||||||
|
ar = 'arm-linux-gnueabihf-ar'
|
||||||
|
strip = 'arm-linux-gnueabihf-strip'
|
||||||
|
|
||||||
|
[host_machine]
|
||||||
|
system = 'linux'
|
||||||
|
cpu_family = 'arm'
|
||||||
|
cpu = 'armv7'
|
||||||
|
endian = 'little'
|
||||||
12
.devcontainer/meson/cross/x86_64
Normal file
12
.devcontainer/meson/cross/x86_64
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[binaries]
|
||||||
|
c = 'x86_64-linux-gnu-gcc'
|
||||||
|
cpp = 'x86_64-linux-gnu-g++'
|
||||||
|
ar = 'x86_64-linux-gnu-ar'
|
||||||
|
strip = 'x86_64-linux-gnu-strip'
|
||||||
|
pkgconfig = 'x86_64-linux-gnu-pkg-config'
|
||||||
|
|
||||||
|
[host_machine]
|
||||||
|
system = 'linux'
|
||||||
|
cpu_family = 'x86_64'
|
||||||
|
cpu = 'x86_64'
|
||||||
|
endian = 'little'
|
||||||
11
.devcontainer/meson/cross/x86_64-alpine-linux-musl
Normal file
11
.devcontainer/meson/cross/x86_64-alpine-linux-musl
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[binaries]
|
||||||
|
c = '/usr/bin/x86_64-alpine-linux-musl-gcc'
|
||||||
|
cpp = '/usr/bin/x86_64-alpine-linux-musl-g++'
|
||||||
|
ar = '/usr/bin/x86_64-alpine-linux-musl-gcc-ar'
|
||||||
|
strip = '/usr/bin/x86_64-alpine-linux-musl-strip'
|
||||||
|
|
||||||
|
[host_machine]
|
||||||
|
system = 'linux'
|
||||||
|
cpu_family = 'x86_64'
|
||||||
|
cpu = 'x86_64'
|
||||||
|
endian = 'little'
|
||||||
12
.devcontainer/meson/cross/x86_64-linux-gnu
Normal file
12
.devcontainer/meson/cross/x86_64-linux-gnu
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[binaries]
|
||||||
|
c = 'x86_64-linux-gnu-gcc'
|
||||||
|
cpp = 'x86_64-linux-gnu-g++'
|
||||||
|
ar = 'x86_64-linux-gnu-ar'
|
||||||
|
strip = 'x86_64-linux-gnu-strip'
|
||||||
|
pkgconfig = 'x86_64-linux-gnu-pkg-config'
|
||||||
|
|
||||||
|
[host_machine]
|
||||||
|
system = 'linux'
|
||||||
|
cpu_family = 'x86_64'
|
||||||
|
cpu = 'x86_64'
|
||||||
|
endian = 'little'
|
||||||
13
.devcontainer/meson/cross/x86_64-w64-mingw32
Normal file
13
.devcontainer/meson/cross/x86_64-w64-mingw32
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[binaries]
|
||||||
|
c = 'x86_64-w64-mingw32-gcc'
|
||||||
|
cpp = 'x86_64-w64-mingw32-g++'
|
||||||
|
ar = 'x86_64-w64-mingw32-ar'
|
||||||
|
strip = 'x86_64-w64-mingw32-strip'
|
||||||
|
pkgconfig = 'x86_64-w64-mingw32-pkg-config'
|
||||||
|
windres = 'x86_64-w64-mingw32-windres'
|
||||||
|
|
||||||
|
[host_machine]
|
||||||
|
system = 'windows'
|
||||||
|
cpu_family = 'x86_64'
|
||||||
|
cpu = 'x86_64'
|
||||||
|
endian = 'little'
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/build
|
||||||
|
/cross
|
||||||
180
.gitlab-ci.yml
Normal file
180
.gitlab-ci.yml
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
image: reg.handtruth.com/roots/cpp-meson/build:debian
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- setup
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
- analysis
|
||||||
|
- package
|
||||||
|
|
||||||
|
variables:
|
||||||
|
GIT_SUBMODULE_STRATEGY: normal
|
||||||
|
|
||||||
|
Restore:x86_64-linux-gnu: &restore
|
||||||
|
stage: setup
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-linux-gnu
|
||||||
|
script:
|
||||||
|
- meson -Db_coverage=true build/$TARGET --cross-file=$TARGET
|
||||||
|
tags: ["default"]
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build
|
||||||
|
expire_in: 2 hrs
|
||||||
|
|
||||||
|
Restore:arm-linux-gnueabihf:
|
||||||
|
<<: *restore
|
||||||
|
variables:
|
||||||
|
TARGET: arm-linux-gnueabihf
|
||||||
|
|
||||||
|
Restore:x86_64-w64-mingw32:
|
||||||
|
<<: *restore
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-w64-mingw32
|
||||||
|
|
||||||
|
Restore:x86_64-alpine-linux-musl:
|
||||||
|
<<: *restore
|
||||||
|
image: reg.handtruth.com/roots/cpp-meson/build:alpine
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-alpine-linux-musl
|
||||||
|
|
||||||
|
Build:x86_64-linux-gnu: &build
|
||||||
|
stage: build
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-linux-gnu
|
||||||
|
script:
|
||||||
|
- cd build/$TARGET
|
||||||
|
- ninja
|
||||||
|
tags: ["default"]
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build
|
||||||
|
expire_in: 2 hrs
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-linux-gnu
|
||||||
|
|
||||||
|
Build:arm-linux-gnueabihf:
|
||||||
|
<<: *build
|
||||||
|
variables:
|
||||||
|
TARGET: arm-linux-gnueabihf
|
||||||
|
dependencies:
|
||||||
|
- Restore:arm-linux-gnueabihf
|
||||||
|
|
||||||
|
Build:x86_64-alpine-linux-musl:
|
||||||
|
<<: *build
|
||||||
|
image: reg.handtruth.com/roots/cpp-meson/build:alpine
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-alpine-linux-musl
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-alpine-linux-musl
|
||||||
|
|
||||||
|
Build:x86_64-w64-mingw32:
|
||||||
|
<<: *build
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-w64-mingw32
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-w64-mingw32
|
||||||
|
|
||||||
|
Test:x86_64-linux-gnu: &test
|
||||||
|
stage: test
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-linux-gnu
|
||||||
|
MESON_TESTTHREADS: 1
|
||||||
|
script:
|
||||||
|
- cd build/$TARGET
|
||||||
|
- meson test --wrap='valgrind --error-exitcode=1 --leak-check=full --tool=memcheck --track-origins=yes'
|
||||||
|
- cat meson-logs/testlog-valgrind.txt
|
||||||
|
tags: ["default"]
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build
|
||||||
|
expire_in: 2 hrs
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-linux-gnu
|
||||||
|
- Build:x86_64-linux-gnu
|
||||||
|
|
||||||
|
Test:arm-linux-gnueabihf:
|
||||||
|
<<: *test
|
||||||
|
image: reg.handtruth.com/roots/cpp-meson/build:debian-armhf
|
||||||
|
variables:
|
||||||
|
TARGET: arm-linux-gnueabihf
|
||||||
|
tags: ["armhf"]
|
||||||
|
dependencies:
|
||||||
|
- Restore:arm-linux-gnueabihf
|
||||||
|
- Build:arm-linux-gnueabihf
|
||||||
|
|
||||||
|
Test:x86_64-alpine-linux-musl:
|
||||||
|
<<: *test
|
||||||
|
image: reg.handtruth.com/roots/cpp-meson/build:alpine
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-alpine-linux-musl
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-alpine-linux-musl
|
||||||
|
- Build:x86_64-alpine-linux-musl
|
||||||
|
|
||||||
|
Coverage: &coverage
|
||||||
|
stage: analysis
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-linux-gnu
|
||||||
|
script:
|
||||||
|
- cd build/$TARGET
|
||||||
|
- ninja coverage-text
|
||||||
|
- cat meson-logs/coverage.txt
|
||||||
|
coverage: '/^TOTAL\s+\S+\s+\S+\s+(\d+\.?\d+)%/'
|
||||||
|
tags: ["default"]
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build
|
||||||
|
expire_in: 2 hrs
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-linux-gnu
|
||||||
|
- Build:x86_64-linux-gnu
|
||||||
|
- Test:x86_64-linux-gnu
|
||||||
|
|
||||||
|
Check:
|
||||||
|
stage: analysis
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-linux-gnu
|
||||||
|
script:
|
||||||
|
- cd build/$TARGET
|
||||||
|
- ninja cppcheck
|
||||||
|
coverage: '/^TOTAL\s+\S+\s+\S+\s+(\d+\.?\d+)%/'
|
||||||
|
tags: ["default"]
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build/x86_64-linux-gnu/cppcheck.log
|
||||||
|
expire_in: 1 week
|
||||||
|
dependencies:
|
||||||
|
- Restore:x86_64-linux-gnu
|
||||||
|
|
||||||
|
Package:x86_64-linux-gnu: &package
|
||||||
|
stage: package
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-linux-gnu
|
||||||
|
script:
|
||||||
|
- meson -Dprefix=`pwd`/dist/$TARGET -Dbuildtype=release -Doptimization=3 --cross-file=$TARGET package/$TARGET
|
||||||
|
- cd package/$TARGET
|
||||||
|
- ninja
|
||||||
|
- ninja install
|
||||||
|
tags: ["default"]
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- dist
|
||||||
|
expire_in: 1 mos
|
||||||
|
dependencies: []
|
||||||
|
|
||||||
|
Package:arm-linux-gnueabihf:
|
||||||
|
<<: *package
|
||||||
|
variables:
|
||||||
|
TARGET: arm-linux-gnueabihf
|
||||||
|
|
||||||
|
Package:x86_64-w64-mingw32:
|
||||||
|
<<: *package
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-w64-mingw32
|
||||||
|
|
||||||
|
Package:x86_64-alpine-linux-musl:
|
||||||
|
<<: *package
|
||||||
|
image: reg.handtruth.com/roots/cpp-meson/build:alpine
|
||||||
|
variables:
|
||||||
|
TARGET: x86_64-alpine-linux-musl
|
||||||
17
.vscode/c_cpp_properties.json
vendored
Normal file
17
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "gcc-x64",
|
||||||
|
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
48
.vscode/settings.json
vendored
Normal file
48
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"config.cpp.in": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
29
.vscode/tasks.json
vendored
Normal file
29
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
// Документацию по формату tasks.json см.
|
||||||
|
// по адресу https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "meson",
|
||||||
|
"mode": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "meson",
|
||||||
|
"mode": "test",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
include/meson.build
Normal file
5
include/meson.build
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
includes = include_directories('.')
|
||||||
|
|
||||||
|
install_headers([
|
||||||
|
|
||||||
|
])
|
||||||
45
meson.build
Normal file
45
meson.build
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
project('cpp-meson', 'cpp',
|
||||||
|
version : run_command('git', 'describe', '--abbrev=0', '--tags').stdout().strip(),
|
||||||
|
default_options : ['warning_level=3',
|
||||||
|
'cpp_std=c++17'])
|
||||||
|
|
||||||
|
group = 'com.handtruth'
|
||||||
|
maintainer = 'someone <someone@handtruth.com>'
|
||||||
|
|
||||||
|
modules = [
|
||||||
|
]
|
||||||
|
|
||||||
|
######################################
|
||||||
|
|
||||||
|
module_deps = []
|
||||||
|
|
||||||
|
foreach module : modules
|
||||||
|
module_deps += dependency(module, fallback : [module, 'dep'])
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
subdir('include')
|
||||||
|
subdir('src')
|
||||||
|
subdir('test')
|
||||||
|
|
||||||
|
if get_option('link_type') == 'static'
|
||||||
|
chosen_lib = static_lib
|
||||||
|
else
|
||||||
|
chosen_lib = shared_lib
|
||||||
|
endif
|
||||||
|
|
||||||
|
dep = declare_dependency(link_with : chosen_lib, include_directories : includes)
|
||||||
|
|
||||||
|
cppcheck = custom_target('cppcheck_internal',
|
||||||
|
output : 'cppcheck.log',
|
||||||
|
input : sources + test_files,
|
||||||
|
command : [
|
||||||
|
'cppcheck',
|
||||||
|
'--enable=all',
|
||||||
|
'-I', meson.current_source_dir() / 'include',
|
||||||
|
'-I', meson.current_source_dir() / 'src',
|
||||||
|
'@INPUT@',
|
||||||
|
# '--project=compile_commands.json',
|
||||||
|
'--output-file=cppcheck.log'
|
||||||
|
])
|
||||||
|
|
||||||
|
run_target('cppcheck', command : ['cat', meson.current_build_dir() / 'cppcheck.log'], depends : cppcheck)
|
||||||
1
meson_options.txt
Normal file
1
meson_options.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
option('link_type', type : 'combo', choices : ['static', 'shared'], value : 'static')
|
||||||
10
src/config.cpp.in
Normal file
10
src/config.cpp.in
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
|
namespace config {
|
||||||
|
const std::string group = "@group@";
|
||||||
|
const std::string version = "@version@";
|
||||||
|
const std::string project = "@project@";
|
||||||
|
|
||||||
|
const std::string build = "@build@";
|
||||||
|
const std::string maintainer = "@maintainer@";
|
||||||
|
}
|
||||||
10
src/config.hpp
Normal file
10
src/config.hpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace config {
|
||||||
|
extern const std::string group;
|
||||||
|
extern const std::string version;
|
||||||
|
extern const std::string project;
|
||||||
|
|
||||||
|
extern const std::string build;
|
||||||
|
extern const std::string maintainer;
|
||||||
|
}
|
||||||
17
src/meson.build
Normal file
17
src/meson.build
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
sources = files([
|
||||||
|
'sample_source.cpp'
|
||||||
|
])
|
||||||
|
|
||||||
|
src = include_directories('.')
|
||||||
|
|
||||||
|
sources += configure_file(output : 'config.cpp', input : 'config.cpp.in',
|
||||||
|
configuration : {
|
||||||
|
'group' : group,
|
||||||
|
'project' : meson.project_name(),
|
||||||
|
'version' : meson.project_version(),
|
||||||
|
'build' : run_command('git', 'describe').stdout().strip(),
|
||||||
|
'maintainer' : maintainer,
|
||||||
|
})
|
||||||
|
|
||||||
|
static_lib = static_library(meson.project_name(), sources, include_directories : includes, install: true, dependencies: module_deps)
|
||||||
|
shared_lib = shared_library(meson.project_name(), sources, include_directories : includes, install: true, dependencies: module_deps)
|
||||||
5
src/sample_source.cpp
Normal file
5
src/sample_source.cpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include "config.hpp"
|
||||||
|
|
||||||
|
void sample_function() {
|
||||||
|
|
||||||
|
}
|
||||||
0
subprojects/.ignore
Normal file
0
subprojects/.ignore
Normal file
11
test/meson.build
Normal file
11
test/meson.build
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
test_names = [
|
||||||
|
'sample_test'
|
||||||
|
]
|
||||||
|
|
||||||
|
test_files = []
|
||||||
|
|
||||||
|
foreach test_name : test_names
|
||||||
|
test_files += files(test_name + '.cpp')
|
||||||
|
test_exe = executable(test_name + '.test', test_files[-1], link_with : static_lib, include_directories : [includes, src], dependencies : module_deps)
|
||||||
|
test(test_name, test_exe)
|
||||||
|
endforeach
|
||||||
5
test/sample_test.cpp
Normal file
5
test/sample_test.cpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include "test.hpp"
|
||||||
|
|
||||||
|
test {
|
||||||
|
assert_equals(2, 1 + 1);
|
||||||
|
}
|
||||||
129
test/test.hpp
Normal file
129
test/test.hpp
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#ifdef __TEST_HEAD
|
||||||
|
# error "test.hpp header can't be included several times"
|
||||||
|
#else
|
||||||
|
# define __TEST_HEAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// LCOV_EXCL_START
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
inline string to_string(const std::string & str) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace tests {
|
||||||
|
|
||||||
|
class assertion_error : std::runtime_error {
|
||||||
|
public:
|
||||||
|
explicit assertion_error(const std::string & message) : ::std::runtime_error(message) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int success = 0;
|
||||||
|
template <typename first, typename second>
|
||||||
|
void assert_eq(const first & expect, const second & actual, const char * file, std::size_t line) {
|
||||||
|
if (actual != expect) {
|
||||||
|
std::string message = std::string(file) + ":" + std::to_string(line) + ": assertion failed (\"" + std::to_string(expect) +
|
||||||
|
"\" expected, got \"" + std::to_string(actual) + "\")";
|
||||||
|
std::cout << "test failed: " << message << std::endl;
|
||||||
|
throw assertion_error(message);
|
||||||
|
} else
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
template <typename first, typename second>
|
||||||
|
void assert_ne(const first & expect, const second & actual, const char * file, std::size_t line) {
|
||||||
|
if (actual == expect) {
|
||||||
|
std::string message = std::string(file) + ":" + std::to_string(line) + ": assertion failed (\"" + std::to_string(expect) +
|
||||||
|
"\" equals to \"" + std::to_string(actual) + "\")";
|
||||||
|
std::cout << "test failed: " << message << std::endl;
|
||||||
|
throw assertion_error(message);
|
||||||
|
} else
|
||||||
|
success++;
|
||||||
|
}
|
||||||
|
template <typename E, typename F>
|
||||||
|
void assert_ex_with(F fun, const char * file, std::size_t line) {
|
||||||
|
try {
|
||||||
|
fun();
|
||||||
|
} catch (const E & e) {
|
||||||
|
success++;
|
||||||
|
return;
|
||||||
|
} catch (...) {
|
||||||
|
std::cout << "test failed: " << std::string(file) << ':' << std::to_string(line)
|
||||||
|
<< ": cought unexpected exception type." << std::endl;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
std::string message = std::string(file) + ":" + std::to_string(line) + ": no exception cought.";
|
||||||
|
std::cout << "test failed: " << message << std::endl;
|
||||||
|
throw assertion_error(message);
|
||||||
|
}
|
||||||
|
template <typename F>
|
||||||
|
void assert_ex(F fun, const char * file, std::size_t line) {
|
||||||
|
try {
|
||||||
|
fun();
|
||||||
|
} catch (...) {
|
||||||
|
success++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string message = std::string(file) + ":" + std::to_string(line) + ": no exception cought.";
|
||||||
|
std::cout << "test failed: " << message << std::endl;
|
||||||
|
throw assertion_error(message);
|
||||||
|
}
|
||||||
|
void assert_tr(bool value, const char * file, std::size_t line, const char * expression) {
|
||||||
|
if (value) {
|
||||||
|
success++;
|
||||||
|
} else {
|
||||||
|
std::string message = std::string(file) + ":" + std::to_string(line) + ": value (" + expression + ") was false.";
|
||||||
|
std::cout << "test failed: " << message << std::endl;
|
||||||
|
throw assertion_error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void assert_fa(bool value, const char * file, std::size_t line, const char * expression) {
|
||||||
|
if (!value) {
|
||||||
|
success++;
|
||||||
|
} else {
|
||||||
|
std::string message = std::string(file) + ":" + std::to_string(line) + ": value (" + expression + ") was true.";
|
||||||
|
std::cout << "test failed: " << message << std::endl;
|
||||||
|
throw assertion_error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} assert;
|
||||||
|
|
||||||
|
#define test \
|
||||||
|
void test_function()
|
||||||
|
|
||||||
|
#define assert_equals(expect, actual) \
|
||||||
|
::tests::assert.assert_eq(expect, actual, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define assert_not_equals(expect, actual) \
|
||||||
|
::tests::assert.assert_ne(expect, actual, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define assert_fails_with(E, fun) \
|
||||||
|
::tests::assert.assert_ex_with<E>([&]() fun, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define assert_fails(fun) \
|
||||||
|
::tests::assert.assert_ex([&]() fun, __FILE__, __LINE__)
|
||||||
|
|
||||||
|
#define assert_true(value) \
|
||||||
|
::tests::assert.assert_tr(value, __FILE__, __LINE__, #value)
|
||||||
|
|
||||||
|
#define assert_false(value) \
|
||||||
|
::tests::assert.assert_fa(value, __FILE__, __LINE__, #value)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_function();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "entering test..." << std::endl;
|
||||||
|
test_function();
|
||||||
|
std::cout << "success: " << tests::assert.success << " assertions passed";
|
||||||
|
}
|
||||||
|
|
||||||
|
// LCOV_EXCL_STOP
|
||||||
Reference in New Issue
Block a user