Created by: T8T9
PR types
Others
PR changes
Others
Describe
问题描述
paddle 在cmake阶段会生成一些动态文件,包括两类:
第一类:dummy文件
/paddle/build/boost_dummy.c
/paddle/build/cblas_dummy.c
/paddle/build/mkldnn_dummy.c
/paddle/build/paddle/fluid/memory/memory_dummy.c
/paddle/build/paddle/fluid/platform/enforce_dummy.c
/paddle/build/paddle/fluid/framework/paddle_framework_dummy.c
/paddle/build/paddle/fluid/operators/jit/jit_kernel_helper_dummy.c
/paddle/build/paddle/fluid/inference/paddle_fluid_dummy.c
/paddle/build/paddle/fluid/inference/analysis/analysis_pass_dummy.c
/paddle/build/paddle/fluid/inference/analysis/argument_dummy.c
第二类:头文件
/paddle/build/paddle/fluid/inference/api/paddle_inference_pass.h
/paddle/build/paddle/fluid/pybind/pybind.h
/paddle/build/paddle/fluid/operators/jit/kernels.h
/paddle/paddle/fluid/pybind/op_function_impl.h
这些动态生成的文件,会导致每次执行cmake都会修改文件时间戳,导致ccache 和make认为这个文件被修改了,进而触发重新编译,重新编译会触发重新链接,增加编译时长。
解决方法
生成文件之前,跳过已经存在并且内容一样的文件。有两种方法:
方法一:configure_file 。这个命令可以在cmake阶段根据一个模板,生成一个新文件,如果模板没有被修改,文件就不会重新生成。这个可以用来生成一些格式固定的文件,dummy文件就属于此类。如:
# 设置dummy文件路径
set(target_SRCS "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}_dummy.c")
# 设置模板参数
set(dummy_generator "${PROJECT_SOURCE_DIR}/cmake/generic.cmake:cc_library")
set(dummy_string "${target_SRCS}")
# 根据模板参数,生成文件,如果模板参数没有改变就跳过
configure_file(${PROJECT_SOURCE_DIR}/cmake/dummy.c.in ${target_SRCS} @ONLY)
方法二:add_custom_target
+ add_dependencies
+ add_custom_command
+ copy_if_different。以 /paddle/build/paddle/fluid/pybind/pybind.h
为例:
# 先生成一个临时文件,如 pybind.h.tmp
set(pybind_file ${PADDLE_BINARY_DIR}/paddle/fluid/pybind/pybind.h.tmp CACHE INTERNAL "pybind.h file")
set(pybind_file_final ${PADDLE_BINARY_DIR}/paddle/fluid/pybind/pybind.h)
file(WRITE ${pybind_file} "// Generated by the paddle/fluid/operators/CMakeLists.txt. DO NOT EDIT!\n\n")
# this is a dummy target, should always be run to update ${jit_file_final}
add_custom_target(update_pybind_h ALL
DEPENDS update_pybind_h_always_rebuild
)
add_dependencies(operator update_pybind_h)
# 在这个自定义的command 中,如果临时文件和最终文件内容不一致,就拷贝,否则就跳过。
add_custom_command(
OUTPUT update_pybind_h_always_rebuild
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${pybind_file} ${pybind_file_final}
COMMENT "copy_if_different ${pybind_file_final}"
VERBATIM
)
这种方法适合生成任意的动态文件,但和第一种方式相比,稍显繁琐。