c++ 如何避免使用CMake对Protobuf生成的文件进行不必要的重新编译?

wyyhbhjk  于 2023-04-01  发布在  其他
关注(0)|答案(1)|浏览(202)

我在一个子目录中有GRPC,所以我有Protobuf目标名称和GRPC C++插件目标名称。我如何生成proto文件,而不需要在每次CMake或Build目标想要运行时重新编译?
当前设置:

add_custom_target(ThatThing
  COMMAND 
    $<TARGET_FILE:${proto_target}>
      --grpc_out=generate_mock_code=true:${the_output_dir}
      --cpp_out=${the_output_dir}
      --plugin=protoc-gen-grpc=$<TARGET_FILE:${grpc_cpp_plugin_target}>
      -I ${that_dir}
      ${those_proto_files}
)
add_dependencies(${that_dependent_target_name} ThatThing)

但是这里我们在每次想要构建时都对生成的文件进行重建。一种方法是通过检查这些文件是否已生成来仅在CMake的生成时生成这些文件。但是execute_process函数似乎既不能理解$<TARGET_FILE> genexpr也不能理解目标名称:

execute_process(COMMAND ${protoc_path} --help COMMAND_ERROR_IS_FATAL ANY)

将失败:

execute_process error getting child return code: No such file or directory

我不知道为什么,但我无法获得目标的LOCATION属性:

get_target_property(the_location ${protoc_path} LOCATION)

将失败:

The LOCATION property may not be read from target "protoc".  Use the target
  name directly with add_custom_command, or use the generator expression
  $<TARGET_FILE>, as appropriate.

而且find_program函数不能使用$<TARGET_FILE> genexpr:

find_program(that_location ${protoc_path} REQUIRED)
find_program(that_location $<TARGET_FILE:${protoc_path}> REQUIRED)

如何解决不必要的重新编译问题?

ctrmrzij

ctrmrzij1#

add_custom_target的问题是 * 目标总是被认为是过时的 *。如果你使用add_custom_command,它只会在DEPENDS中指定的文件更改时重建。
这比配置时解决方案更好,因为如果任何输入文件发生更改,它将在构建期间重新生成目标。
请注意,如果需要为多个目标生成文件,则应该为它们添加一个虚拟目标,如add_custom_command的文档所示。

相关问题