ObKo / stm32-cmake

CMake for stm32 developing.
MIT License
1.2k stars 340 forks source link

Target all HAL libraries for a family #322

Open simoneruffini opened 1 year ago

simoneruffini commented 1 year ago

Is it possible to target all hall libraries of a device via something like:

target_link_libraries(executable_name
HAL::STM32::F4

so that each time a new peripheral is used the makefile won't need changes?

atsju commented 1 year ago

Yes. Supposing you talk about cmakefile and not makefile. Only drawback is that you will build some files that you not need thus increasing build time.

simoneruffini commented 1 year ago

Yes, I was talking about cmake file, but I can't make it work. This is my CMakeLists.txt file

# Necessary tag
cmake_minimum_required(VERSION 3.16)
cmake_path(SET STM32_CUBE_F4_PATH "./")
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Lib/stm32-cmake/cmake/stm32_gcc.cmake)

project(tlb_battery)
enable_language(C ASM)

find_package(CMSIS COMPONENTS STM32F446RET REQUIRED) 

find_package(HAL COMPONENTS STM32F4 REQUIRED)

set(PROJECT_INCLUDE_DIRECTORIES 
    ${CMAKE_CURRENT_SOURCE_DIR}/Core/Inc)

file(GLOB_RECURSE PROJECT_C_SOURCES FOLLOW_SYMLINKS
    ${CMAKE_CURRENT_SOURCE_DIR}/Core/Src/*.c)

# Define the executable variable (name of the compiled output)
set(EXECUTABLE ${PROJECT_NAME})

# Generate the Executable target
add_executable(${EXECUTABLE})

target_compile_definitions(${EXECUTABLE} PRIVATE
    STM32F446RET
    USE_HAL_DRIVER)

target_sources(${EXECUTABLE} PRIVATE
    ${PROJECT_C_SOURCES})

target_include_directories(${EXECUTABLE} PRIVATE
    ${PROJECT_INCLUDE_DIRECTORIES}
)

stm32_add_linker_script(${EXECUTABLE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/STM32F446RETx_FLASH.ld)

target_link_libraries(${EXECUTABLE}
    CMSIS::STM32::F446xx # this target adds common includes, compiler flags and startup file (TODO: change to STM32::F4, startup file should be added manually)
    #CMSIS::STM32::F4
    #HAL::STM32::F4::RCC
    #HAL::STM32::F4::CORTEX
    #HAL::STM32::F4::GPIO
    #HAL::STM32::F4::TIM
    #HAL::STM32::F4::TIMEx
    #HAL::STM32::F4::ADC # include all drivers for the f4 family
    #HAL::STM32::F4::CAN
    #HAL::STM32::F4::UART
    HAL::STM32::F4
    STM32::Nano
    STM32::NoSys
    #STM32::Nano::FloatPrintf
)

stm32_generate_binary_file(${EXECUTABLE})
stm32_generate_hex_file(${EXECUTABLE})

stm32_print_size_of_target(${EXECUTABLE})

I run the cmake and get a list of errors at linking time (the custom linker used is the same provided with the cmsis just in a different position since I'm using an STMCubeMX generated project) For example:

/lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld: CMakeFiles/tlb_battery.dir/Core/Src/adc.c.obj: in function `MX_ADC1_Init':
Hish15 commented 1 year ago

Actually this is not possible out of the box. This goes againt cmake's target approach. Nothing is included, everything is neatly encapsulated. You might be able to hack something together using cmake's BUILDSYSTEM_TARGETS. But again, don't do this. You will not have to change this that often anyways .

simoneruffini commented 1 year ago

Unfortunately I have a use case where the development team can't change the way it used to work. Since the stm32-vscode plugin does that in the make file I need to re-create this feature in the cmake.

Therefore, do I need to hack around in the stm32-cmake library or in my makefile?

Can we re-open the issue?

simoneruffini commented 1 year ago

I would mention #315 as a way to auto-define what peripheral needs to be compiled and what not? Can the user just comments out the used peripherals in stm32f<family>xx_hal_conf.h and cmake can auto infer what to compile based on that file? I think the vscode extension stm32-vscode does exactly that to understand what to add in the generated makefile (it doesn't autocompile all the targets as I thought)

atsju commented 1 year ago

Cmake, make, VScode and cubeMX are different tools that may not play well together. They are different way to manage projects.

I'm not sure to fully understand your need. Are you confortable with cmake ?

As a side note, ideally CubeMX would provide a way to generate Cmake projects and we would not even need this repo. CubeMX is a great tool, but people here are (in general) more in a mindset where they avoid using this type of tools and want to have full control over code. This does not play well with tools that want to control same things.

simoneruffini commented 1 year ago

Yes I'm comfortable with cmake but my team uses CubeMX for code generation. For now this is not a problem because stm32-cmake can be used alongside CubeMX. My previous example (vscode plugin) was just to show how other tools approach this problem: "less user interaction with the [c]makefile and more autogeneration". I think in fact vscode reads the stm32fXxx_hal_conf.h file to define which targets to compile and then generates the makefile accordingly. Therefore, since compiling all targets seems anti cmake maybe this approach can be implemented somehow?

atsju commented 1 year ago

What you propose is probably possible but would require work and is not current approach. The idea itself is not bad.

If you don't care about compile time, just enable all peripheral in stm32fXxx_hal_conf.h and add all corresponding targets in cmakelists. Again, I'm still not sure to fully understand your need.

simoneruffini commented 1 year ago

My use case is to have a somewhat stable CMAkeList file that needs little change from projet to project (the developer must learn cmake but not the library so much to understand it's inner working). Idealy for future projects I could use the cmake file that I provided in this issue, change the device family name and a new project can be compiled.

If you don't care about compile time, just enable all peripheral in stm32fXxx_hal_conf.h and add all corresponding targets in cmakelists. Again, I'm still not sure to fully understand your need.

I can't do that: if I want a stable cmakefile that can be used as a template for all (no dualcore or wireless) stm devices I need to know which peripherals are available, and that information is known by the stm32-cmake library only. So I can't write a cmake that has all the HAL drivers as targets, some of them could not be available on a different platform.

what doesn't work exactly ? You shared a cmakelist and a partial error line. This is not enough for us to reproduce something and help you.

@atsju previously said that I can just add HAL::STM32::F4 and all HAL drivers for that family will be included in compilation, this doesn't happen. For what regards an example to test the code: this repo. Comment out the HAL::STM32::F4::<peripheral> targets and leave only the HAL::STM32::F4 one. It will not compile.

david-drinn commented 4 months ago

I don't think there's anything preventing you from creating your own cmake include file, and in it you could define a library target like you're thinking, one that links all the peripheral targets. Then your end users just need to link to your new one, and automatically get all the others.