CMake:配置时尚未生成的安装文件
我有一个项目,里面用到了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/")
这个设置确实很好用,当我运行两次的时候效果很好。但是如果我删除了我的构建目录,然后从头开始配置,CMake就找不到Python的protobuf接口文件了,因为这些文件在第一次运行 make all
命令之前是不存在的,所以 file(GLOB PROTOBUF_INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/*_pb2.py")
这行代码就找不到它们。
有没有办法让CMake在第一次构建完成后再执行上面的代码?或者有没有其他更简单的方法来实现这个?
1 个回答
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
会被直接加到目标目录后面。而有了这个斜杠,就不会出现这种情况。