Skip to content

cmake build fails if more than one build_sketch definition is used #2282

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

Closed
ddowling opened this issue Feb 21, 2024 · 7 comments · Fixed by #2283
Closed

cmake build fails if more than one build_sketch definition is used #2282

ddowling opened this issue Feb 21, 2024 · 7 comments · Fixed by #2283
Labels
enhancement New feature or request

Comments

@ddowling
Copy link
Contributor

ddowling commented Feb 21, 2024

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.

@fpistm
Copy link
Member

fpistm commented Feb 21, 2024

@massonal any input for this? Did you try build with several sketches? Thanks.

@massonal
Copy link
Contributor

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 ;)

@ddowling
Copy link
Contributor Author

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.

@massonal
Copy link
Contributor

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 ?

@ddowling
Copy link
Contributor Author

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.

@massonal
Copy link
Contributor

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?

@ddowling
Copy link
Contributor Author

@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()

@fpistm fpistm added enhancement New feature or request and removed New feature labels Jul 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants