Skip to content

CMake: better detection of memap dependencies #14205

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

Merged
merged 12 commits into from
Feb 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ endfunction()
# Parse toolchain generated map file of `target` and display a readable table format.
#
function(mbed_generate_map_file target)
find_package (Python3)
add_custom_command(
TARGET
${target}
Expand Down Expand Up @@ -234,7 +233,10 @@ endfunction()
function(mbed_set_post_build target)
mbed_validate_application_profile(${target})
mbed_generate_bin_hex(${target})
mbed_generate_map_file(${target})

if(HAVE_MEMAP_DEPS)
mbed_generate_map_file(${target})
endif()
endfunction()

# Ninja requires to be forced for response files
Expand Down
62 changes: 62 additions & 0 deletions tools/cmake/CheckPythonPackage.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright (c) 2020 ARM Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# CMake functions for checking for Python packages
# Requires PYTHON_EXECUTABLE to be defined. Call FindPython first!

# set OUTPUT_VAR to whether PACKAGENAME was found
function(check_python_package PACKAGENAME OUTPUT_VAR)
# can't have Python packages without Python!
if(NOT Python3_FOUND)
set(${OUTPUT_VAR} FALSE PARENT_SCOPE)
return()
endif()

set(NEED_TO_RUN_CHECK TRUE)

if(DEFINED ${OUTPUT_VAR})
if(${OUTPUT_VAR})
# if the python interpreter changed, we need to recheck
if("${PY_INTERP_FOR_${OUTPUT_VAR}}" STREQUAL "${Python3_EXECUTABLE}")
set(NEED_TO_RUN_CHECK FALSE)
endif()
endif()
endif()

if(NEED_TO_RUN_CHECK)
set(PY_INTERP_FOR_${OUTPUT_VAR} ${Python3_EXECUTABLE} CACHE INTERNAL "The python interpreter used to run the ${OUTPUT_VAR} check" FORCE)

execute_process(
COMMAND ${Python3_EXECUTABLE} -c "import ${PACKAGENAME}" RESULT_VARIABLE PACKAGECHECK_RESULT
)

if(${PACKAGECHECK_RESULT} EQUAL 0)
set(HAVE_PACKAGE TRUE)
else()
set(HAVE_PACKAGE FALSE)
endif()

if(HAVE_PACKAGE)
message(STATUS "Checking for Python package ${PACKAGENAME} -- found")
else()
message(STATUS "Checking for Python package ${PACKAGENAME} -- not found")
endif()

set(${OUTPUT_VAR} ${HAVE_PACKAGE} CACHE BOOL "Whether the Python package ${PACKAGENAME} was found" FORCE)
mark_as_advanced(${OUTPUT_VAR})
endif()
endfunction(check_python_package)

# check that PACKAGENAME can be imported, and print an error if not
function(verify_python_package PACKAGENAME)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently nowhere, but it can be a useful part of the module if we need it at some point.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also remove unused functionality, we can add it in the future if its needed (based on use case requirements).

I'll send separate patches after this one gets in, for review.


# we can just generate our own variable name
string(TOUPPER "HAVE_${PACKAGENAME}" HAVE_VAR_NAME)

check_python_package(${PACKAGENAME} ${HAVE_VAR_NAME})

if(NOT ${HAVE_VAR_NAME})
message(FATAL_ERROR "The required Python package ${PACKAGENAME} was not found in ${Python3_EXECUTABLE}. Please install it.")
endif()

endfunction(verify_python_package)
32 changes: 32 additions & 0 deletions tools/cmake/app.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,35 @@ enable_language(C CXX ASM)
# set executable suffix (has to be done after enabling languages)
# Note: This is nice to have, but is also required because STM32Cube will only work on files with a .elf extension
set(CMAKE_EXECUTABLE_SUFFIX .elf)

# Find Python
find_package(Python3 COMPONENTS Interpreter)
include(${CMAKE_CURRENT_LIST_DIR}/CheckPythonPackage.cmake)

# Check python packages from requirements.txt
file(STRINGS ${CMAKE_CURRENT_LIST_DIR}/requirements.txt PYTHON_REQUIREMENTS)
foreach(REQUIREMENT ${PYTHON_REQUIREMENTS})
# Look for a string from the start of each line that does not contain "<", ">", "=", or " ".
if(REQUIREMENT MATCHES "^([^<>= ]+)")
set(PACKAGE_NAME ${CMAKE_MATCH_1})
string(TOUPPER ${PACKAGE_NAME} PACKAGE_NAME_UCASE) # Ucase name needed for CMake variable
string(TOLOWER ${PACKAGE_NAME} PACKAGE_NAME_LCASE) # Lcase name needed for import statement

check_python_package(${PACKAGE_NAME_LCASE} HAVE_PYTHON_${PACKAGE_NAME_UCASE})
if(NOT HAVE_PYTHON_${PACKAGE_NAME_UCASE})
message(WARNING "Missing Python dependency ${PACKAGE_NAME}")
endif()
else()
message(FATAL_ERROR "Cannot parse line \"${REQUIREMENT}\" in requirements.txt")
endif()

endforeach()

# Check deps for memap
if(Python3_FOUND AND HAVE_PYTHON_INTELHEX AND HAVE_PYTHON_PRETTYTABLE)
set(HAVE_MEMAP_DEPS TRUE)
else()
set(HAVE_MEMAP_DEPS FALSE)
message(STATUS "Missing Python dependencies (python3, intelhex, prettytable) so the memory map cannot be printed")
endif()

1 change: 1 addition & 0 deletions tools/cmake/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
prettytable==0.7.2
future==0.16.0
Jinja2>=2.10.1,<2.11
intelhex>=2.3.0,<3.0.0