Skip to content

Commit

Permalink
cmake: fixing toolchain_parse_make_rule to correctly handle \ files
Browse files Browse the repository at this point in the history
Fixes: #37637

toolchain_parse_make_rule() parses depfiles and converted `\\` to the
CMake list separator `;`.

However, gcc -M might create depfiles with windows path separator `\`
causing this conversion to fail, as a path like:
c:\...\zephyr\samples\drivers\led_ws2812\nrf52-bindings.h

resulting in a file list as:
c:;...;zephyr;samples;drivers;led_ws2812;nrf52-bindings.h

which results in a CMake configure dependency to be added to `C:`.
As C: is always newer than the build.ninja file, this resulted in
continues CMake re-invocation.

As a small side-note, the `\` in file name did only occur in situations
where a relative past had been used elsewhere in the build system, such
as here:
https://github.com/zephyrproject-rtos/zephyr/blob/\
c3050a5/samples/drivers/led_ws2812/\
boards/nrf52dk_nrf52832.overlay#L9

To ensure proper handling of files, then all files are converted to
CMake paths, that is with forward slashes: `/`

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
  • Loading branch information
tejlmand authored and cfriedt committed Sep 11, 2021
1 parent 92f0f70 commit 14b6314
Showing 1 changed file with 16 additions and 11 deletions.
27 changes: 16 additions & 11 deletions cmake/extensions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1797,30 +1797,35 @@ endfunction()
# The argument 'include_files' is an output parameter with the result
# of parsing the include files.
function(toolchain_parse_make_rule input_file include_files)
file(READ ${input_file} input)
file(STRINGS ${input_file} input)

# The file is formatted like this:
# empty_file.o: misc/empty_file.c \
# nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts \
# nrf52840_qiaa.dtsi

# Get rid of the backslashes
string(REPLACE "\\" ";" input_as_list ${input})
# The dep file will contain `\` for line continuation.
# This results in `\;` which is then treated a the char `;` instead of
# the element separator, so let's get the pure `;` back.
string(REPLACE "\;" ";" input_as_list ${input})

# Pop the first line and treat it specially
list(GET input_as_list 0 first_input_line)
list(POP_FRONT input_as_list first_input_line)
string(FIND ${first_input_line} ": " index)
math(EXPR j "${index} + 2")
string(SUBSTRING ${first_input_line} ${j} -1 first_include_file)
list(REMOVE_AT input_as_list 0)

list(APPEND result ${first_include_file})
# Remove whitespace before and after filename and convert to CMake path.
string(STRIP "${first_include_file}" first_include_file)
file(TO_CMAKE_PATH "${first_include_file}" first_include_file)
set(result "${first_include_file}")

# Add the other lines
list(APPEND result ${input_as_list})

# Strip away the newlines and whitespaces
list(TRANSFORM result STRIP)
# Remove whitespace before and after filename and convert to CMake path.
foreach(file ${input_as_list})
string(STRIP "${file}" file)
file(TO_CMAKE_PATH "${file}" file)
list(APPEND result "${file}")
endforeach()

set(${include_files} ${result} PARENT_SCOPE)
endfunction()
Expand Down

0 comments on commit 14b6314

Please sign in to comment.