22

我正在尝试使用 cmake 来简化我的 OpenCL 程序的分发。我有一个内核文件,其中包含几个头文件和其他源文件,我想要一个独立的可执行文件。

我的计划是让 cmake 在内核源代码上运行C预处理器,将 cl 文件及其包含的内容变成一个更易于使用的单元。

我可以通过使用 -E 调用 gcc/clang 来使用 add_custom_command 来执行此操作,但是我没有得到包含正确目录以在命令中查找各种头文件的标志,而且我看不到一个简单的方法查找要在对编译器的自定义调用中使用的所有当前包含目录。

有没有办法只在当前 cmake 环境的文件上运行C预处理器?

4

4 回答 4

21

CMake 自动生成用于预处理文件的 make 目标。对于foo.c您项目中的每个项目,都有一个foo.i仅运行预处理器(带有所有相关-D-I标志等)的 make 目标。运行make help以查看 CMake 在您的 makefile 中生成的所有其他可能有用的目标。

顺便说一句,我看不出这个“单一单元”如何更容易为您工作。

于 2012-05-14T12:49:05.157 回答
2

这将是一个粗略的 hack,但您可以滥用 add_definition ,因为“此命令可用于添加任何标志,但它最初旨在添加预处理器定义。”

或者,您可以将目标的 COMPILE_FLAGS 属性设置为“-E”,这将实现相同的效果,但对于该目标是本地的。

于 2012-05-02T11:37:00.053 回答
1

到目前为止,这工作正常:

function(add_c_preprocessor_command)
    # Add custom command to run C preprocessor.
    #
    # Arguments
    #   OUTPUT          output file
    #   SOURCE          input file
    #   TARGET          CMake target to inherit compile definitions, include directories, and compile options
    #   EXTRA_C_FLAGS   extra compiler flags added after all flags inherited from the TARGET

    set(one_value_args TARGET SOURCE OUTPUT)
    set(multi_value_args EXTRA_C_FLAGS)
    cmake_parse_arguments(CPP "" "${one_value_args}" "${multi_value_args}" ${ARGN})

    string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
    string(REPLACE " " ";" c_flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${build_type}}")

    add_custom_command(
        OUTPUT ${CPP_OUTPUT}
        COMMAND ${CMAKE_C_COMPILER}
            "-D$<JOIN:$<TARGET_PROPERTY:${CPP_TARGET},COMPILE_DEFINITIONS>,;-D>"
            "-I$<JOIN:$<TARGET_PROPERTY:${CPP_TARGET},INCLUDE_DIRECTORIES>,;-I>"
            ${c_flags}
            $<TARGET_PROPERTY:${CPP_TARGET},COMPILE_OPTIONS>
            ${CPP_EXTRA_C_FLAGS}
            -E ${CPP_SOURCE} -o ${CPP_OUTPUT}
        COMMAND_EXPAND_LISTS VERBATIM
        IMPLICIT_DEPENDS C ${CPP_SOURCE}
        DEPENDS ${CPP_SOURCE})
endfunction()
于 2021-03-31T23:43:55.867 回答
0

我会建议一种不同的方法。

  1. 将内核构建为二进制文件(ATI Stream 的示例:http: //developer.amd.com/support/KnowledgeBase/Lists/KnowledgeBase/DispForm.aspx ?ID=115 )

  2. 将此二进制数据编译到您的程序中(作为 char[] blob)并在程序启动时加载它。

使用 cmake 和自定义目标,这应该非常简单。

于 2010-08-28T14:34:49.907 回答