我们可以在模板源文件中使用CMake foreach吗?

时间:2019-09-06 22:44:12

标签: c cmake

对于单元测试我的功能,我已经自动生成了名称,就像这样:

test_implode test_range

放入CMake变量。

我想用C自动调用全部。 我还在CMake中使用了配置文件(.in.c)

set(CONFIG configuration)
configure_file(${CONFIG}.in.c ${CONFIG}.c)
set(CONFIG_SRC ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG}.c)

但是函数的名称仅在CMake的列表中,C语法无效。我可以使用适当的语法在CMake中生成一个变量,但是在配置文件中生成输出将使CMake源文件干净并且可能非常强大。

具体来说,我想做的是(虚构语法):

#include "tests.h"

void all_tests() {

    void(*tests)()[] = {
    @FOREACH(FUNC FUNCTIONS)@
        test_@FUNC@,
    @ENDFOREACH()@
        NULL
    };

    void(*test_function)() = tests[0];

    while(test_function) {
        test_function();
        test_function++;
    }
}

类似于刀片或PHP。 我可以使用CMake作为脚本语言(或foreach),还是必须将其放入CMake源文件并将其存储到变量中?

我目前可以接受的工作有效。但是我正在学习,我想知道它是否仍然可能

foreach(PHP_FUNCTION ${PHP_FUNCTIONS})
  list(APPEND GENERATED_C_CODE_RUN_TEST "\n\ttest_${PHP_FUNCTION}()")
endforeach()

set(GENERATED_C_CODE_RUN_TEST "${GENERATED_C_CODE_RUN_TEST};")
set(CONFIG configuration)
configure_file(${CONFIG}.in.c ${CONFIG}.c)
set(CONFIG_SRC ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG}.c)
add_executable(...);
#include "tests.h"

void all_tests() {

    @GENERATED_C_CODE_RUN_TEST@
}

1 个答案:

答案 0 :(得分:2)

一种解决方案是将test_前缀附加到列表中的每个测试名称,然后使用list(JOIN ...)构造一个表示逗号分隔列表(有效的C语法)的字符串。

list(APPEND PHP_FUNCTIONS
    func1
    func2
    func3
)

# Append the 'test_' prefix to each test function name.
foreach(PHP_FUNCTION ${PHP_FUNCTIONS})
    list(APPEND FUNCTION_NAMES_LIST "test_${PHP_FUNCTION}")
endforeach()
message(STATUS "FUNCTION_NAMES_LIST: ${FUNCTION_NAMES_LIST}")

# Construct a comma-separated string from the list.
list(JOIN FUNCTION_NAMES_LIST "," FUNCTION_NAMES_STRING)
message(STATUS "FUNCTION_NAMES_STRING: ${FUNCTION_NAMES_STRING}")

这将打印以下内容:

FUNCTION_NAMES_LIST: test_func1;test_func2;test_func3
FUNCTION_NAMES_STRING: test_func1,test_func2,test_func3

然后,您可以修改configuration.in.c文件,因此只需要替换一个变量即可。

void all_tests() {

    void(*tests)()[] = {
        @FUNCTION_NAMES_STRING@,
        NULL
    };

    void(*test_function)() = tests[0];

    while(test_function) {
        test_function();
        test_function++;
    }
}

您可以使用“胶水”或用于将CMake列表连接在一起的分隔符字符串。在我的示例中,我使用了",",但是您可以使用", "",\n\t"使所得的C代码在视觉上更令人愉悦。 CMake list()(和string())有很多可用的操作选项,因此,我建议您检查一下。