-
Notifications
You must be signed in to change notification settings - Fork 946
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
[question] how to configure Pico SDK to work Conan and CMake projects #16193
Comments
Assuming that the CMakeLists is configured like documented here: https://github.com/raspberrypi/pico-sdk/tree/master, with a
Once the path to the SDK is located, I suspect it eventually set this as the but since it's already set by Conan upon invoking CMake, then it is skipped - and some mismatched configuration happens. |
Yes, that is the problem I think. My initial thoughts were that I might need to create a custom Toolchain for this, but I have no idea on how to do this for the SDK. |
Here is a somewhat minimal example on what our CMakeLists look like in our RP2040 projects: CMakeLists.txtcmake_minimum_required(VERSION 3.13...3.27)
include(FetchContent)
# PICO_SDK ------------------------------------------------------------------------------
# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
if(NOT DEFINED $ENV{PICO_SDK_PATH}) # Pull in Raspberry Pi Pico SDK (must be before project)
message(STATUS "PICO_SDK_PATH not defined.")
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/deps/pico-sdk)
message(STATUS "Using path: ${CMAKE_CURRENT_BINARY_DIR}/deps/pico-sdk")
include(${CMAKE_CURRENT_BINARY_DIR}/deps/pico-sdk/pico_sdk_init.cmake)
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake)
message(STATUS "Using path: ${CMAKE_CURRENT_LIST_DIR}")
include(${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake)
else()
message(FATAL_ERROR "PICO_SDK_PATH not defined and pico_sdk_import.cmake not found.")
endif()
else()
message(STATUS "PICO_SDK_PATH defined. Using path: $ENV{PICO_SDK_PATH}")
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
endif()
set(PICO_BOARD pico CACHE STRING "Board type")
if (PICO_SDK_VERSION_STRING VERSION_LESS "1.5.0")
message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.5.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()
project(pico-conan-blink LANGUAGES C CXX ASM VERSION 0.0.1)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# create disassembly with source
function(pico_add_dis_output2 TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_OBJDUMP} -S $<TARGET_FILE:${TARGET}> >$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.dis2)
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND arm-none-eabi-size ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.elf
VERBATIM
)
endfunction()
# LIBRARIES ------------------------------------------------------------------------------
# https://stackoverflow.com/questions/7787823/cmake-how-to-get-the-name-of-all-subdirectories-of-a-directory
macro(SUBDIRLIST result curdir)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
foreach(child ${children})
if(IS_DIRECTORY ${curdir}/${child} AND EXISTS ${curdir}/${child}/CMakeLists.txt)
list(APPEND dirlist ${child})
endif()
endforeach()
set(${result} ${dirlist})
endmacro()
# Add each library in the lib directory
SUBDIRLIST(LIBDIRS ${CMAKE_CURRENT_LIST_DIR}/lib)
foreach(libdir ${LIBDIRS})
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/lib/${libdir})
endforeach()
# GITVERSION ------------------------------------------------------------------------------
FetchContent_Declare(cmake_git_version_tracking
GIT_REPOSITORY https://github.com/andrew-hardin/cmake-git-version-tracking.git
GIT_TAG 904dbda1336ba4b9a1415a68d5f203f576b696bb
)
FetchContent_MakeAvailable(cmake_git_version_tracking)
# BUILD ------------------------------------------------------------------------------
# Device type configuration
# Check if the build type is Debug
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
# Add compile options for Debug build
add_compile_options(-g) # include debug info
add_compile_options(-O0) # no optimization
add_compile_options(-fno-inline) # no inlining
add_compile_definitions(DEBUG) # define DEBUG
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# Add compile options for Release build
add_compile_options(-O3) # optimize for speed
add_definitions(-DFW_VERSION_MAJOR=${PROJECT_VERSION_MAJOR})
add_definitions(-DFW_VERSION_MINOR=${PROJECT_VERSION_MINOR})
add_definitions(-DFW_VERSION_PATCH=${PROJECT_VERSION_PATCH})
endif()
# Custom Conan package dependencies
# E.g.: find_package(lex-common REQUIRED)
# Add executable. Default name is the project name, version 0.1
add_executable(${PROJECT_NAME} src/main.cpp)
set_target_properties(${PROJECT_NAME} PROPERTIES
CMAKE_C_STANDARD 11
CMAKE_CXX_STANDARD 17
)
# Add the standard include files to the build
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/inc
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
# compiler flags
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
-fno-exceptions
-fno-check-new
$<$<COMPILE_LANGUAGE:CXX>:-fno-enforce-eh-specs>
-g
-ffunction-sections
-fdata-sections
-O3
-funroll-loops
$<$<COMPILE_LANGUAGE:CXX>:-Wno-psabi> # NOTE Compiling with GCC 7.1 or later, so can ignore ABI compatibility warnings when they come up (-Wpsabi)
-Wno-unknown-pragmas
-Werror
-Wall
)
target_compile_definitions(${PROJECT_NAME} PRIVATE
${DEVICE_TYPE}
PICO_HEAP_SIZE=4096
PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64
)
# select linker script
# pico_set_binary_type(${PROJECT_NAME} copy_to_ram)
# Generate PIO headerss here if necessary
# pico_generate_pio_header(... ${CMAKE_CURRENT_LIST_DIR}/pio/...)
pico_set_program_name(${PROJECT_NAME} "${PROJECT_NAME}")
pico_set_program_version(${PROJECT_NAME} "0.1")
pico_enable_stdio_uart(${PROJECT_NAME} 0)
pico_enable_stdio_usb(${PROJECT_NAME} 1)
#pico_add_extra_outputs(${PROJECT_NAME})
#pico_add_dis_output2(${PROJECT_NAME})
file(GLOB SOURCES_CPP "src/*.cpp")
file(GLOB SOURCES_C "src/*.c")
target_sources(${PROJECT_NAME} PRIVATE
${SOURCES_C}
${SOURCES_CPP}
)
# Add the standard library to the build
target_link_libraries(${PROJECT_NAME} PRIVATE
pico_stdlib
)
# linker options
target_link_options(${PROJECT_NAME}
PRIVATE "LINKER:--print-memory-usage"
) And here is a somewhat minimal conanfile.pyfrom conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.scm import Git
from conan.tools.files import get
class BlinkRecipe(ConanFile):
name = "pico-conan-blink"
version = "0.0.1"
package_type = "application"
arch = "armv6"
# Optional metadata
license = ""
author = ""
description = "Conan + Pico SDK Toolchain example with blink code"
# Binary configuration
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False],
"parallel": [True, False]}
default_options = {"shared": False,
"parallel": True}
# Sources are located in the same place as this recipe, copy them to the recipe
exports_sources = "src/*", "CMakeLists.txt"
def layout(self):
cmake_layout(self, src_folder=".", build_folder="build")
def source(self):
# get(self, "https://github.com/raspberrypi/pico-sdk/archive/refs/tags/1.5.1.tar.gz", destination="deps/pico-sdk", strip_root=True)
pass
def requirements(self):
# Any custom static library packages go here
pass
def build_requirements(self):
pass
# def layout(self):
# self.folders.source = "src"
# self.folders.build = "build"
# self.cpp.source.includedirs = ["inc"]
def generate(self):
deps = CMakeDeps(self)
deps.generate()
tc = CMakeToolchain(self)
tc.extra_cflags = ["--mcpu=cortex-m0plus", "-mthumb"]
tc.extra_cxxflags = ["--mcpu=cortex-m0plus", "-mthumb"]
tc.preprocessor_definitions["PICO_SDK_PATH"] = "deps/pico-sdk"
tc.generate()
def build(self):
get(self, "https://github.com/raspberrypi/pico-sdk/archive/refs/tags/1.5.1.tar.gz", destination="deps/pico-sdk", strip_root=True)
common_cmake_args = []
cmake = CMake(self)
cmake.configure(cli_args=common_cmake_args)
if self.options.parallel:
common_cmake_args += ["--parallel"]
cmake.build(cli_args=common_cmake_args) |
There are two Conan features where you can override the behaviour of the Conan-generated toolchain:
You can pass this either:
|
I've added Build log
I have these lines in the CMakeLists in an attempt to circumvent compiler-check errors set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1) But it doesn't work that way, as seen in the above build error. |
Without the COMPILER_WORKS circumvention, I get the following: Build log
|
I suspect I have a similar error as described here: Apparently, some parts (like ELF2UF2) require a native compiler and not the Allthough I have commented out the usage of the additional outputs, I believe that the error is related to the pico_sdk only getting the compiler configuration defined in conan and this might not work for all cases. I believe somehow this behaviour of using a different compiler for a necessary tool used in the Pico SDK is broken when using Conan, but when building normally it gets resolved fine.
I should mention, I do not mind having to compile the SDK with the project, my problem solely lies in the face that it does not compile when run through conan due to misconfigurations occuring with As a note, the build does work without conan: Build logConfigure:
Build:
|
According to raspberrypi/pico-sdk#1693 (comment) I can get rid of the errors caused by I then skip the The end result is further build errors, and I'm at a loss at this point why the compilation with Conan produces all of these errors, which do not occur without it. From my perspective, I've checked these boxes:
Build log
I then suspected there's further misconfiguration regarding the architecture, since these errors are weird and the architecture "normally" is configured when using However that doesn't seem to be the case when using conan, so I've manually configured some flags in the profile: [conf]
tools.cmake.cmaketoolchain:user_toolchain=["$ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake"]
tools.build:cflags=["-mcpu=cortex-m0plus", "-mthumb", "-march=armv6-m"]
tools.build:cxxflags=["-mcpu=cortex-m0plus -mthumb", "-march=armv6-m"] And all of a sudden, we see this: Build log
Main issue is solved, but my question remains: What the hell does conan do differently that these things are not configured, EVEN THOUGH they should be when |
What is your question?
From: https://cpplang.slack.com/archives/C41CWV9HA/p1714639717500339
Profile:
Results in error:
Have you read the CONTRIBUTING guide?
The text was updated successfully, but these errors were encountered: