Arduino_Core_STM32
Arduino_Core_STM32 copied to clipboard
cmake build fails if more than one build_sketch definition is used
I am trying to build multiple sketches using a project wide CMakeLists.txt file. If I call the build_sketch() function with each of the targets then cmake reports an error about duplicated targets:
...
Make Error at /home/dpd/.arduino15/packages/STMicroelectronics/hardware/stm32/2.7.1/variants/STM32F1xx/F103C8T_F103CB(T-U)/CMakeLists.txt:5 (add_library):
add_library cannot create target "variant" because another target with the
same name already exists. The existing target is an interface library
created in source directory
"/home/dpd/.arduino15/packages/STMicroelectronics/hardware/stm32/2.7.1/variants/STM32F1xx/F103C8T_F103CB(T-U)".
See documentation for policy CMP0002 for more details.
...
I have tried various cmake property settings but the error persists. I was able to get the builds to work by putting an if (NOT TARGET variant)
guard around the add_subdirectory calls in build_sketch.cmake.
*** build_sketch.cmake.orig 2024-02-21 17:32:23.290460959 +1100
--- build_sketch.cmake 2024-02-21 17:33:09.851221766 +1100
***************
*** 6,14 ****
include(set_base_arduino_config)
function(build_sketch)
! add_subdirectory(${BUILD_VARIANT_PATH} ./variant)
! add_subdirectory(${BUILD_CORE_PATH} ./cores/arduino)
! add_subdirectory(${BUILD_LIB_PATH} ./libraries)
cmake_parse_arguments(PARSE_ARGV 0 SKBD "" "TARGET" "SOURCES;DEPENDS")
--- 6,17 ----
include(set_base_arduino_config)
function(build_sketch)
! if (NOT TARGET variant)
! add_subdirectory(${BUILD_VARIANT_PATH} ./variant)
! add_subdirectory(${BUILD_CORE_PATH} ./cores/arduino)
! add_subdirectory(${BUILD_LIB_PATH} ./libraries)
! endif()
!
cmake_parse_arguments(PARSE_ARGV 0 SKBD "" "TARGET" "SOURCES;DEPENDS")
If there is a better solution then I would love to know otherwise I can submit a pull request.
@massonal any input for this? Did you try build with several sketches? Thanks.
Hello,
IIRC build_sketch()
creates build targets with specific names to handle the Arduino workflow.
These targets always have the same conventional name, so that they can be more easily integrated into the rest of the project. (variant
is one, there are others.)
Unfortunately, this means than no more than one sketch is supported per CMake project.
I think it's possible to change the name of the conventional targets to include some sketch-specific prefix. If you're interested in developing this, please feel free! - assuming @fpistm agrees on the idea ;)
The targets that cause a clash seem to be more dependant on the variant selected and this is controlled by set_board and should not really change on a per sketch basis. I thin redefining them in each sketch is the issue.
You're right. I have studied the issue in a bit more depth, and the limitation you're running into is that each variant has its own CMakeLists.txt file which defines a target named variant
.
The simplest solution is, I think, to move the add_subdirectory()
calls you pointed out earlier outside of build_sketch()
(directly at file level, under include(set_base_arduino_config)
).
This would have to be thoroughly documented in the wiki, however:
- importing
build_sketch.cmake
has side-effects - importing
build_sketch.cmake
should only happen once - having several sketches with different targets / configs is not supported.
What do you think about this, @ddowling @fpistm ?
Moving the add_subdirectory()
calls out of the function definition works in my use-case. If we are concerned about importing build_sketch.cmake more than once the we could use include_guard()
on the file. I understand having different configs is not supported but I don't think this would be a very common case. If you were building for different boards or settings this can be handled by having different build directories where cmake is run with different defines.
The case I am trying to address is a library with multiple small programs to unit test the functionality and to provide some user examples. When doing embedded development I like to keep a few very small and simple test programs around for when the whole board just starts misbehaving. You need this to determine if you are fighting a software or hardware issue.
Hey, I'm glad this solution works for you. Also, I did not know about include_guard()
; it would definitely be a good addition in most files in stm32duino's CMake framework.
Do you want to implement these changes and propose a pull request?
@massonal I just noticed another issue in sketch_preprocess_sources.cmake
. If you have an .ino file in a subdirectory the dependency fails. Everything is setup correctly but the filename without the flattened ${CMAKE_CURRENT_BINARY_DIR}
path is added to the SRCLIST
.
I will get a pull request together with these changes.
*** sketch_preprocess_sources.cmake.orig 2024-02-21 20:52:30.297138663 +1100
--- sketch_preprocess_sources.cmake 2024-02-21 21:02:28.738043288 +1100
***************
*** 27,33 ****
COMPILE_OPTIONS "-include;Arduino.h;-include;${SRCFILE}.h"
OBJECT_DEPENDS "${SRCFILE}.h"
)
! list(APPEND SRCLIST ${SRCFILE}.cpp)
else()
list(APPEND SRCLIST ${SRCFILE})
endif()
--- 27,33 ----
COMPILE_OPTIONS "-include;Arduino.h;-include;${SRCFILE}.h"
OBJECT_DEPENDS "${SRCFILE}.h"
)
! list(APPEND SRCLIST ${CMAKE_CURRENT_BINARY_DIR}/${SRC_BASE_NAME}.cpp)
else()
list(APPEND SRCLIST ${SRCFILE})
endif()