英文:
How can I create a python3 venv in cmake install?
问题
以下是您要翻译的代码部分:
find_package(Python3 REQUIRED COMPONENTS Interpreter)
set(VENV "${CMAKE_INSTALL_PREFIX}/venv")
set(REQUIREMENTS "${CMAKE_SOURCE_DIR}/tools/testing/scripts/requirements.txt")
set(BIN_DIR "${VENV}/bin")
install(CODE "
MESSAGE(\"Creating VENV from ${Python3_EXECUTABLE} to ${VENV}\")
execute_process(COMMAND_ECHO STDOUT COMMAND ${Python3_EXECUTABLE} -m venv ${VENV} )
execute_process(COMMAND_ECHO STDOUT COMMAND ${BIN_DIR}/pip install -U pip wheel )
execute_process(COMMAND_ECHO STDOUT COMMAND ${BIN_DIR}/pip install -r ${REQUIREMENTS} )
")
希望这有所帮助。如果您有任何其他问题,请随时提出。
英文:
I have a medium sized project composed by many parts, mostly in C++, but testing and configuration relies on Python3 scripts.
The project buildsystem is generated using CMake and installed (by CMake rules) in a "deploy" directory.
I would like to create a Python venv to segregate changes.
I have the following CMake fragment:
set(VENV ${CMAKE_INSTALL_PREFIX}/venv)
set(REQUIREMENTS ${CMAKE_SOURCE_DIR}/tools/testing/scripts/requirements.txt)
set(BIN_DIR ${VENV}/bin)
set(PYTHON ${BIN_DIR}/python)
set(OUTPUT_FILE ${VENV}/environment.txt)
add_custom_command(
OUTPUT ${OUTPUT_FILE}
COMMAND ${Python3_EXECUTABLE} -m venv ${VENV}
COMMAND ${BIN_DIR}/pip install -U pip wheel
COMMAND ${BIN_DIR}/pip install -r ${REQUIREMENTS}
COMMAND ${BIN_DIR}/pip freeze > ${VENV}/environment.txt
DEPENDS ${REQUIREMENTS}
)
add_custom_target(venv DEPENDS ${PYTHON})
... but I don't know how to trigger the venv
target while doing installation.
I am unsure if this is the right approach (comments welcome, of course), but need should be quite clear: I need to be able to run my scripts from the "deploy" directory using something like:
venv/bin/python test-script.py
or use a custom: #!venv/bin/python
line (I am working under Linux).
UPDATE:
My somewhat working code, based on @user Answer, is as follows:
find_package(Python3 REQUIRED COMPONENTS Interpreter)
set(VENV "${CMAKE_INSTALL_PREFIX}/venv")
set(REQUIREMENTS "${CMAKE_SOURCE_DIR}/tools/testing/scripts/requirements.txt")
set(BIN_DIR "${VENV}/bin")
install(CODE "
MESSAGE(\"Creating VENV from ${Python3_EXECUTABLE} to ${VENV}\")
execute_process(COMMAND_ECHO STDOUT COMMAND ${Python3_EXECUTABLE} -m venv ${VENV} )
execute_process(COMMAND_ECHO STDOUT COMMAND ${BIN_DIR}/pip install -U pip wheel )
execute_process(COMMAND_ECHO STDOUT COMMAND ${BIN_DIR}/pip install -r ${REQUIREMENTS} )
")
Equivalent code with set(...
and find_package(...
inside install(CODE...
did not work; also quoting seems wrong.
I will accept this answer, but I would like to clarify the above.
答案1
得分: 0
你可以使用install(SCRIPT)
或install(CODE)
来实现这个功能:
SCRIPT
形式会在安装过程中调用给定的CMake脚本文件。如果脚本文件名是相对路径,它将相对于当前源目录进行解释。CODE
形式会在安装过程中调用给定的CMake代码。代码被指定为双引号内的单个参数。
我认为可以这样做(在这里使用CODE
形式使得变量替换和使用一些在配置阶段上下文之外不可用的变量更容易,即使你使用SCRIPT
模式,也需要明确传递它们):
install(CODE "
set(VENV \"${CMAKE_INSTALL_PREFIX}/venv\")
set(REQUIREMENTS \"${CMAKE_SOURCE_DIR}/tools/testing/scripts/requirements.txt\")
set(BIN_DIR \"${VENV}/bin\")
set(OUTPUT_FILE \"${VENV}/environment.txt\")
execute_process(COMMAND \"${Python3_EXECUTABLE}\" -m venv \"${VENV}\")
execute_process(COMMAND \"${BIN_DIR}/pip\" install -U pip wheel)
execute_process(COMMAND \"${BIN_DIR}/pip\" install -r \"${REQUIREMENTS}\")
execute_process(COMMAND \"${BIN_DIR}/pip\" freeze > \"${VENV}/environment.txt\")
execute_process(COMMAND \"${REQUIREMENTS}\")
")
另请参阅关于execute_process
的文档,如果你想处理命令失败等情况。
英文:
You should be able to do this using install(SCRIPT)
or install(CODE)
:
> The SCRIPT
form will invoke the given CMake script files during installation. If the script file name is a relative path it will be interpreted with respect to the current source directory. The CODE
form will invoke the given CMake code during installation. Code is specified as a single argument inside a double-quoted string.
I believe it would be done something like this (using the CODE
form here to make it easier to do variable substitution and use some of the variables that wouldn't be available outside the context of the configuration phase (i.e. if you were to use the SCRIPT
mode) without explicitly passing them):
install(CODE "
set(VENV \"${CMAKE_INSTALL_PREFIX}/venv\")
set(REQUIREMENTS \"${CMAKE_SOURCE_DIR}/tools/testing/scripts/requirements.txt\")
set(BIN_DIR \"${VENV}/bin\")
set(OUTPUT_FILE \"${VENV}/environment.txt\")
execute_process(COMMAND \"${Python3_EXECUTABLE}\" -m venv \"${VENV}\")
execute_process(COMMAND \"${BIN_DIR}/pip\" install -U pip wheel)
execute_process(COMMAND \"${BIN_DIR}/pip\" install -r \"${REQUIREMENTS}\")
execute_process(COMMAND \"${BIN_DIR}/pip\" freeze > \"${VENV}/environment.txt\")
execute_process(COMMAND \"${REQUIREMENTS}\")
")
See also the docs for execute_process
if you want to do things like handle command failures, etc.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论