Skip to content

zephyr: CMake portability fixes #6611

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
wants to merge 1 commit into from
Closed
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
108 changes: 83 additions & 25 deletions py/mkrules.cmake
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# CMake fragment for MicroPython rules

set(MICROPY_CONCAT_QUOTE_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/gen_qstrdefs_concat_quote.cmake")
set(MICROPY_CONCAT_DEQUOTE_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/gen_qstrdefs_concat_dequote.cmake")
set(MICROPY_PY_QSTRDEFS "${MICROPY_PY_DIR}/qstrdefs.h")
set(MICROPY_QSTRDEFS_CONCAT "${CMAKE_CURRENT_BINARY_DIR}/qstrdefs_concat.h")
set(MICROPY_GENHDR_DIR "${CMAKE_BINARY_DIR}/genhdr")
set(MICROPY_MPVERSION "${MICROPY_GENHDR_DIR}/mpversion.h")
set(MICROPY_MODULEDEFS "${MICROPY_GENHDR_DIR}/moduledefs.h")
set(MICROPY_QSTR_DEFS_LAST "${MICROPY_GENHDR_DIR}/qstr.i.last")
set(MICROPY_QSTR_DEFS_SPLIT "${MICROPY_GENHDR_DIR}/qstr.split")
set(MICROPY_QSTR_DEFS_COLLECTED "${MICROPY_GENHDR_DIR}/qstrdefs.collected.h")
set(MICROPY_QSTR_DEFS_PREPROCESSED_QUOTED "${MICROPY_GENHDR_DIR}/qstrdefs.preprocessed_quoted.h")
set(MICROPY_QSTR_DEFS_PREPROCESSED "${MICROPY_GENHDR_DIR}/qstrdefs.preprocessed.h")
set(MICROPY_QSTR_DEFS_GENERATED "${MICROPY_GENHDR_DIR}/qstrdefs.generated.h")

Expand Down Expand Up @@ -36,65 +40,119 @@ target_sources(${MICROPY_TARGET} PRIVATE
${MICROPY_QSTR_DEFS_GENERATED}
)

# Command to force the build of another command

add_custom_command(
OUTPUT MICROPY_FORCE_BUILD
COMMENT ""
COMMAND echo -n
)

# Generate mpversion.h
# Re-run CMake to recreate the git version data when the git repository is updated
if(EXISTS "${MICROPY_DIR}/.git/HEAD")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${MICROPY_DIR}/.git/HEAD")
endif()

add_custom_command(
OUTPUT ${MICROPY_MPVERSION}
COMMAND ${CMAKE_COMMAND} -E make_directory ${MICROPY_GENHDR_DIR}
COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/py/makeversionhdr.py ${MICROPY_MPVERSION}
DEPENDS MICROPY_FORCE_BUILD
# Generate mpversion.h at configuration time
file(MAKE_DIRECTORY "${MICROPY_GENHDR_DIR}")
execute_process(
COMMAND "${Python3_EXECUTABLE}" "${MICROPY_PY_DIR}/makeversionhdr.py" "${MICROPY_MPVERSION}"
COMMAND_ERROR_IS_FATAL
)

# Generate moduledefs.h
# This is currently hard-coded to support modarray.c only, because makemoduledefs.py doesn't support absolute paths

add_custom_command(
OUTPUT ${MICROPY_MODULEDEFS}
COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makemoduledefs.py --vpath="." ../../../py/modarray.c > ${MICROPY_MODULEDEFS}
DEPENDS ${MICROPY_MPVERSION}
${MICROPY_SOURCE_QSTR}
OUTPUT "${MICROPY_MODULEDEFS}"
COMMAND "${Python3_EXECUTABLE}" "${MICROPY_PY_DIR}/makemoduledefs.py" --vpath="." ../../../py/modarray.c > "${MICROPY_MODULEDEFS}"
DEPENDS "${MICROPY_MPVERSION}"
"${MICROPY_SOURCE_QSTR}"
COMMAND_EXPAND_LISTS
)

# Generate qstrs

get_property_and_add_prefix(micropython_includes_raw ${MICROPY_TARGET} INCLUDE_DIRECTORIES "-I")
process_flags(C micropython_includes_raw micropython_includes)
get_property_and_add_prefix(micropython_definitions_raw ${MICROPY_TARGET} COMPILE_DEFINITIONS "-D")
process_flags(C micropython_definitions_raw micropython_definitions)

set(includes -I$<JOIN:$<TARGET_PROPERTY:zephyr_interface,INTERFACE_INCLUDE_DIRECTORIES>,$<SEMICOLON>-I>)
set(system_includes -I$<JOIN:$<TARGET_PROPERTY:zephyr_interface,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>,$<SEMICOLON>-I>)
set(definitions -D$<JOIN:$<TARGET_PROPERTY:zephyr_interface,INTERFACE_COMPILE_DEFINITIONS>,$<SEMICOLON>-D>)

zephyr_get_compile_options_for_lang(C options)
# For add_custom_command to properly handle argument escaping in lists or generator expressions,
# the items have to separated by semicolons and not spaces. Zephyr uses spaces, so we need to then.
# see also https://gitlab.kitware.com/cmake/cmake/-/merge_requests/377
string(REGEX REPLACE "^ *(.*), (-?[a-zA-Z]*)>$" "\\1,$<SEMICOLON>\\2>" options ${options})

set(THE_FLAGS ${micropython_includes} ${micropython_definitions} ${includes} ${system_includes} ${definitions} ${options})


# If any of the dependencies in this rule change then the C-preprocessor step must be run.
# It only needs to be passed the list of MICROPY_SOURCE_QSTR files that have changed since
# it was last run, but it looks like it's not possible to specify that with cmake.
# It only needs to be passed the list of MICROPY_SOURCE_QSTR files that have changed since it was
# last run, but it looks like it's not possible to specify that with cmake.
add_custom_command(
OUTPUT ${MICROPY_QSTR_DEFS_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 ${CMAKE_C_COMPILER} -E ${THE_FLAGS} -DNO_QSTR ${MICROPY_SOURCE_QSTR} > ${MICROPY_QSTR_DEFS_LAST}
DEPENDS ${MICROPY_MODULEDEFS}
${MICROPY_SOURCE_QSTR}
VERBATIM
COMMAND_EXPAND_LISTS
)

add_custom_command(
OUTPUT ${MICROPY_QSTR_DEFS_SPLIT}
COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py split qstr ${MICROPY_GENHDR_DIR}/qstr.i.last ${MICROPY_GENHDR_DIR}/qstr _
COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py split qstr ${MICROPY_QSTR_DEFS_LAST} ${MICROPY_GENHDR_DIR}/qstr _
COMMAND touch ${MICROPY_QSTR_DEFS_SPLIT}
DEPENDS ${MICROPY_QSTR_DEFS_LAST}
VERBATIM
COMMAND_EXPAND_LISTS
)

add_custom_command(
OUTPUT ${MICROPY_QSTR_DEFS_COLLECTED}
COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py cat qstr _ ${MICROPY_GENHDR_DIR}/qstr ${MICROPY_QSTR_DEFS_COLLECTED}
DEPENDS ${MICROPY_QSTR_DEFS_SPLIT}
VERBATIM
COMMAND_EXPAND_LISTS
)

file(GENERATE OUTPUT "${MICROPY_CONCAT_QUOTE_SCRIPT}"
CONTENT "# Generate ${MICROPY_QSTRDEFS_CONCAT} with Q() quotes
file(REMOVE \"${MICROPY_QSTRDEFS_CONCAT}\")
foreach(file \"${MICROPY_PY_QSTRDEFS}\" \"${MICROPY_QSTR_DEFS_COLLECTED}\")
file(STRINGS \"\${file}\" CONTENTS)
foreach(line \${CONTENTS})
# Apply regex to quote Q()s
string(REGEX REPLACE \"^(Q\\\\(.*\\\\))\" \"\\\"\\\\1\\\"\" replaced \"\${line}\")
file(APPEND \"${MICROPY_QSTRDEFS_CONCAT}\" \"\${replaced}\\n\")
endforeach()
endforeach()
")

file(GENERATE OUTPUT "${MICROPY_CONCAT_DEQUOTE_SCRIPT}"
CONTENT "# Generate ${MICROPY_QSTR_DEFS_PREPROCESSED} from ${MICROPY_QSTR_DEFS_PREPROCESSED_QUOTED} with quotes removed
file(REMOVE \"${MICROPY_QSTR_DEFS_PREPROCESSED}\")
file(STRINGS \"${MICROPY_QSTR_DEFS_PREPROCESSED_QUOTED}\" CONTENTS)
foreach(line \${CONTENTS})
# Apply regex to dequote Q()s
string(REGEX REPLACE \"^\\\"(Q\\\\(.*\\\\))\\\"\" \"\\\\1\" replaced \"\${line}\")
file(APPEND \"${MICROPY_QSTR_DEFS_PREPROCESSED}\" \"\${replaced}\\n\")
endforeach()
")

add_custom_command(OUTPUT "${MICROPY_QSTRDEFS_CONCAT}"
COMMAND "${CMAKE_COMMAND}" -P "${MICROPY_CONCAT_QUOTE_SCRIPT}"
DEPENDS "${MICROPY_PY_QSTRDEFS}" "${MICROPY_QSTR_DEFS_COLLECTED}" "${MICROPY_CONCAT_QUOTE_SCRIPT}"
VERBATIM
)

add_custom_command(
OUTPUT ${MICROPY_QSTR_DEFS_PREPROCESSED}
COMMAND cat ${MICROPY_PY_QSTRDEFS} ${MICROPY_QSTR_DEFS_COLLECTED} | sed "s/^Q(.*)/\"&\"/" | ${CMAKE_C_COMPILER} -E ${MICROPY_CPP_FLAGS} - | sed "s/^\\\"\\(Q(.*)\\)\\\"/\\1/" > ${MICROPY_QSTR_DEFS_PREPROCESSED}
DEPENDS ${MICROPY_QSTR_DEFS_COLLECTED}
OUTPUT ${MICROPY_QSTR_DEFS_PREPROCESSED_QUOTED}
COMMAND ${CMAKE_C_COMPILER} -E ${THE_FLAGS} ${MICROPY_QSTRDEFS_CONCAT} > ${MICROPY_QSTR_DEFS_PREPROCESSED_QUOTED}
DEPENDS "${MICROPY_QSTRDEFS_CONCAT}"
VERBATIM
COMMAND_EXPAND_LISTS
)

add_custom_command(OUTPUT "${MICROPY_QSTR_DEFS_PREPROCESSED}"
COMMAND "${CMAKE_COMMAND}" -P "${MICROPY_CONCAT_DEQUOTE_SCRIPT}"
DEPENDS "${MICROPY_QSTR_DEFS_PREPROCESSED_QUOTED}" "${MICROPY_CONCAT_DEQUOTE_SCRIPT}"
VERBATIM
)

Expand Down