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

Target all HAL libraries for a family #322

Open
simoneruffini opened this issue May 15, 2023 · 10 comments
Open

Target all HAL libraries for a family #322

simoneruffini opened this issue May 15, 2023 · 10 comments

Comments

@simoneruffini
Copy link
Contributor

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
Copy link
Collaborator

atsju commented May 15, 2023

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.

@atsju atsju closed this as completed May 15, 2023
@simoneruffini
Copy link
Contributor Author

simoneruffini commented May 15, 2023

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
Copy link
Collaborator

Hish15 commented May 15, 2023

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
Copy link
Contributor Author

simoneruffini commented May 15, 2023

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
Copy link
Contributor Author

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 atsju reopened this May 16, 2023
@atsju
Copy link
Collaborator

atsju commented May 16, 2023

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
Copy link
Contributor Author

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
Copy link
Collaborator

atsju commented May 16, 2023

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.

  • why do you require that cmakelist is untouched during whole project ? This doesn't look like a requirement but as some side effect of other choices. In general cmakelist can evolve with sources and is versioned with them.
  • 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.

@simoneruffini
Copy link
Contributor Author

simoneruffini commented May 16, 2023

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
Copy link

david-drinn commented Jul 18, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants