我正在尝试使用cmake来简化我的OpenCL程序的分发。我有一个内核文件,其中包含几个头文件和其他源文件,我希望有一个自包含的可执行文件。
我的计划是让cmake在内核源代码上运行 C 预处理器,将cl文件及其包含文件转换为一个更易于使用的单元。
我可以使用add_custom_command来通过使用-E调用gcc / clang来实现它,但是我没有得到包含正确目录的标志来查找命令中的各种头文件,我没有看到查找在编译器的自定义调用中使用的所有当前包含目录的简单方法。
是否有办法在具有当前cmake环境的文件上仅运行 C 预处理器?
答案 0 :(得分:14)
CMake自动为预处理文件生成make目标。对于项目中的每个foo.c
,都有一个foo.i
make目标,它只运行预处理器(包含所有相关的-D
和-I
标志等)。运行make help
以查看CMake在您的makefile中生成的所有其他可能有用的目标。
答案 1 :(得分:1)
这将是一个粗糙的黑客,但你可以滥用add_definition,因为“此命令可用于添加任何标志,但它最初旨在添加预处理器定义。”
或者,您可以将目标的COMPILE_FLAGS属性设置为“-E”,这将实现相同的效果,但对于该目标是本地的。
答案 2 :(得分: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()
答案 3 :(得分:0)
我建议采用不同的方法。
将内核构建为二进制文件(ATI Stream示例:http://developer.amd.com/support/KnowledgeBase/Lists/KnowledgeBase/DispForm.aspx?ID=115)
将此二进制数据编译到您的程序中(作为char [] blob)并在程序启动时加载它。
使用cmake和自定义目标,这应该非常简单。