FreeRTOS-Kernel icon indicating copy to clipboard operation
FreeRTOS-Kernel copied to clipboard

[Feature Request] CMakeLists.txt improvements for better Project integration and maintenance of portable(s)

Open phelter opened this issue 2 years ago • 3 comments

Problem:

The method of using FREERTOS_CONFIG_FILE_DIRECTORY limits the integration and what is included in the FreeRTOSConfig.h file.

With this method a user of FreeRTOS-Kernel cannot include or link other libraries into the FreeRTOSConfig.h file:

One example would be to include a local file for the project:

// FreeRTOSConfig.h file
#include "project_settings.h"  # This is in a different directory.

Solution: Suggest using an assumed name for a target eg : FreeRTOS::config that is included in all of the freertos_* libs etc.

An example integration with the project would be - where all of the FreeRTOS based config files would reside: project_config The project_config target would provide location to where where FreeRTOSConfig.h and all other FreeRTOS submodule config files reside.

# Toplevel or Project CMakeLists.txt
add_library(project_config INTERFACE)

target_include_directories( project_config
  INTERFACE
    include
)

And the only thing you would need to have defined in your project is something like:

# Add this line to the target that publicizes the FreeRTOS configuration files.
add_library(FreeRTOS::config ALIAS project_config)

And in all of the libraries that are in the CMakeLists.txt - these would have eg: here for freertos_kernel

target_link_libraries(freertos_kernel 
  PUBLIC
    FreeRTOS::config
    freertos_kernel_port
)

And remove the use of FREERTOS_CONFIG_FILE_DIRECTORY in the target_include_directories

Alternatives: Alternative solution: I currently copy the CMakeLists.txt into a separate directory under my project directory, modify them with the above changes and then use

config_file(<local cmake file>  <Dir with FreeRTOS code and CMakeLists.txt> COPYONLY)

To overwrite the existing CMakeLists.txt inside the FreeRTOS directory, but this is only to workaround the limitation of defining a FreeRTOS::config target.

How many devices will this feature impact? N/A - used for compile.

What are your project timelines? N/A - using Alternative workaround for now.

Additional context None.

Would also suggest doing this for the portable freertos_kernel_port target as well. Per portable/* directory have a CMakeLists.txt file and partition the monolithic portable/CMakeLists.txt into their own directories - so they are unique to each of those. This would also simplify the portable.

An example CMakeLists.txt file for the portable directories:

# portable/GCC/ARM_CA9/CMakeLists.txt

add_library(freertos_kernel_port_GCC_ARM_CA9 STATIC EXCLUDE_FROM_ALL)

target_sources(freertos_kernel_port_GCC_ARM_CA9
  PRIVATE
      port.c
      portASM.S
      portmacro.h
)

target_include_directories(freertos_kernel_port_GCC_ARM_CA9
  PUBLIC
     .
)

target_link_libraries(freertos_kernel_port_GCC_ARM_CA9
  PRIVATE
     freertos_kernel
)

And then in the portable/CMakeLists.txt This just includes all of the port directories - they won't compile unless they are used due to the EXCLUDE_FROM_ALL option. If you still want tosupport FREERTOS_PORT - then you can have a single large case statement

if(NOT TARGET freertos_kernel_port)
    add_library(freertos_kernel_port ALIAS
            $<$<STREQUAL:${FREERTOS_PORT},BCC_16BIT_DOS_FLSH186>:freertos_kernel_port_BCC_16BIT_DOS_FLSH186>
            #...
            $<$<STREQUAL:${FREERTOS_PORT},GCC_ARM_CA9>:freertos_kernel_port_GCC_ARM_CA9>
            #...
           $<$<STREQUAL:${FREERTOS_PORT},WIZC_PIC18>:freertos_kernel_port_WIZC_PIC18>
     )
else()
    message(STATUS "freertos_kernel_port already defined - using that.")
endif()

For the FreeRTOS-Kernel/CMakeLists.txt check for FREERTOS_PORT this changes to:

if(NOT TARGET freertos_kernel_port)
    message(FATAL_ERROR " `freertos_kernel_port library alias is not defined. Please specify it from top-level CMake file (example):\n"
        "  add_library(freertos_kernel_port ALIAS freertos_kernel_port_GCC_ARM_CM4F)\n"
        " or from CMake command line option:\n"
        "  -DFREERTOS_PORT=GCC_ARM_CM4F\n"
        " \n"
        " Available port options:\n"
          #...)
endif()

phelter avatar Sep 13 '22 19:09 phelter

@phelter Thanks for the suggestion.

I like the idea of an injectable configuration target "FreeRTOS::Kernel::Config" or something similar.

You can always add something like:

target_link_libraries( freertos_kernel PRIVATE project_config )
target_link_libraries( freertos_kernel_port PRIVATE project_config )

to your cmake files.

Given that many of the port-specific bits are supplied in macros, I don't think that it makes much sense to have separate static library targets for the core kernel and ports.

Perhaps It makes more sense to provide these as an INTERFACE target for each port and then provide a single static library target if a particular port is selected and configured.

paulbartell avatar Sep 14 '22 17:09 paulbartell

@paulbartell - here's a git diff to support FREERTOS_PORT = A_CUSTOM_PORT - put it at the top of the list: Note - in the CMakeLists.txt - should also fix spelling : Compiller -> Compiler

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86e149c02..2ef5a0bf1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,6 +38,7 @@ if(NOT FREERTOS_PORT)
         "  -DFREERTOS_PORT=GCC_ARM_CM4F\n"
         " \n"
         " Available port options:\n"
+        " A_CUSTOM_PORT                    - Compiler: UserDefined    Target: User Defined"\n
         " BCC_16BIT_DOS_FLSH186            - Compiller: BCC           Target: 16 bit DOS Flsh186\n"
         " BCC_16BIT_DOS_PC                 - Compiller: BCC           Target: 16 bit DOS PC\n"
         " CCS_ARM_CM3                      - Compiller: CCS           Target: ARM Cortex-M3\n"
@@ -168,6 +169,25 @@ if(NOT FREERTOS_PORT)
         " CDK_THEAD_CK802                  - Compiller: CDK           Target: T-head CK802\n"
         " XCC_XTENSA                       - Compiller: XCC           Target: Xtensa\n"
         " WIZC_PIC18                       - Compiller: WizC          Target: PIC18")
+elseif((FREERTOS_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_kernel_port) )
+    message(FATAL_ERROR " FREERTOS_PORT is set to A_CUSTOM_PORT. Please specify the custom port target with all necessary files. For example:\n"
+    " Assuming a directory of:\n"
+    "  FreeRTOSCustomPort/\n"
+    "    CMakeLists.txt\n"
+    "    port.c\n"
+    "    portmacro.h\n\n"
+    " Where FreeRTOSCustomPort/CMakeLists.txt is a modified version of:\n"
+    "   add_library(freertos_kernel_port STATIC)\n\n"
+    "   target_sources(freertos_kernel_port\n"
+    "     PRIVATE\n"
+    "       portcomm.c\n"
+    "       portmacro.h)\n\n"
+    "   target_include_directories(freertos_kernel_port\n"
+    "     PUBLIC\n"
+    "      .)\n\n"
+    "   taget_link_libraries(freertos_kernel_port\n"
+    "     PRIVATE\n"
+    "       freertos_kernel)")
 endif()
 
 add_subdirectory(portable)
diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt
index 9848adaf4..47dfe3fbb 100644
--- a/portable/CMakeLists.txt
+++ b/portable/CMakeLists.txt
@@ -1,5 +1,10 @@
 # FreeRTOS internal cmake file. Do not use it in user top-level project
 
+if (FREERTOS_PORT STREQUAL "A_CUSTOM_PORT")
+    message(STATUS "Using a custom FREERTOS_PORT.")
+    return()
+endif()
+
 add_library(freertos_kernel_port STATIC
     $<$<STREQUAL:${FREERTOS_PORT},BCC_16BIT_DOS_FLSH186>:
         BCC/16BitDOS/common/portcomn.c

phelter avatar Sep 21 '22 17:09 phelter

@paulbartell

Given that many of the port-specific bits are supplied in macros, I don't think that it makes much sense to have separate static library targets for the core kernel and ports.

Perhaps It makes more sense to provide these as an INTERFACE target for each port and then provide a single static library target if a particular port is selected and configured.

I agree. It only makes sense to have the ports as independent libraries if there is a need to support in a single project repo different compiles of the same FreeRTOS-Kernel with different ports. I don't think so as you have to configure multiple things which may vary - eg the compiler (via toolchain files) - and possibly other directories/drivers.

I'm adding a branch with the proposed changes for you to review.

phelter avatar Sep 29 '22 22:09 phelter

Addressed in #571

paulbartell avatar Dec 21 '22 19:12 paulbartell