Skip to content

Commit

Permalink
7.3.4
Browse files Browse the repository at this point in the history
updated QV, QK for MSP430
Cmake support
  • Loading branch information
quantum-leaps committed Mar 21, 2024
1 parent a2c05d3 commit 10441f7
Show file tree
Hide file tree
Showing 31 changed files with 703 additions and 71 deletions.
207 changes: 207 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# use a recent CMake version
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
cmake_policy(VERSION 3.13)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14")
cmake_policy(SET CMP0083 NEW)
endif()

# QPC SDK project root CMakeLists.txt
set(QPCPP_HOST_PORTS posix win32)
set(QPCPP_RTOS_PORTS embos freertos threadx uc-os2)
set(QPCPP_BAREMETAL_PORTS arm-cm arm-cr msp430 pic32)
set(QPCPP_MISC_PORTS qep-only)
foreach(p in HOST RTOS BAREMETAL MISC)
list(APPEND QPCPP_ALL_PORTS ${QPCPP_${p}_PORTS})
endforeach()

# project configuration
if(DEFINED ENV{QPCPP_CFG_KERNEL} AND (NOT QPCPP_CFG_KERNEL))
set(QPCPP_CFG_KERNEL $ENV{QPCPP_CFG_KERNEL})
message("Using QPCPP_CFG_KERNEL from environment ('${QPCPP_CFG_KERNEL}')")
elseif(NOT QPCPP_CFG_KERNEL)
set(QPCPP_CFG_KERNEL qv)
message("Set QPCPP_CFG_KERNEL to ('${QPCPP_CFG_KERNEL}') since not specified")
endif()

if(DEFINED ENV{QPCPP_CFG_PORT} AND (NOT QPCPP_CFG_PORT))
set(QPCPP_CFG_PORT $ENV{QPCPP_CFG_PORT})
message("Using QPCPP_CFG_PORT from environment ('${QPCPP_CFG_PORT}')")
endif()

if(NOT QPCPP_CFG_GUI)
set(QPCPP_CFG_GUI OFF CACHE BOOL "enable GUI support for matching ports (e.g. win32 or posix & GTK)")
message("Set QPCPP_CFG_GUI to ('${QPCPP_CFG_GUI}') since not specified")
endif()

if(NOT QPCPP_CFG_UNIT_TEST)
set(QPCPP_CFG_UNIT_TEST OFF CACHE BOOL "enable detailled unit testing support")
message("Set QPCPP_CFG_UNIT_TEST to ('${QPCPP_CFG_UNIT_TEST}') since not specified")
endif()

if(NOT QPCPP_CFG_DEBUG)
set(QPCPP_CFG_DEBUG ON CACHE BOOL "enable debug sessions")
message("Set QPCPP_CFG_DEBUG to ('${QPCPP_CFG_DEBUG}') since not specified")
endif()

if(NOT QPCPP_CFG_VERBOSE)
set(QPCPP_CFG_VERBOSE OFF CACHE BOOL "enable verbose build output")
message("Set QPCPP_CFG_VERBOSE to ('${QPCPP_CFG_VERBOSE}') since not specified")
endif()

project(
qpcpp
VERSION "1.0.0"
DESCRIPTION "QPCPP library"
LANGUAGES C ASM
)

# add support for SPY configuration if not set via CMAKE_TOOLCHAIN_FILE
if(NOT CMAKE_C_FLAGS_SPY)
foreach(LANG IN ITEMS C CXX ASM)
set(CMAKE_${LANG}_FLAGS_SPY "${CMAKE_${LANG}_FLAGS_DEBUG} -DQ_SPY")
endforeach()
endif()

# check target port plausibility
if(NOT QPCPP_CFG_PORT)
message(WARNING "No PORT is configured! Falling back to target system '${CMAKE_SYSTEM_NAME}/${CMAKE_SYSTEM_PROCESSOR}'.")
if(CMAKE_SYSTEM_NAME)
string(TOLOWER ${CMAKE_SYSTEM_NAME} sysName)
else()
set(sysName generic)
endif()
if(CMAKE_SYSTEM_PROCESSOR)
string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} sysProc)
else()
set(sysproc none)
endif()
if((sysName STREQUAL generic) AND (sysProc STREQUAL arm))
set(PORT arm-cm)
elseif(WIN32)
set(PORT win32)
elseif(UNIX)
set(PORT posix)
else()
message(FATAL_ERROR No valid target port could be found. Aborting!)
endif()
else()
string(TOLOWER ${QPCPP_CFG_PORT} PORT)
endif()

if(NOT (${PORT} IN_LIST QPCPP_ALL_PORTS))
if(DEFINED PORT)
message(FATAL_ERROR "Target port '${PORT}' not found!")
else()
message(FATAL_ERROR "Target port not defined!")
endif()
endif()

set(QPCPP_CFG_PORT ${PORT} CACHE STRING "The QPC target port for the system platform")
message(STATUS "Set QPCPP_CFG_PORT to ('${QPCPP_CFG_PORT}')")

# check/set Qx real time kernel
string(TOLOWER ${QPCPP_CFG_KERNEL} KERNEL)
list (APPEND kernList qv qk qxk)
if(NOT (${KERNEL} IN_LIST kernList))
if(QPCPP_CFG_KERNEL)
message(WARNING "Unknown kernel '${QPCPP_CFG_KERNEL}' specified!
Falling back to QV kernel")
endif()
set(QPCPP_CFG_KERNEL QV CACHE STRING "set the desired micro kernel for your project. (default: QV)" FORCE)
set(KERNEL qv)
endif()
unset(kernList)

add_library(qpcpp STATIC "")

# set position independent code compile/link parameters
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14")
include(CheckPIESupported)
check_pie_supported()
endif()
set_property(TARGET qpcpp PROPERTY POSITION_INDEPENDENT_CODE FALSE)

# set up the include directory search path
target_include_directories(qpcpp PUBLIC
src
include
)

# add subdirectories with source/header files
add_subdirectory(src)
add_subdirectory(ports)

# set general defines
target_compile_definitions(qpcpp PRIVATE
$<$<BOOL:${ADD_DEBUG_CODE}>:${ADD_DEBUG_CODE}>
$<$<BOOL:${QPCPP_CFG_GUI}>:QWIN_GUI>
# $<$<CONFIG:Spy>:Q_SPY> # set via toolchain file
$<$<AND:$<CONFIG:Spy>,$<BOOL:${QPCPP_CFG_UNIT_TEST}>>:Q_UTEST>
)

target_compile_options(qpcpp PRIVATE
$<$<BOOL:${QPCPP_CFG_VERBOSE}>:-v>
)

target_link_options(qpcpp PRIVATE
$<$<BOOL:${QPCPP_CFG_VERBOSE}>:-v>
)

target_link_libraries(qpcpp PUBLIC
$<$<AND:$<CONFIG:Spy>,$<STREQUAL:win32,${PORT}>>:ws2_32>
)

# print configuration
message(STATUS
"========================================================
Configured project ${PROJECT_NAME} for ${PORT}
PROJECT_NAME = ${QPCPP_PROJECT}
TARGET = ${TARGET}
IMAGE = ${IMAGE}
SW_VERSION = ${SW_VERSION}
PORT = ${PORT}
QPCPP_CFG_GUI = ${QPCPP_CFG_GUI}
QPCPP_CFG_UNIT_TEST = ${QPCPP_CFG_UNIT_TEST}
QPCPP_CFG_KERNEL = ${QPCPP_CFG_KERNEL}
QPCPP_CFG_DEBUG = ${QPCPP_CFG_DEBUG}
CMAKE_C_CPPCHECK = ${CMAKE_C_CPPCHECK}
-- ========================================================
"
)

if(QPCPP_CFG_VERBOSE)
message(STATUS
"========================================================
System information:
CMAKE_VERSION = ${CMAKE_VERSION}
CMAKE_CROSSCOMPILING = ${CMAKE_CROSSCOMPILING}
CMAKE_HOST_SYSTEM = ${CMAKE_HOST_SYSTEM}
CMAKE_HOST_SYSTEM_NAME = ${CMAKE_HOST_SYSTEM_NAME}
CMAKE_HOST_LINUX = ${CMAKE_HOST_LINUX}
CMAKE_HOST_UNIX = ${CMAKE_HOST_UNIX}
CMAKE_HOST_WIN32 = ${CMAKE_HOST_WIN32}
CMAKE_SYSTEM = ${CMAKE_SYSTEM}
CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}
CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}
WIN32 = ${WIN32}
MSYS = ${MSYS}
MINGW = ${MINGW}
UNIX = ${UNIX}
LINUX = ${LINUX}
CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}
CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}
CMAKE_C_COMPILER_ID = ${CMAKE_C_COMPILER_ID}
CMAKE_C_COMPILER_VERSION = ${CMAKE_C_COMPILER_VERSION}
CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}
CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}
CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}
CMAKE_ASM_COMPILER = ${CMAKE_ASM_COMPILER}
CMAKE_ASM_FLAGS = ${CMAKE_ASM_FLAGS}
-- ========================================================
"
)
endif()
171 changes: 171 additions & 0 deletions cmakeSupport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# cmake Support in QP/C++

This branch adds comprehensive cmake support to QP/C++

## Quick Start

create your project with a root `CMakeLists.txt` file, following this blueprint.
1. copy [qpcpp_sdk_import.cmake](https://github.com/QuantumLeaps/3rd_party/cmake/qpcpp_sdk_import.cmake) into your project. Make sure, it can be found by `cmake` as an included script
2. Setup your 1<sup>st</sup> `CMakeLists.txt`:
```
# use a recent CMake version
cmake_minimum_required(VERSION 3.23 FATAL_ERROR)
cmake_policy(VERSION 3.23...3.28)
cmake_policy(SET CMP0083 NEW)
cmake_policy(SET CMP0105 NEW)
cmake_policy(SET CMP0116 NEW)
cmake_policy(SET CMP0128 NEW)
# include general project config & import qpcpp
set(QPCPP_SDK_PATH ${CMAKE_SOURCE_DIR}/Source/qpcpp-sdk)
# set(QPCPP_FETCH_FROM_GIT ON)
# set(QPCPP_FETCH_FROM_GIT_PATH ${CMAKE_SOURCE_DIR}/Source/qpcpp-sdk)
include(qpcpp_sdk_import)
# default image/project name is trafficlight
# Give a special name via -DIMAGE=<image>
# the main project
project(myProject
VERSION "1.0.0""
DESCRIPTION "my 1st qpcpp project"
LANGUAGES C CXX)
# the project target(s)
add_executable(qpcppApp main.cpp qpcppApp.cpp)
include(${QPCPP_SDK_PATH}/qpcpp_sdk_init.cmake)
set(QPCPP_PROJECT qpcPrj)
set(QPCPP_CFG_KERNEL QV)
set(QPCPP_CFG_GUI TRUE)
set(QPCPP_CFG_PORT win32)
qpcpp_sdk_init()
target_link_libraries(qpcppApp PRIVATE qpcpp)
```
3. configure your project with
`cmake -B Build .`
4. build
`cmake --build Build`

## Usage
### `qpcpp_sdk_import.cmake`
This file prepares your project for integrating qpcpp.
Before adding this file to your project with `include(qpcpp_sdk_import)` make sure to set `CMAKE_MODULE_PATH` accordingly.

To configure the integration of qpcpp you can provide information either with cmake variables or via environment variables of the very same names.

* Mandatory variables (only one of the two must be set)
- `QPCPP_SDK_PATH` - set this variable to point to the full path of an already installed qpcpp instance.
- `QPCPP_FETCH_FROM_GIT` - set this variable to ON or TRUE, if no pre-installed qpcpp directory exists. QPCPP
will then be downloaded from git automatically. The download URL is pre-defined in `qpcpp_sdk_import.cmake`
* Optional variables
- `QPCPP_FETCH_FROM_GIT_PATH` - set this variable to download qpcpp from git (`QPCPP_FETCH_FROM_GIT`) into the
specified directory
- `QPCPP_URL`- set this variable to the URL to download qpcpp from. This must point to a remote git
repository

### `qpcpp_sdk_init.cmake`
This file is situated in the root directory of qpcpp. It performs a pre-initialization of the qpcpp package and provides the function `qpcpp_sdk_init`. Call this function from your project's `CMakeLists.txt` file to perform the final integration of qpcpp into your project. To configure qpcpp to your projects requirements set these variables before calling `qpcpp_sdk_init()`

* `QPCPP_CFG_KERNEL` - STRING: set this variable to the QPCPP kernel for your project. Valid values are QV, QK or QXK. Default: QV
* `QPCPP_CFG_PORT` - STRING: set this variable to reflect the target platform of your project. Default: host system. Valid values are:
+ `arm-cm`, `arm-cr` - Arm CortexM or CortexR micro controllers. Tested with GNU cross compiler environments.
+ `freertos`, `esp-idf`, `emb-os`, `threadx`, `uc-os2` - real time OS
+ `msp430`, `pic32` - TI MSP430 or PIC32 micro controllers
+ `riscv`- Risc V µC
+ `qep-only`, `qube` - test environments
+ `win32`, `posix` - host environments MS Windows, Linux (Posix compatible systems)
* `QPCPP-CFG-GUI` - BOOL: set this Boolean variable to ON/TRUE, if GUI support (win32) shall be compiled in. Default: OFF
* `QPCPP_CFG_UNIT_TEST` - BOOL: set this to ON/TRUE to support qutest, if build configuration `Spy` is active. Default: OFF
* `QPCPP_CFG_VERBOSE` - BOOL: set this to enable more verbosity in message output. Default: OFF

### General usage hints
1. Set `QPCPP_SDK_PATH` or `QPCPP_FETCH_FROM_GIT` either in your `CMakeLists.txt` file or as an environment variable.
2. Optionally set the configuration variable(s)
3. Include `qpcpp_sdk_import` __before__ defining the cmake `project()`
4. Define the project
5. Define the cmake target (executable or library)
6. Include `qpcpp_sdk_init.cmake`
7. configure the qpc SDK
8. call `qpcpp_sdk_init`
9. Add the qpcpp library to your cmake target:
`target_link_libraries(<target>> PRIVATE qpcpp)`

Generate and build your cmake project

## Generation and building hints
* Generate with configuration support
The recommendation is to use a multi-configuration cmake generator like `"Ninja Multi-Config"` and set the cmake variable `CMAKE_CONFIGURATION_TYPES` to `"Debug;Release;Spy"`.
Then you can build with `cmake --build <build directory> --config=<config>.
* Use `CMakePresets.json`
Define the build configurations for your projects in a presets definitions file.
Refer to the [CMakePresets.json manual](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html) for further details.
Then you generate with `cmake --preset=<preset> .` from your project directory. The build then can be started with `cmake --build --preset=<preset>`.

### QPC configurations support
Many `qpcpp` examples provide 3 build configurations:
* `Debug` - build with debug support and debug symbols. Most optimizations are turned off
* `Release` - build without debug support. Activate optimizations instead
* `Spy` - build like `Debug`. Additionally activate support for `QSpy`.

These configurations are also supported by qpcpp with cmake. Different possibilities exist to activate those.

### `qp_config.h` support
Some build configurations require the inclusion of `qp_config.h`. To achieve this, the QPC macro `QP_CONFIG` should be set, when compiling the
`qpcpp` source files. The include search paths also needs to be set accordingly in order for the preprocessor to be able to find the correct include
file.

As `qp_config.hpp` is a project related file, which - in most cases - resides outside the `qpcpp` source code tree, the decision is to handle the
above mentioned topic within the root project's `CMakeLists.txt` file instead of integrating this topic into a rather complicated configuration
of `qpcpp` itself.

An example can be found in the [cmake dpp example](https://github.com/QuantumLeaps/qpcpp-examples/tree/main/posix-win32-cmake/dpp). Have a look into
the example's [CMakeLists.txt](https://github.com/QuantumLeaps/qpcpp-examples/blob/main/posix-win32-cmake/dpp/CMakeLists.txt).

You will find the reference to the `qpc` library, followed by the project's specific setup for `qp_config.h` like this:
```
# set up qpcpp library
target_link_libraries(dpp
PRIVATE
qpcpp
)
# should a 'qp_config.h' configuration file be used and is it available
# edit the HINTS in the 'find_file()' call according to your project settings
if(USE_QP_CONFIG)
find_file(QP_CONFIG qp_config.h HINTS ${CMAKE_CURRENT_SOURCE_DIR}) # try to identify 'qp_config.h'
if(QP_CONFIG) # found 'qp_config.h'
cmake_path(GET QP_CONFIG PARENT_PATH QP_CONFIG_DIR) # extract the path from the FQFN
target_compile_definitions(qpcpp # add -DQP_CONFIG to the qpcpp build
PUBLIC
QP_CONFIG
)
target_include_directories(qpcpp # add the path to 'qp_config.h' to the list of include paths for qpcpp
PUBLIC
${QP_CONFIG_DIR}
)
else() # 'qp_config.h' requested but not find - try to configure and build anyways
message(WARNING "File 'qp_config.h' not found!")
endif()
endif()
```

### Multi configuration generators
The most easy way to make use of the different configurations is to use a multi config generator like `Ninja Multi-Config` or `MS Visual Studio`.
Using one of such generators enables to generate the build system using `cmake` and afterwards simply selecting the desired build configuration like
`cmake --build <Build Directory> --config=<Debug|Release|Spy>`

To support this, the `cmake` variables
* `CMAKE_C_FLAGS_<CONFIGURATION>`
* `CMAKE_CXX_FLAGS_<CONFIGURATION>`
* `CMAKE_ASM_FLAGS_<CONFIGURATION>`
* `CMAKE_EXE_LINKER_FLAGS_<CONFIGURATION>`

have to be set for all configurations. The desired place to hold these settings is the `toolchain` file of the compilation toolchain in use.
If no `toolchain` file is used, the `cmake` default configuration provides settings for the `Debug` and `Release` configuration fot the host
compiler setup. The `Spy` configuration will be added by the qpcpp `CMakeLists.txt` file.

### Single configuration generators
For single configuration generators like `Makefile` or `Ninja`, specific build configurations need to configured. One for each configuration.
When generationg the build system, set the `cmake` variable `CMAKE_BUILD_TYPE` to the desired configuration (`Debug`, `Release` or `Spy`).

Everything said above concerning the `CMAKE_<LANG>_FLAGS_<CONFIGURATION>` variables, also applies here.
2 changes: 1 addition & 1 deletion examples
Submodule examples updated 51 files
+166 −0 arm-cm/dpp_nucleo-l053r8/CMakeLists.txt
+38 −0 arm-cm/dpp_nucleo-l053r8/CMakePresets.json
+14 −5 arm-cm/real-time_nucleo-l053r8/README.md
+301 −0 posix-win32-cmake/dpp/CMakeLists.txt
+180 −0 posix-win32-cmake/dpp/CMakePresets.json
+ posix-win32-cmake/dpp/Res/BTN_DWN.bmp
+ posix-win32-cmake/dpp/Res/BTN_UP.bmp
+ posix-win32-cmake/dpp/Res/eating.bmp
+ posix-win32-cmake/dpp/Res/hungry.bmp
+ posix-win32-cmake/dpp/Res/qp.ico
+ posix-win32-cmake/dpp/Res/thinking.bmp
+144 −0 posix-win32-cmake/dpp/Resource.rc
+238 −0 posix-win32-cmake/dpp/bsp-con.cpp
+524 −0 posix-win32-cmake/dpp/bsp-gtk.cpp
+408 −0 posix-win32-cmake/dpp/bsp-gui.cpp
+64 −0 posix-win32-cmake/dpp/bsp.hpp
+106 −0 posix-win32-cmake/dpp/dpp.hpp
+520 −0 posix-win32-cmake/dpp/dpp.qm
+11 −0 posix-win32-cmake/dpp/dppImages.xml
+68 −0 posix-win32-cmake/dpp/main.cpp
+264 −0 posix-win32-cmake/dpp/philo.cpp
+57 −0 posix-win32-cmake/dpp/qp_config.hpp
+129 −0 posix-win32-cmake/dpp/qutest/bsp.cpp
+145 −0 posix-win32-cmake/dpp/qutest/test_dpp.cpp
+58 −0 posix-win32-cmake/dpp/qutest/test_dpp_init.py
+75 −0 posix-win32-cmake/dpp/qutest/test_dpp_tick.py
+139 −0 posix-win32-cmake/dpp/qutest/test_philo.cpp
+89 −0 posix-win32-cmake/dpp/qutest/test_philo.py
+20 −0 posix-win32-cmake/dpp/qutest/test_philo_init.py
+156 −0 posix-win32-cmake/dpp/qutest/test_table.cpp
+85 −0 posix-win32-cmake/dpp/qutest/test_table.py
+35 −0 posix-win32-cmake/dpp/qutest/test_table_init.py
+112 −0 posix-win32-cmake/dpp/qview/dpp.py
+155 −0 posix-win32-cmake/dpp/qview/dpp1.py
+ posix-win32-cmake/dpp/qview/img/BTN_DWN.gif
+ posix-win32-cmake/dpp/qview/img/BTN_UP.gif
+ posix-win32-cmake/dpp/qview/img/eating.gif
+ posix-win32-cmake/dpp/qview/img/hungry.gif
+ posix-win32-cmake/dpp/qview/img/thinking.gif
+8 −0 posix-win32-cmake/dpp/qview/qview-dpp.bat
+8 −0 posix-win32-cmake/dpp/qview/qview-dpp1.bat
+35 −0 posix-win32-cmake/dpp/resource.h
+348 −0 posix-win32-cmake/dpp/table.cpp
+146 −0 posix-win32/dpp/CMakeLists.txt
+46 −0 posix-win32/dpp/CMakePresets.json
+142 −0 qwin-gui/dpp-gui/CMakeLists.txt
+46 −0 qwin-gui/dpp-gui/CMakePresets.json
+ qwin-gui/dpp-gui/Resource.rc
+3 −3 qwin-gui/dpp-gui/dpp-gui.vcxproj
+ qwin-gui/game-gui/Resource.rc
+4 −4 qwin-gui/game-gui/game-gui.vcxproj
Loading

0 comments on commit 10441f7

Please sign in to comment.