我确实有一个带有Protobuf接口的项目,我需要使用CMake为Python编译和安装。
我的CMakeLists.txt
如下所示:
file(GLOB PROTO_INPUT "*.proto")
add_custom_target(BuildPythonInterface ALL
protoc -I=${CMAKE_CURRENT_SOURCE_DIR} --python_out=${CMAKE_CURRENT_BINARY_DIR} ${PROTO_INPUT}
DEPENDS ${PROTO_INPUT})
file(GLOB PROTOBUF_INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/*_pb2.py")
LIST(APPEND PROTOBUF_INTERFACE "${INIT_PY}" )
install(FILES ${PROTOBUF_INTERFACE} DESTINATION "lib/python2.7/site-packages/${PROJECT_NAME}/proto/")
当它运行两次时确实像魅力一样工作,但是如果我删除了我的构建目录并开始从头开始进行混淆,那么file(GLOB PROTOBUF_INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/*_pb2.py")
找不到Python的protobuf接口文件它们尚不存在,直到make all
命令运行一次。
有没有办法让CMake在运行一次构建后执行上面的代码行? 或者也许是另一种(清洁?)这样做的方式?
答案 0 :(得分:3)
执行此操作的首选CMake方法是显式列出输入和输出文件,而不是使用file(GLOB)
。这有多种原因;你面临的是其中之一;事实上,使用GLOB
,添加文件不会导致自动重新运行CMake(因此文件未被拾取)是另一个。
然而,如果GLOB
是您特定场景中的最佳方式(如您在评论中所述),则可以使用install(DIRECTORY)
而不是安装文件来解决此问题。像这样:
file(GLOB PROTO_INPUT "*.proto")
add_custom_target(BuildPythonInterface ALL
protoc -I=${CMAKE_CURRENT_SOURCE_DIR} --python_out=${CMAKE_CURRENT_BINARY_DIR}/ToBeInstalled ${PROTO_INPUT}
DEPENDS ${PROTO_INPUT})
install(
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ToBeInstalled/
DESTINATION "lib/python2.7/site-packages/${PROJECT_NAME}/proto/"
FILES_MATCHING PATTERN "*_pb2.py"
)
install(FILES ${INIT_PY} DESTINATION "lib/python2.7/site-packages/${PROJECT_NAME}/proto/")
注意DIRECTORY
参数中的尾部斜杠。重要的是:如果它不存在,名称ToBeInstalled
将附加到目标目录。使用尾部斜杠,此附加被抑制。