使用 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;
我想生成一个自定义头文件,想知道 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;