From 0cf12dd59c9ddddbd602d4267410033cb5a9d265 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 23 Feb 2021 22:57:14 +0000 Subject: [PATCH] rp2: Add support for USER_C_MODULES to CMake build system. The parts that are generic are added to py/ so they can be used by other ports that use CMake. py/usermod.cmake: * Creates a usermod target to hang user C/CXX modules from. * Gathers sources from user C/CXX modules and libs for QSTR scan. ports/rp2/CMakeLists.txt: * Includes py/usermod.cmake. * Links the resulting usermod library to the MicroPython target. py/mkrules.cmake: Add cxxflags to qstr.i.last custom command for CXX modules: * MICROPY_CPP_FLAGS so CXX modules will find includes. * -DNO_QSTR to fix fatal error missing "genhdr/qstrdefs.generated.h". Usage: The rp2 port can be linked against user C modules by running: make USER_C_MODULES=/path/to/module/micropython.cmake CMake will print a list of included modules. Co-authored-by: Graham Sanderson Co-authored-by: Michael O'Cleirigh Signed-off-by: Phil Howard --- ports/rp2/CMakeLists.txt | 6 +++++ ports/rp2/Makefile | 8 ++++++- py/mkrules.cmake | 2 +- py/usermod.cmake | 52 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 py/usermod.cmake diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt index 3968194dc..3db0e6b62 100644 --- a/ports/rp2/CMakeLists.txt +++ b/ports/rp2/CMakeLists.txt @@ -27,6 +27,8 @@ project(${MICROPY_TARGET}) pico_sdk_init() +include(${MICROPY_DIR}/py/usermod.cmake) + add_executable(${MICROPY_TARGET}) set(MICROPY_QSTRDEFS_PORT @@ -80,6 +82,7 @@ set(MICROPY_SOURCE_PORT set(MICROPY_SOURCE_QSTR ${MICROPY_SOURCE_PY} ${MICROPY_SOURCE_EXTMOD} + ${MICROPY_SOURCE_USERMOD} ${MICROPY_DIR}/lib/utils/mpirq.c ${MICROPY_DIR}/lib/utils/sys_stdio_mphal.c ${PROJECT_SOURCE_DIR}/machine_adc.c @@ -142,7 +145,10 @@ target_sources(${MICROPY_TARGET} PRIVATE ${MICROPY_SOURCE_PORT} ) +target_link_libraries(${MICROPY_TARGET} usermod) + target_include_directories(${MICROPY_TARGET} PRIVATE + ${MICROPY_INC_USERMOD} "${PROJECT_SOURCE_DIR}" "${MICROPY_DIR}" "${CMAKE_BINARY_DIR}" diff --git a/ports/rp2/Makefile b/ports/rp2/Makefile index 08cd53dcc..3358c4cca 100644 --- a/ports/rp2/Makefile +++ b/ports/rp2/Makefile @@ -6,8 +6,14 @@ BUILD = build $(VERBOSE)MAKESILENT = -s +CMAKE_ARGS = + +ifdef USER_C_MODULES +CMAKE_ARGS += -DUSER_C_MODULES=${USER_C_MODULES} +endif + all: - [ -d $(BUILD) ] || cmake -S . -B $(BUILD) -DPICO_BUILD_DOCS=0 + [ -d $(BUILD) ] || cmake -S . -B $(BUILD) -DPICO_BUILD_DOCS=0 ${CMAKE_ARGS} $(MAKE) $(MAKESILENT) -C $(BUILD) clean: diff --git a/py/mkrules.cmake b/py/mkrules.cmake index 9c4c4afab..f20240c62 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -69,7 +69,7 @@ add_custom_command( # it was last run, but it looks like it's not possible to specify that with cmake. add_custom_command( OUTPUT ${MICROPY_QSTRDEFS_LAST} - COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py pp ${CMAKE_C_COMPILER} -E output ${MICROPY_GENHDR_DIR}/qstr.i.last cflags ${MICROPY_CPP_FLAGS} -DNO_QSTR sources ${MICROPY_SOURCE_QSTR} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py pp ${CMAKE_C_COMPILER} -E output ${MICROPY_GENHDR_DIR}/qstr.i.last cflags ${MICROPY_CPP_FLAGS} -DNO_QSTR cxxflags ${MICROPY_CPP_FLAGS} -DNO_QSTR sources ${MICROPY_SOURCE_QSTR} DEPENDS ${MICROPY_MODULEDEFS} ${MICROPY_SOURCE_QSTR} VERBATIM diff --git a/py/usermod.cmake b/py/usermod.cmake new file mode 100644 index 000000000..853276283 --- /dev/null +++ b/py/usermod.cmake @@ -0,0 +1,52 @@ +# Create a target for all user modules to link against. +add_library(usermod INTERFACE) + +function(usermod_gather_sources SOURCES_VARNAME INCLUDE_DIRECTORIES_VARNAME INCLUDED_VARNAME LIB) + if (NOT ${LIB} IN_LIST ${INCLUDED_VARNAME}) + list(APPEND ${INCLUDED_VARNAME} ${LIB}) + + # Gather library sources + get_target_property(lib_sources ${LIB} INTERFACE_SOURCES) + if (lib_sources) + list(APPEND ${SOURCES_VARNAME} ${lib_sources}) + endif() + + # Gather library includes + get_target_property(lib_include_directories ${LIB} INTERFACE_INCLUDE_DIRECTORIES) + if (lib_include_directories) + list(APPEND ${INCLUDE_DIRECTORIES_VARNAME} ${lib_include_directories}) + endif() + + # Recurse linked libraries + get_target_property(trans_depend ${LIB} INTERFACE_LINK_LIBRARIES) + if (trans_depend) + foreach(SUB_LIB ${trans_depend}) + usermod_gather_sources( + ${SOURCES_VARNAME} + ${INCLUDE_DIRECTORIES_VARNAME} + ${INCLUDED_VARNAME} + ${SUB_LIB}) + endforeach() + endif() + + set(${SOURCES_VARNAME} ${${SOURCES_VARNAME}} PARENT_SCOPE) + set(${INCLUDE_DIRECTORIES_VARNAME} ${${INCLUDE_DIRECTORIES_VARNAME}} PARENT_SCOPE) + set(${INCLUDED_VARNAME} ${${INCLUDED_VARNAME}} PARENT_SCOPE) + endif() +endfunction() + +# Include CMake files for user modules. +if (USER_C_MODULES) + foreach(USER_C_MODULE_PATH ${USER_C_MODULES}) + message("Including User C Module(s) from ${USER_C_MODULE_PATH}") + include(${USER_C_MODULE_PATH}) + endforeach() +endif() + +# Recursively gather sources for QSTR scanning - doesn't support generator expressions. +usermod_gather_sources(MICROPY_SOURCE_USERMOD MICROPY_INC_USERMOD found_modules usermod) + +# Report found modules. +list(REMOVE_ITEM found_modules "usermod") +list(JOIN found_modules ", " found_modules) +message("Found User C Module(s): ${found_modules}")