使用 CMAKE 从特定行开始读取文件

Start reading file from a specific line using CMAKE

我想从特定行开始读取文件。 Cmake 官方文档建议使用 file() with offset 但我不确定它的用法。 我要读取的文件是 test.mak:

# -----------------------------------------------------------------------------
## TEST
# -----------------------------------------------------------------------------
TEST_COMPONENTS      ?= ABC DEF GHI

# SYMBOLS
SYMBOLS_PROJ ?= A002
SYMBOLS_LABEL   ?= TEST_A002_FINAL

我有一个 cmake 文件(该函数来自互联网,它适用于我的用例),我想在其中读取从“#SYMBOLS”开始的 test.mak 文件,以便在此行之前定义的宏是 ignored/skipped,然后我想在我当前的 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")

偏移设置不起作用,因此我也得到了我不需要的宏 TEST_COMPONENTS。注意:TEST_COMPONENTS 只是一个例子,在“# SYMBOLS”之前有多行宏定义我想跳过。感谢您提出任何提前解决此问题的建议。

使用file(STRINGS)将文本文件的行读入列表变量。然后您可以使用 list(POP_FRONT) 直到遇到匹配的行。

# 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()

将其中一条 # Line 1 评论替换为 # SYMBOLS 以获得成功的结果。为简单起见,这只是一个可以 运行 和 cmake -P script.cmake 的 cmake 脚本。脚本文件自行解析。


如果知道要跳过的行数,您可以将 file(STRINGS) 命令后的逻辑简化为单个 list(SUBLIST) 调用。