使用 CMake 生成自定义头文件

Generate custom header file with CMake

我想生成一个自定义头文件,想知道 CMake 是否有一些我可以在不编写自己的生成器的情况下使用的东西。它会有一些 "one time" 项和一些我需要基于循环生成的项。

例如,所需的输出如下所示:

//One time stuff
#define ABC 1
#define DEF 2
#define GHI 3
#define JKL 4

//Stuff generated in loop

//Iteration with params Item1, 1, 2 
const int prefix_Item1_1 = 2;
const int prefix2_1_2 = 0;

//Iteration with params Item2, 3, 4 
const int prefix_Item2_3 = 4;
const int prefix2_3_4 = 0;

//Iteration with params Item5, 6, 7 
const int prefix_Item5_6 = 7;
const int prefix2_6_7 = 0;

对于输入,我将以某种形式提供以下内容:

Item1, 1, 2 
Item2, 3, 4
Item5, 6, 7

CMake 提供了一些用于在配置阶段生成和写入文件的实用程序。首先,我们可以将 "One time stuff" 放入模板文件中,然后使用 configure_file() 从中生成头文件:

# Generate header.hpp from your template file header.hpp.in
configure_file(${CMAKE_CURRENT_LIST_DIR}/header.hpp.in 
    ${CMAKE_CURRENT_LIST_DIR}/header.hpp COPYONLY
)

模板文件 header.hpp.in 可以简单地包含以下内容:

//One time stuff
#define ABC 1
#define DEF 2
#define GHI 3
#define JKL 4

//Stuff generated in loop

接下来,我们可以使用 CMake 的 file() and string() 实用程序 读取 输入文件(本例中为 CSV 格式),解析 内容,写入 头文件的其余部分。所以,test.csv 将包含输入,我们可以这样做:

# Read the entire CSV file.
file(READ ${CMAKE_CURRENT_LIST_DIR}/test.csv CSV_CONTENTS)

# Split the CSV by new-lines.
string(REPLACE "\n" ";" CSV_LIST ${CSV_CONTENTS})

# Loop through each line in the CSV file.
foreach(CSV_ROW ${CSV_LIST})
    # Get a list of the elements in this CSV row.
    string(REPLACE "," ";" CSV_ROW_CONTENTS ${CSV_ROW})

    # Get variables to each element.
    list(GET CSV_ROW_CONTENTS 0 ELEM0)
    list(GET CSV_ROW_CONTENTS 1 ELEM1)
    list(GET CSV_ROW_CONTENTS 2 ELEM2)

    # Append these lines to header.hpp, using the elements from the current CSV row.
    file(APPEND ${CMAKE_CURRENT_LIST_DIR}/header.hpp
    "
//Iteration with params ${ELEM0}, ${ELEM1}, ${ELEM2}
const int prefix_${ELEM0}_${ELEM1} = ${ELEM2};
const int prefix2_${ELEM1}_${ELEM2} = 0;
    "
    )
endforeach()

这将适用于输入 CSV 文件中任意数量的行。虽然这是一种解决方案,但使用正则表达式肯定可以实现更简洁的解决方案。请注意,如果您的 CSV 不包含空格,此方法效果最佳!

已完成header.hpp:

//One time stuff
#define ABC 1
#define DEF 2
#define GHI 3
#define JKL 4

//Stuff generated in loop

//Iteration with params Item1, 1, 2
const int prefix_Item1_1 = 2;
const int prefix2_1_2 = 0;

//Iteration with params Item2, 3, 4
const int prefix_Item2_3 = 4;
const int prefix2_3_4 = 0;

//Iteration with params Item5, 6, 7
const int prefix_Item5_6 = 7;
const int prefix2_6_7 = 0;