From 31edd48b4396636e52a24c77e78874335354b3af Mon Sep 17 00:00:00 2001 From: Jakob Hasse Date: Tue, 18 Feb 2020 12:48:57 +0800 Subject: [PATCH] C++: Moved all C++ examples to own folder * moved C++ examples to a new cxx folder in examples * added experimental C++ component * added ESPException class to the C++ experimental component * added test cases for ESPException and corresponding test macros --- .../exceptions}/CMakeLists.txt | 0 .../exceptions}/Makefile | 0 .../exceptions}/README.md | 0 .../exceptions}/example_test.py | 0 .../exceptions}/main/CMakeLists.txt | 0 .../exceptions}/main/component.mk | 0 .../main/exception_example_main.cpp | 0 .../exceptions}/sdkconfig.defaults | 0 .../experimental_cpp_component/CMakeLists.txt | 2 + .../experimental_cpp_component/README.md | 20 +++++++++ .../experimental_cpp_component/component.mk | 0 .../esp_exception.cpp | 11 +++++ .../include/esp_exception.hpp | 44 +++++++++++++++++++ .../test/CMakeLists.txt | 3 ++ .../test/component.mk | 7 +++ .../test/test_cxx_exceptions.cpp | 44 +++++++++++++++++++ .../test/unity_cxx.hpp | 35 +++++++++++++++ .../pthread}/CMakeLists.txt | 0 .../cpp_pthread => cxx/pthread}/Makefile | 0 .../cpp_pthread => cxx/pthread}/README.md | 0 .../pthread}/main/CMakeLists.txt | 0 .../pthread}/main/component.mk | 0 .../pthread}/main/cpp_pthread.cpp | 0 .../cpp_rtti => cxx/rtti}/CMakeLists.txt | 0 .../{system/cpp_rtti => cxx/rtti}/Makefile | 0 .../{system/cpp_rtti => cxx/rtti}/README.md | 0 .../cpp_rtti => cxx/rtti}/example_test.py | 0 .../cpp_rtti => cxx/rtti}/main/CMakeLists.txt | 0 .../cpp_rtti => cxx/rtti}/main/component.mk | 0 .../rtti}/main/rtti_example_main.cpp | 0 .../cpp_rtti => cxx/rtti}/sdkconfig.defaults | 0 tools/ci/check_examples_cmake_make.sh | 2 +- tools/unit-test-app/CMakeLists.txt | 4 +- 33 files changed, 170 insertions(+), 2 deletions(-) rename examples/{system/cpp_exceptions => cxx/exceptions}/CMakeLists.txt (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/Makefile (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/README.md (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/example_test.py (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/main/CMakeLists.txt (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/main/component.mk (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/main/exception_example_main.cpp (100%) rename examples/{system/cpp_exceptions => cxx/exceptions}/sdkconfig.defaults (100%) create mode 100644 examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt create mode 100644 examples/cxx/experimental/experimental_cpp_component/README.md create mode 100644 examples/cxx/experimental/experimental_cpp_component/component.mk create mode 100644 examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp create mode 100644 examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp create mode 100644 examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt create mode 100644 examples/cxx/experimental/experimental_cpp_component/test/component.mk create mode 100644 examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp create mode 100644 examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp rename examples/{system/cpp_pthread => cxx/pthread}/CMakeLists.txt (100%) rename examples/{system/cpp_pthread => cxx/pthread}/Makefile (100%) rename examples/{system/cpp_pthread => cxx/pthread}/README.md (100%) rename examples/{system/cpp_pthread => cxx/pthread}/main/CMakeLists.txt (100%) rename examples/{system/cpp_pthread => cxx/pthread}/main/component.mk (100%) rename examples/{system/cpp_pthread => cxx/pthread}/main/cpp_pthread.cpp (100%) rename examples/{system/cpp_rtti => cxx/rtti}/CMakeLists.txt (100%) rename examples/{system/cpp_rtti => cxx/rtti}/Makefile (100%) rename examples/{system/cpp_rtti => cxx/rtti}/README.md (100%) rename examples/{system/cpp_rtti => cxx/rtti}/example_test.py (100%) rename examples/{system/cpp_rtti => cxx/rtti}/main/CMakeLists.txt (100%) rename examples/{system/cpp_rtti => cxx/rtti}/main/component.mk (100%) rename examples/{system/cpp_rtti => cxx/rtti}/main/rtti_example_main.cpp (100%) rename examples/{system/cpp_rtti => cxx/rtti}/sdkconfig.defaults (100%) diff --git a/examples/system/cpp_exceptions/CMakeLists.txt b/examples/cxx/exceptions/CMakeLists.txt similarity index 100% rename from examples/system/cpp_exceptions/CMakeLists.txt rename to examples/cxx/exceptions/CMakeLists.txt diff --git a/examples/system/cpp_exceptions/Makefile b/examples/cxx/exceptions/Makefile similarity index 100% rename from examples/system/cpp_exceptions/Makefile rename to examples/cxx/exceptions/Makefile diff --git a/examples/system/cpp_exceptions/README.md b/examples/cxx/exceptions/README.md similarity index 100% rename from examples/system/cpp_exceptions/README.md rename to examples/cxx/exceptions/README.md diff --git a/examples/system/cpp_exceptions/example_test.py b/examples/cxx/exceptions/example_test.py similarity index 100% rename from examples/system/cpp_exceptions/example_test.py rename to examples/cxx/exceptions/example_test.py diff --git a/examples/system/cpp_exceptions/main/CMakeLists.txt b/examples/cxx/exceptions/main/CMakeLists.txt similarity index 100% rename from examples/system/cpp_exceptions/main/CMakeLists.txt rename to examples/cxx/exceptions/main/CMakeLists.txt diff --git a/examples/system/cpp_exceptions/main/component.mk b/examples/cxx/exceptions/main/component.mk similarity index 100% rename from examples/system/cpp_exceptions/main/component.mk rename to examples/cxx/exceptions/main/component.mk diff --git a/examples/system/cpp_exceptions/main/exception_example_main.cpp b/examples/cxx/exceptions/main/exception_example_main.cpp similarity index 100% rename from examples/system/cpp_exceptions/main/exception_example_main.cpp rename to examples/cxx/exceptions/main/exception_example_main.cpp diff --git a/examples/system/cpp_exceptions/sdkconfig.defaults b/examples/cxx/exceptions/sdkconfig.defaults similarity index 100% rename from examples/system/cpp_exceptions/sdkconfig.defaults rename to examples/cxx/exceptions/sdkconfig.defaults diff --git a/examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt new file mode 100644 index 000000000..db45ae32e --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "esp_exception.cpp" + INCLUDE_DIRS "include") diff --git a/examples/cxx/experimental/experimental_cpp_component/README.md b/examples/cxx/experimental/experimental_cpp_component/README.md new file mode 100644 index 000000000..dba16a188 --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/README.md @@ -0,0 +1,20 @@ +# Experimental C++ Component + +*Warning:* This component is subject to change without notice. Don't consider it as a stable API. +It proposes future C++ interfaces of IDF components. + +# Usage/Build +To use and build this component, add it as an extra component in your project's cmake file: +```cmake +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component) +``` + +# Tests +To build the tests, first add them to the unit test's CMakeLists.txt: +```cmake +set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") +``` +Then go to the unit test app's directory and run: +```bash +idf.py -T experimental_cpp_component build +``` diff --git a/examples/cxx/experimental/experimental_cpp_component/component.mk b/examples/cxx/experimental/experimental_cpp_component/component.mk new file mode 100644 index 000000000..e69de29bb diff --git a/examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp b/examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp new file mode 100644 index 000000000..113652927 --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/esp_exception.cpp @@ -0,0 +1,11 @@ +#ifdef __cpp_exceptions + +#include "esp_exception.hpp" + +namespace idf { + +ESPException::ESPException(esp_err_t error) : error(error) { } + +} // namespace idf + +#endif // __cpp_exceptions diff --git a/examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp b/examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp new file mode 100644 index 000000000..7a68078ae --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/include/esp_exception.hpp @@ -0,0 +1,44 @@ +// Copyright 2019 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ESP_EXCEPTION_HPP_ +#define ESP_EXCEPTION_HPP_ + +#ifdef __cpp_exceptions + +#include "esp_err.h" +#include + +namespace idf { + +/** + * General exception class for exceptions on the ESP chips. + * All throwing code in IDF should use either this exception directly or a sub-classes. + */ +struct ESPException : public std::exception { + ESPException(esp_err_t error); + + esp_err_t error; +}; + +/** + * Convenience macro to help converting IDF error codes into ESPException. + */ +#define CHECK_THROW(error_) if (error_ != ESP_OK) throw idf::ESPException(error_); + +} // namespace idf + +#endif // __cpp_exceptions + +#endif // ESP_EXCEPTION_HPP_ diff --git a/examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt b/examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt new file mode 100644 index 000000000..fcac48d9b --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/test/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRC_DIRS "." + PRIV_INCLUDE_DIRS . + PRIV_REQUIRES unity test_utils experimental_cpp_component) diff --git a/examples/cxx/experimental/experimental_cpp_component/test/component.mk b/examples/cxx/experimental/experimental_cpp_component/test/component.mk new file mode 100644 index 000000000..8b9586c0b --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/test/component.mk @@ -0,0 +1,7 @@ +# +#Component Makefile +# + +COMPONENT_SRCDIRS := . + +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp b/examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp new file mode 100644 index 000000000..b43752ba8 --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/test/test_cxx_exceptions.cpp @@ -0,0 +1,44 @@ +#include +#include "unity.h" + +#include "unity_cxx.hpp" +#include "esp_exception.hpp" + +#ifdef __cpp_exceptions + +using namespace std; +using namespace idf; + +#define TAG "CXX Exception Test" + +TEST_CASE("TEST_THROW catches exception", "[cxx exception]") +{ + TEST_THROW(throw ESPException(ESP_FAIL);, ESPException); +} + +/* The following two test cases are expected to fail */ + +TEST_CASE("TEST_THROW asserts catching different exception", "[cxx exception][ignore]") +{ + TEST_THROW(throw std::exception();, ESPException); +} + +TEST_CASE("TEST_THROW asserts not catching any exception", "[cxx exception][ignore]") +{ + TEST_THROW(printf(" ");, ESPException); // need statement with effect +} + +TEST_CASE("CHECK_THROW continues on ESP_OK", "[cxx exception]") +{ + esp_err_t error = ESP_OK; + CHECK_THROW(error); +} + +TEST_CASE("CHECK_THROW throws", "[cxx exception]") +{ + esp_err_t error = ESP_FAIL; + TEST_THROW(CHECK_THROW(error), ESPException); +} + +#endif // __cpp_exceptions + diff --git a/examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp b/examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp new file mode 100644 index 000000000..f90533238 --- /dev/null +++ b/examples/cxx/experimental/experimental_cpp_component/test/unity_cxx.hpp @@ -0,0 +1,35 @@ +#ifndef UNITY_CXX_H_ +#define UNITY_CXX_H_ + +#include "unity.h" + +#define STR(x) #x + +/** + * Very simple helper macro to catch exceptions. + * + * @note + * * If there is any exception which not a child of std::exception, it will terminate the program! + * * If there is no exception, it will jump from the current frame without de-initializing + * destructors! + */ +#define TEST_THROW(expr_, exception_) \ + do { \ + bool caught = false; \ + bool caught_different = false; \ + try { \ + expr_; \ + } catch ( exception_ &e) { \ + caught = true; \ + } catch ( std::exception &e) { \ + caught_different = true; \ + } \ + TEST_ASSERT_FALSE_MESSAGE(caught_different, "ERROR: Expected " STR(exception_) \ + ", but caught different exception."); \ + TEST_ASSERT_TRUE_MESSAGE(caught, "ERROR: Expected " STR(exception_) \ + ", but no exception thrown."); \ + } \ + while (0) + + +#endif // UNITY_CXX_H_ diff --git a/examples/system/cpp_pthread/CMakeLists.txt b/examples/cxx/pthread/CMakeLists.txt similarity index 100% rename from examples/system/cpp_pthread/CMakeLists.txt rename to examples/cxx/pthread/CMakeLists.txt diff --git a/examples/system/cpp_pthread/Makefile b/examples/cxx/pthread/Makefile similarity index 100% rename from examples/system/cpp_pthread/Makefile rename to examples/cxx/pthread/Makefile diff --git a/examples/system/cpp_pthread/README.md b/examples/cxx/pthread/README.md similarity index 100% rename from examples/system/cpp_pthread/README.md rename to examples/cxx/pthread/README.md diff --git a/examples/system/cpp_pthread/main/CMakeLists.txt b/examples/cxx/pthread/main/CMakeLists.txt similarity index 100% rename from examples/system/cpp_pthread/main/CMakeLists.txt rename to examples/cxx/pthread/main/CMakeLists.txt diff --git a/examples/system/cpp_pthread/main/component.mk b/examples/cxx/pthread/main/component.mk similarity index 100% rename from examples/system/cpp_pthread/main/component.mk rename to examples/cxx/pthread/main/component.mk diff --git a/examples/system/cpp_pthread/main/cpp_pthread.cpp b/examples/cxx/pthread/main/cpp_pthread.cpp similarity index 100% rename from examples/system/cpp_pthread/main/cpp_pthread.cpp rename to examples/cxx/pthread/main/cpp_pthread.cpp diff --git a/examples/system/cpp_rtti/CMakeLists.txt b/examples/cxx/rtti/CMakeLists.txt similarity index 100% rename from examples/system/cpp_rtti/CMakeLists.txt rename to examples/cxx/rtti/CMakeLists.txt diff --git a/examples/system/cpp_rtti/Makefile b/examples/cxx/rtti/Makefile similarity index 100% rename from examples/system/cpp_rtti/Makefile rename to examples/cxx/rtti/Makefile diff --git a/examples/system/cpp_rtti/README.md b/examples/cxx/rtti/README.md similarity index 100% rename from examples/system/cpp_rtti/README.md rename to examples/cxx/rtti/README.md diff --git a/examples/system/cpp_rtti/example_test.py b/examples/cxx/rtti/example_test.py similarity index 100% rename from examples/system/cpp_rtti/example_test.py rename to examples/cxx/rtti/example_test.py diff --git a/examples/system/cpp_rtti/main/CMakeLists.txt b/examples/cxx/rtti/main/CMakeLists.txt similarity index 100% rename from examples/system/cpp_rtti/main/CMakeLists.txt rename to examples/cxx/rtti/main/CMakeLists.txt diff --git a/examples/system/cpp_rtti/main/component.mk b/examples/cxx/rtti/main/component.mk similarity index 100% rename from examples/system/cpp_rtti/main/component.mk rename to examples/cxx/rtti/main/component.mk diff --git a/examples/system/cpp_rtti/main/rtti_example_main.cpp b/examples/cxx/rtti/main/rtti_example_main.cpp similarity index 100% rename from examples/system/cpp_rtti/main/rtti_example_main.cpp rename to examples/cxx/rtti/main/rtti_example_main.cpp diff --git a/examples/system/cpp_rtti/sdkconfig.defaults b/examples/cxx/rtti/sdkconfig.defaults similarity index 100% rename from examples/system/cpp_rtti/sdkconfig.defaults rename to examples/cxx/rtti/sdkconfig.defaults diff --git a/tools/ci/check_examples_cmake_make.sh b/tools/ci/check_examples_cmake_make.sh index f23ebc56e..4dd6b2122 100755 --- a/tools/ci/check_examples_cmake_make.sh +++ b/tools/ci/check_examples_cmake_make.sh @@ -2,7 +2,7 @@ # While we support GNU Make & CMake together, check the same examples are present for both -CMAKE_EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name CMakeLists.txt | grep -v "/components/" | grep -v "/common_components/" | grep -v "/main/" | grep -v "/build_system/cmake/" | grep -v "/mb_example_common/") +CMAKE_EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name CMakeLists.txt | grep -v "/components/" | grep -v "/common_components/" | grep -v "/cxx/experimental/experimental_cpp_component/" | grep -v "/main/" | grep -v "/build_system/cmake/" | grep -v "/mb_example_common/") MAKE_EXAMPLE_PATHS=$( find ${IDF_PATH}/examples/ -type f -name Makefile | grep -v "/build_system/cmake/") CMAKE_EXAMPLE_PATHS="$(/usr/bin/dirname $CMAKE_EXAMPLE_PATHS | sort -n)" diff --git a/tools/unit-test-app/CMakeLists.txt b/tools/unit-test-app/CMakeLists.txt index 95932b0c2..a1861793e 100644 --- a/tools/unit-test-app/CMakeLists.txt +++ b/tools/unit-test-app/CMakeLists.txt @@ -2,5 +2,7 @@ # CMakeLists in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) +set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/") + include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(unit-test-app) \ No newline at end of file +project(unit-test-app)