oe-selftest: add a cpp-example recipe

This simple C++ project supports compilation with CMake and Meson.
(Autotool support could be added later on.)
It's supposed to be used with oe-selftest.

An artificial project has several advantages over compiling a normal
CMake or Meson based project for testing purposes:
- It is much faster because it can be kept minimalistic
- It can cover multiple odd corner cases
- No one will change it in an unpredictable way
- It can support multiple build tools with only one C++ codebase

(From OE-Core rev: 4904e772470b0d6e5d98ef0344b3f2bf54214661)

Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Adrian Freihofer 2023-12-07 21:52:49 +01:00 committed by Richard Purdie
parent d7c05e4eed
commit 2df986746b
13 changed files with 296 additions and 0 deletions

View File

@ -0,0 +1 @@
build*

View File

@ -0,0 +1,25 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
SUMMARY = "A C++ example compiled with cmake."
require cpp-example.inc
SRC_URI += "file://CMakeLists.txt"
inherit cmake-qemu
PACKAGECONFIG[failing_test] = "-DFAILING_TEST=ON"
FILES:${PN}-ptest += "${bindir}/test-cmake-example"
do_run_tests () {
bbnote ${DESTDIR:+DESTDIR=${DESTDIR} }${CMAKE_VERBOSE} cmake --build '${B}' --target test -- ${EXTRA_OECMAKE_BUILD}
eval ${DESTDIR:+DESTDIR=${DESTDIR} }${CMAKE_VERBOSE} cmake --build '${B}' --target test -- ${EXTRA_OECMAKE_BUILD}
}
do_run_tests[doc] = "Run cmake --target=test using qemu-user"
addtask do_run_tests after do_compile

View File

@ -0,0 +1,10 @@
#!/bin/sh
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
test-cmake-example
# Note: run-ptests exits with exit value from test-cmake-example

View File

@ -0,0 +1,24 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
DEPENDS += "json-c"
PV = "1.0"
SRC_URI = "\
file://cpp-example.cpp \
file://cpp-example-lib.hpp \
file://cpp-example-lib.cpp \
file://test-cpp-example.cpp \
file://run-ptest \
"
S = "${WORKDIR}"
inherit ptest

View File

@ -0,0 +1,61 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
cmake_minimum_required(VERSION 3.22)
project(cmake-example
VERSION 1.0.0
LANGUAGES CXX
)
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(FAILING_TEST "Compile a failing unit test to test the test infrastructure" OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED On)
set(CMAKE_CXX_EXTENSIONS Off)
include(GNUInstallDirs)
# Linking a small library makes the example more useful for testing.
find_package(json-c)
# A simple library linking json-c library found by pkgconfig
add_library(cmake-example-lib cpp-example-lib.cpp cpp-example-lib.hpp)
set_target_properties(cmake-example-lib PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
target_link_libraries(cmake-example-lib PRIVATE json-c::json-c)
install(TARGETS cmake-example-lib
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
# A simple executable linking the library
add_executable(cmake-example cpp-example.cpp)
target_link_libraries(cmake-example PRIVATE cmake-example-lib)
install(TARGETS cmake-example
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# A simple test executable for testing the library
add_executable(test-cmake-example test-cpp-example.cpp)
target_link_libraries(test-cmake-example PRIVATE cmake-example-lib)
if (FAILING_TEST)
target_compile_definitions(test-cmake-example PRIVATE FAIL_COMPARISON_STR="foo")
endif(FAILING_TEST)
install(TARGETS test-cmake-example
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
include(CTest)
add_test(NAME test-cmake-example COMMAND test-cmake-example)

View File

@ -0,0 +1,33 @@
/*
* Copyright OpenEmbedded Contributors
*
* SPDX-License-Identifier: MIT
*/
#include <iostream>
#include <string>
#include <json-c/json.h>
#include "cpp-example-lib.hpp"
const std::string &CppExample::get_string()
{
return test_string;
}
const char *CppExample::get_json_c_version()
{
return json_c_version();
}
void CppExample::print_json()
{
struct json_object *jobj;
const int flag = JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY;
jobj = json_object_new_object();
json_object_object_add(jobj, "test_string", json_object_new_string(test_string.c_str()));
std::cout << json_object_to_json_string_ext(jobj, flag) << std::endl;
json_object_put(jobj); // Delete the json object
}

View File

@ -0,0 +1,21 @@
/*
* Copyright OpenEmbedded Contributors
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <string>
struct CppExample
{
inline static const std::string test_string = "cpp-example-lib Magic: 123456789";
/* Retrieve a constant string */
const std::string &get_string();
/* Retrieve a constant string from a library */
const char *get_json_c_version();
/* Call a more advanced function from a library */
void print_json();
};

View File

@ -0,0 +1,18 @@
/*
* Copyright OpenEmbedded Contributors
*
* SPDX-License-Identifier: MIT
*/
#include "cpp-example-lib.hpp"
#include <iostream>
int main()
{
auto cpp_example = CppExample();
std::cout << "C++ example linking " << cpp_example.get_string() << std::endl;
std::cout << "Linking json-c version " << cpp_example.get_json_c_version() << std::endl;
cpp_example.print_json();
return 0;
}

View File

@ -0,0 +1,38 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
project('meson-example', 'cpp',
version: '1.0.0',
default_options: ['cpp_std=c++17']
)
jsoncdep = dependency('json-c')
if get_option('FAILING_TEST').enabled()
add_project_arguments('-DFAIL_COMPARISON_STR=foo', language: 'cpp')
endif
mesonexlib = shared_library('mesonexlib',
'cpp-example-lib.cpp', 'cpp-example-lib.hpp',
version: meson.project_version(),
soversion: meson.project_version().split('.')[0],
dependencies : jsoncdep,
install : true
)
executable('mesonex',
'cpp-example.cpp',
link_with : mesonexlib,
install : true
)
test_mesonex = executable('test-mesonex',
'test-cpp-example.cpp',
link_with : mesonexlib,
install : true
)
test('meson example test', test_mesonex)

View File

@ -0,0 +1,3 @@
option('FAILING_TEST', type : 'feature', value : 'disabled',
description : 'Compile a failing unit test to test the test infrastructure')

View File

@ -0,0 +1,25 @@
/*
* Copyright OpenEmbedded Contributors
*
* SPDX-License-Identifier: MIT
*/
#include "cpp-example-lib.hpp"
#include <iostream>
/* This is for creating a failing test for testing the test infrastructure */
#ifndef FAIL_COMPARISON_STR
#define FAIL_COMPARISON_STR ""
#endif
int main() {
auto cpp_example = CppExample();
auto ret_string = cpp_example.get_string();
if(0 == ret_string.compare(CppExample::test_string + FAIL_COMPARISON_STR)) {
std::cout << "PASS: " << ret_string << " = " << CppExample::test_string << std::endl;
} else {
std::cout << "FAIL: " << ret_string << " != " << CppExample::test_string << std::endl;
return 1;
}
}

View File

@ -0,0 +1,27 @@
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
SUMMARY = "A C++ example compiled with meson."
require cpp-example.inc
SRC_URI += "\
file://meson.build \
file://meson.options \
"
inherit pkgconfig meson
PACKAGECONFIG[failing_test] = "-DFAILING_TEST=enabled"
FILES:${PN}-ptest += "${bindir}/test-mesonex"
do_run_tests () {
meson test -C "${B}" --no-rebuild
}
do_run_tests[doc] = "Run meson test using qemu-user"
addtask do_run_tests after do_compile

View File

@ -0,0 +1,10 @@
#!/bin/sh
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#
test-mesonex
# Note: run-ptests exits with exit value from test-mesonex