Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cmake): fix custom targets #313

Draft
wants to merge 33 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7d6cead
fix(cmake): fix custom targets
glencoe Oct 25, 2024
950a596
wip(cmake): make the first three unit tests work
glencoe Oct 28, 2024
963c035
wip(cmake): add cmake presets
glencoe Oct 28, 2024
47ec78f
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Oct 28, 2024
bef97d0
wip(cmake): compile hw tests
glencoe Oct 29, 2024
9969e45
wip(cmake): make custom targets more explicit
glencoe Oct 29, 2024
fdc8e97
docs(cmake): document new cmake approach
glencoe Oct 30, 2024
b1d56ef
docs(cmake): remove transitive deps
glencoe Nov 4, 2024
9510e6c
fix(cmake): restore previous __hdrs __impl behaviour
glencoe Nov 4, 2024
61815be
fix(cmake): add missing cmake targets
glencoe Nov 4, 2024
2a2f5d1
build(cmake): add missing cmake targets
glencoe Nov 4, 2024
f87c641
fix(cmake): fix cmake files for unit tests except for mqtt unit test
Nov 4, 2024
47e57f7
fix(cmake): cheat direct dependency linking order
Nov 5, 2024
ba5ca26
wip(cmake): first hardwaretest cmake implementation
Nov 6, 2024
f43d5ac
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Nov 6, 2024
94563ee
wip(cmake): Hardwaretest for BMI works now, but StressTestAdxl345b st…
Nov 8, 2024
0cb3022
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Nov 8, 2024
115486d
wip(cmake): fix stub_defs print message
Nov 11, 2024
d338c03
wip(cmake): move to idiomatic cmake defs
glencoe Nov 11, 2024
1f93701
Merge remote-tracking branch 'origin/fix-custom-cmake-targets' into f…
glencoe Nov 11, 2024
363efcf
wip(cmake): simplify scripts and fix conflicts
glencoe Nov 12, 2024
7d5c616
wip(cmake): add adxl hw test
glencoe Nov 12, 2024
1e0c66d
fix(cmake): sensor hardwaretest work
Nov 12, 2024
bd0cd60
wip(cmake): working on spi and network issue
Nov 15, 2024
b54bc22
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Nov 15, 2024
b2efae8
fix(cmake): fix missing dependency on http hw test
Nov 15, 2024
b5680a2
fix(cmake): fix missing dependency on usb hw test
Nov 15, 2024
6aa3f5d
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Nov 15, 2024
7dcc566
fix(cmake): fix missing dependencies
Nov 15, 2024
f34952f
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Nov 15, 2024
d03e74b
fix(cmake): unit tests work
Nov 20, 2024
8b23218
style(all): apply clang-format to 'fix-custom-cmake-targets'
actions-user Nov 20, 2024
250ca31
wip(cmake): implement bare bones hw test for esp
Nov 28, 2024
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
12 changes: 0 additions & 12 deletions .idea/cmake.xml

This file was deleted.

7 changes: 7 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/elastic-ai.runtime.enV5.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/runConfigurations/Unit_Tests.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/runConfigurations/all.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 37 additions & 54 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,69 +1,52 @@
cmake_minimum_required(VERSION 3.20...3.24)
include(helpers.cmake)

include(cmake/set_build_target.cmake)


include(cmake/third_party_deps.cmake)

add_pico_sdk("2.0.0")
add_unity()
add_cexception()
add_runtime_c()



set(CMAKE_EXPORT_COMPILE_COMMANDS 1)

# enable debug prints
if (DEBUG_OUTPUT)
add_definitions(-DDEBUG_MODE)
endif ()

if (UNIT_TEST)
message(NOTICE "INFO: Building for local machine")
else ()
message(NOTICE "INFO: Building for enV5 hardware (Type: ${CMAKE_BUILD_TYPE})")
setupPicoSdk("2.0.0")


if(NOT BUILDING_FOR_ELASTIC_NODE)
add_compile_options(-ftrapv) # abort execution on integer overflow
endif ()

project(enV5 C CXX ASM)
pico_sdk_init()

# enable test execution via CMake
include(CTest)
include(cmake/custom_targets.cmake)
include(cmake/pico_targets.cmake)

# include unit-test framework
add_unity()
include(CTest)

# include required standard libs for testing

if(UNIT_TEST)
add_runtime_c()
add_cexception()
add_subdirectory(src/common)
add_subdirectory(src/network/atCommands)
add_subdirectory(src/network/config)

# include dummies for local machine
add_subdirectory(test/unit/dummies)

# include our own libraries to test
add_subdirectory(src/hal/enV5HwConfiguration)
add_subdirectory(src/sensor/sht3x)
add_subdirectory(src/sensor/adxl345b)
add_subdirectory(src/sensor/pac193x)
add_subdirectory(src/network/wifi)
add_subdirectory(src/network/http)
add_subdirectory(src/network/broker)
add_subdirectory(src/fpga/fpgaConfigurationHandler)
add_subdirectory(src/filesystem)

# include unit-tests
add_subdirectory(test/unit)
else ()
pico_sdk_init()

if (TARGET tinyusb_device)
# include required libraries
add_basic_functionality()
add_freertos_kernel()

add_rp2040_hal()
add_sensor_libraries()

# include hardware tests
add_subdirectory(test/hardware)

add_dependency_graph()
elseif (PICO_ON_DEVICE)
message(WARNING "Not building Project, because TinyUSB submodule is not initialized in the SDK!")
endif ()
add_subdirectory(src)
add_subdirectory(test/unit)
add_subdirectory(test/unit/Adxl345b)
add_subdirectory(test/unit/Pac193x)
add_subdirectory(test/unit/FpgaConfigurationHandler)
add_subdirectory(test/unit/Http)
add_subdirectory(test/unit/Network)
add_subdirectory(test/unit/MqttBroker)
add_subdirectory(test/unit/Sht3x)
add_subdirectory(test/hardware)

add_freertos()

if(BUILDING_FOR_ELASTIC_NODE AND NOT TARGET tinyusb_device)
message(WARNING "not building project, because tinyusb not initialized")
else()
endif ()

76 changes: 76 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "host",
"displayName": "Host Config",
"description": "Build for your host system (MacOs, Linux, Windows)",
"generator": "Ninja",
"binaryDir": "build/host/",
"cacheVariables": {
"ELASTIC_AI_TARGET": "HOST",
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "env5_rev2",
"displayName": "EnV5 Rev2",
"generator": "Ninja",
"binaryDir": "build/env5_rev2",
"cacheVariables": {
"ELASTIC_AI_TARGET": "ENV5_REV2",
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "env5_rev2_debug",
"displayName": "EnV5 Rev2 Debug",
"generator": "Ninja",
"binaryDir": "build/env5_rev2_debug",
"cacheVariables": {
"ELASTIC_AI_TARGET": "ENV5_REV2",
"CMAKE_BUILD_TYPE": "Debug",
"DEBUG_MODE": "ON"
}
}
],
"buildPresets": [
{
"name": "host",
"configurePreset": "host",
"jobs": 4
},
{
"name": "env5_rev2",
"configurePreset": "env5_rev2",
"jobs": 6
},
{
"name": "unit_test",
"inherits": "host",
"targets": "all_unit_tests"
}
],
"testPresets": [
{
"name": "unit_test",
"displayName": "Unit Tests",
"configurePreset": "host",
"output": {
"outputJUnitFile": "unit-test.junit",
"outputOnFailure": true
},
"filter": {
"include": {
"label": "unit"
}
}

}
]
}
49 changes: 49 additions & 0 deletions cmake/Readme.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
== Cmake Scripts

=== Encapsulated Libraries

We want to have the following goals

- fine-grained control over dependencies for flexibility and to facilitate link-time substitution
- prevent access to header files of transitive dependencies, i.e., if you call a function defined in `libB` you have to explicitly depend on it. There should not be a way to include a header provided by `B` without declaring that explicit dependency. This way, we avoid hidden source code dependencies. And each module only sees the header files it actually needs.
- for convenience, we want to have a target combines implementation and headers.

We achieve these by (typically) defining four build targets for each of our modules. Assuming we want to define a new library `A` that performs a direct call to library `B`. Then we define

`A__hdrs`:: providing access to all public header files of our module `A`, e.g.,
+
[source, cmake]
----
add_library(A__hdrs INTERFACE)
target_include_directories(A__hdrs INTERFACE include)
----
`A__impl`:: containing the implementation of `A`. This target needs access to the headers of its dependent modules, e.g.,
+
[source, cmake]
----
add_library(A__impl A.c)
target_link_libraries(A__impl PRIVATE B__hdrs)
----
+
`A`:: providing access to public headers for consuming targets (e.g., executables) and transitively providing dependent library implementations
[source, cmake]
----
add_library(A INTERFACE)
target_link_libraries(A INTERFACE A__impl A__hdrs)
----

Currently, the `elastic_ai_add_library` function provides most of this functionality. However, using it will prevent the IDE from automatically discovering your targets for the sake of jump-to-definition and auto-completion.

=== Building HW Dependent Libs
The build scripts will set a global variable `BUILDING_FOR_ELASTIC_NODE` to `true` iff we're building for an elastic node hardware.
If you need to define a HW dependent lib, e.g., because it calls into the pico_sdk, you should ask for that flag and define the `__impl` as an empty interface target. E.g.,

[source, cmake]
----
if(BUILDING_FOR_ELASTIC_NODE)
add_library(A__impl A.c)
target_link_libraries(A__impl PRIVATE Pico::pico_runtime__hdrs)
else()
add_library(A__impl INTERFACE)
endif ()
----
98 changes: 14 additions & 84 deletions cmake/custom_targets.cmake
Original file line number Diff line number Diff line change
@@ -1,84 +1,14 @@
################
# Functions in here are supposed to help keeping consistent naming scheme and package structure
# for different cmake targets.
################

function(elastic_ai_lib)
# Takes the following parameters:
#
# NAME: the name of your library (withstand the urge to use 'lib' as a suffix!)
# SOURCES: all the *.c files that need to be compiled for this library
# DEPS: all libaries, that the current library depends on. These need to be specified via
# the elastic_ai_lib function as well.
#
# We assume that public headers live inside an `include` directory in the package.
#
#
# Will generate several different library targets:
# 1. <mylib>__hdrs : a pure INTERFACE library containing only the public headers of this
# module. These hdr only libs will be automatically linked when defining a new lib that depends
# on the current one.
# 2. <mylib>__nodeps : a library that contains the implementation in addition to 1, linking against all
# all hdr libs of the specified dependencies.
# 3. <mylib> : a library carrying all transitive dependencies.
#
# If you need to link a lib A against a library B that was not defined as an elastic_ai_lib
# you will want to do it like this in most cases:
#
# elastic_ai(NAME A SOURCES A.c)
# target_link_libraries(A PRIVATE B)
# target_include_directories(A__nodeps PRIVATE get_property(TARGET B INTERFACE_INCLUDE_DIRECTORY))
set(oneValueArgs NAME)
set(multiValueArgs SOURCES DEPS)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}" "${oneValueArgs}" "${multiValueArgs}"
)
if(NOT ${arg_DEPS})
set(arg_DEPS "")
endif ()
add_library(${arg_NAME}__hdrs INTERFACE)
target_include_directories(${arg_NAME}__hdrs INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)

add_library(${arg_NAME}__nodeps ${arg_SOURCES})
target_include_directories(${arg_NAME}__nodeps PRIVATE ${CMAKE_CURRENT_LIST_DIR})
set(hdrLibs "")
foreach (lib ${DEPS})
list(APPEND hdrLibs ${lib}__hdrs)
endforeach ()
target_link_libraries(${arg_NAME}__nodeps PUBLIC ${arg_NAME}__hdrs)
target_link_libraries(${arg_NAME}__nodeps PRIVATE ${hdrLibs})

add_library(${arg_NAME} INTERFACE)
target_link_libraries(${arg_NAME} INTERFACE ${arg_NAME}__nodeps ${DEPS})
endfunction()


function(elastic_ai_unit_test)
# Similar to elastic_ai_lib but defines a new unit test.
# You only need to specify the LIB_UNDER_TEST.
# The function will automatically try to compile a file with the same name, but
# the prefix `Unittest` and link against the nodeps version of LIB_UNDER_TEST.
# For flexibility you can specify additional libraries (MORE_LIBS) and
# sources (MORE_SOURCES).
set(oneValueArgs LIB_UNDER_TEST)
set(multiValueArgs MORE_SOURCES MORE_LIBS)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${options}" "${oneValueArgs}" "${multiValueArgs}"
)
if(NOT ${arg_MORE_SOURCES})
set(arg__MORE_SOURCES "")
endif ()

if(NOT ${arg_MORE_LIBS})
set(arg_MORE_LIBS "")
endif ()

if (NOT ${arg_DEPS})
set(arg_DEPS "")
endif ()
add_executable(unit-test_${arg_LIB_UNDER_TEST} Unittest${arg_LIB_UNDER_TEST}.c)
target_sources(unit-test_${arg_LIB_UNDER_TEST} PRIVATE ${arg_MORE_SOURCES})
target_link_libraries(unit-test_${arg_LIB_UNDER_TEST} ${arg_LIB_UNDER_TEST}__nodeps unity)
add_test(unit-test_${arg_LIB_UNDER_TEST} unit-test_${arg_LIB_UNDER_TEST})
target_link_libraries(unit-test_${arg_LIB_UNDER_TEST} ${arg_MORE_LIBS})
endfunction()
function(create_enV5_executable target)
# enable usb output
pico_enable_stdio_usb(${target} 1)
# disable uart output
pico_enable_stdio_uart(${target} 0)
# create map/bin/hex/uf2 file etc.
pico_add_uf2_output(${target})
# # copy u2f files after build to out directory
# file(RELATIVE_PATH relative_path ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_LIST_DIR})
# add_custom_command(TARGET ${target} POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy
# ${CMAKE_BINARY_DIR}/${relative_path}/${target}.uf2
# ${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}-Rev${REVISION}/${relative_path}/${target}.uf2)
endfunction()
10 changes: 10 additions & 0 deletions cmake/env5.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
message("Building for env5")
set(BUILDING_FOR_ELASTIC_NODE ON CACHE INTERNAL "we're building for elastic node")
set(PICO_BOARD none)
set(PICO_PLATFORM rp2040)

if(${ELASTIC_AI_TARGET} EQUAL ENV5_REV1)
set(REVISION "1" CACHE INTERNAL "")
else()
set(REVISION "2" CACHE INTERNAL "")
endif ()
5 changes: 5 additions & 0 deletions cmake/host.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
message("building for native host platform")
set(BUILDING_FOR_ELASTIC_NODE OFF CACHE INTERNAL "we're building for elastic node")
set(PICO_BOARD none)
set(PICO_PLATFORM host)
set(REVISION "1" CACHE INTERNAL "")
Loading