I want to start reading a file from a specific line. Cmake official docs suggest using file() with offset but I am not sure about its usage. The file that I want to read is test.mak:
# -----------------------------------------------------------------------------
## TEST
# -----------------------------------------------------------------------------
TEST_COMPONENTS ?= ABC DEF GHI
# SYMBOLS
SYMBOLS_PROJ ?= A002
SYMBOLS_LABEL ?= TEST_A002_FINAL
I have a cmake file (the function is from internet and it works with my use case) where i want to read the test.mak file starting from "#SYMBOLS" so that the macros defined before this line are ignored/skipped, and then i want to set the macros in my current cmake:
function(Fileread MKFile)
file(READ "${MKFile}" FileContents [OFFSET "# SYMBOLS"])
string(REPLACE "?" "" FileContents ${FileContents})
string(REPLACE "\\\n" "" FileContents ${FileContents})
string(REPLACE "\n" ";" FileLines ${FileContents})
list(REMOVE_ITEM FileLines "")
foreach(line ${FileLines})
string(REPLACE "=" ";" line_split ${line})
list(LENGTH line_split count)
if (count LESS 2)
message(STATUS "Skipping ${line}")
continue()
endif()
list(GET line_split -1 value)
string(STRIP "${value}" value)
separate_arguments(value)
list(REMOVE_AT line_split -1)
foreach(var_name ${line_split})
string(STRIP ${var_name} var_name)
set(${var_name} ${value} PARENT_SCOPE)
endforeach()
endforeach()
endfunction()
Fileread("test.mak")
The offset setting is not working as a result of which i am also getting the macro TEST_COMPONENTS which i don't need. NOTE: TEST_COMPONENTS is just an example, there are multiple lines of macro definitions before "# SYMBOLS" that i would like to skip. Thanks for any suggestions to solve this in advance.
Use file(STRINGS)
to read the lines of the text file into a list variable. You could then use list(POP_FRONT)
until you encounter a matching line.
# Line 1
# Line 2
# Line 3
# Line 4
file(STRINGS ${CMAKE_CURRENT_LIST_FILE} THIS_FILE)
set(REDUCTION_SUCCESS False)
while(THIS_FILE)
list(POP_FRONT THIS_FILE LINE)
if (LINE MATCHES "^# SYMBOLS.*")
set(REDUCED_FILE ${LINE} ${THIS_FILE})
set(REDUCTION_SUCCESS True)
break()
endif()
endwhile()
if (REDUCTION_SUCCESS)
# use the contents of the REDUCED_FILE variable
# (print all remaining lines for the purpose of demonstation)
foreach(_LINE IN LISTS REDUCED_FILE)
message(STATUS "${_LINE}")
endforeach()
else()
message(FATAL_ERROR "No line containing '# SYMBOLS' found")
endif()
Replace one of the # Line 1
comments with # SYMBOLS
to get a successful outcome. For simplicity this is just a cmake script that can be run with cmake -P script.cmake
. The script file parses itself.
If the number of lines to skip is known, you could simplify the logic after the file(STRINGS)
command to a single list(SUBLIST)
call.