CMake:设置自定义目标的 TARGET_FILE 生成器表达式

CMake: setting the TARGET_FILE generator expression of a custom target

我有一个自定义目标。如何设置它的 TARGET_FILE 生成器表达式。

add_custom_target(my_target)
...
# set TARGET_FILE
...
# Use $<TARGET_FILE:my_target>

我试图设置 LOCATION 目标 属性 希望 TARGET_FILE 生成器表达式会指向它,但事实并非如此。

I have a custom target. How do I set it's TARGET_FILE generator expression.

不可能,来自add_custom_target

The target has no output file

因此它没有 TARGET_FILE 生成器表达式。

正如另一个答案所指出的,add_custom_target 无法做到这一点,但如果您想要的是具有 TARGET_FILE 属性 的自定义目标,那么这是可能的。如果你有一个通过其他机制构建的 non-C++ 可执行文件(例如,它可能只是一个 shell 脚本,或者它可能是一个 self-extracting 包等),则以下技术很有用.

dummy-main.cc:

int main(int argc, char** argv) {
  return 0;
}

CMakeLists.txt:

# This is the custom command where you generate the custom binary. Maybe it's
# a special compiler for a dynamic language, or maybe you're just creating
# an executable zipfile for python.
add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/my-custom-binary.real
         ${CMAKE_CURRENT_BINARY_DIR}/empty.cc
  COMMAND make-my-custom-binary
    -o ${CMAKE_CURRENT_BINARY_DIR}/my-custom-binary.real
  # There is no way to add a file-level dependency between some
  # `add_executable` and this generated file, so we have to generate a
  # stub .cc file just so we can depend on it in `add_executable`
  COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/empty.cc
)

# In cmake, a c++ binary is the only first class citizen. Here, we have a
# custom binary which is generated in some other way and we want cmake to
# treat it like a C++ binary in so much as the target is a name in the global
# namespace of targets and can be used in generator expressions and has
# properties and things. So, first we create a dummy executable:
add_executable(
  my-custom-binary
  dummy-main.cc ${CMAKE_CURRENT_BINARY_DIR}/empty.cc
)

# Then, in the POST_BUILD commands, we delete the executable created by the
# C++ compiler, and replace it with the executable we constructed through
# some other means. 
add_custom_command(
  TARGET my-custom-binary
  POST_BUILD
  COMMAND rm $<TARGET_FILE:my-custom-binary>
  COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/my-custom-binary.real
          $<TARGET_FILE:my-custom-binary>
)

其他CMakeLists.txt

# Since your custom binary appears to cmake indistinguishable from a C++
# binary, we can use it in the same ways. If our custom binary were a
# code generator, for example, we might do something like this somewhere
# else in our build system
add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h
         ${CMAKE_CURRENT_BINARY_DIR}/foo.cc
  DEPENDS foo.in my-custom-binary
  COMMAND $<TARGET_FILE:my-custom-binary>
      -i ${CMAKE_CURRENT_SOURCE_DIR}/foo.in
      -o ${CMAKE_CURRENT_BINARY_DIR} 
)

注意:我已经在构建系统中验证了这项技术,但没有验证这个确切的代码。我可能犯了拼写错误或其他 transcription/redaction 错误。