Skip to content

Commit df1104b

Browse files
committed
feat cmake: speed up creating Python venv using uv (opt-in)
* Added `USERVER_PIP_USE_UV` option that allows to use `uv` instead of `venv + pip` for Python virtual environments. `uv` gives a measurable speedup to cmake Configure step when building services. commit_hash:c8869a4355118ee7954de8433e429dd1fdf370cc
1 parent ac9a6c9 commit df1104b

2 files changed

Lines changed: 32 additions & 19 deletions

File tree

cmake/UserverVenv.cmake

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ function(_userver_prepare_venv_variables)
2626
""
2727
CACHE STRING "Options for all pip calls"
2828
)
29+
30+
# @ingroup dependencies
31+
option(USERVER_PIP_USE_UV "Use uv instead of venv for managing Python virtual environments" OFF)
2932
endfunction()
3033

3134
_userver_prepare_venv_variables()
@@ -72,9 +75,10 @@ function(userver_venv_setup)
7275

7376
list(APPEND ARG_PIP_ARGS ${USERVER_PIP_OPTIONS})
7477
set(venv_params "")
75-
set(format_version 2)
78+
set(format_version 3)
7679
string(APPEND venv_params "format-version=${format_version}\n")
7780
string(APPEND venv_params "pip-args=${ARG_PIP_ARGS}\n")
81+
string(APPEND venv_params "use-uv=${USERVER_PIP_USE_UV}\n")
7882
_userver_append_requirements_from_file(venv_params ${ARG_REQUIREMENTS})
7983

8084
if(NOT ARG_NAME)
@@ -103,7 +107,7 @@ function(userver_venv_setup)
103107
set(venv_dir "${parent_directory}/${venv_name}")
104108
set(venv_bin_dir "${venv_dir}/bin")
105109
set("${python_output_var}"
106-
"${venv_bin_dir}/python"
110+
"${venv_bin_dir}/python3"
107111
PARENT_SCOPE
108112
)
109113

@@ -126,11 +130,19 @@ function(userver_venv_setup)
126130
message(STATUS "Setting up the venv at ${venv_dir}")
127131

128132
if(NOT EXISTS "${venv_dir}/.venv-settled")
129-
file(REMOVE_RECURSE "${venv_dir}")
133+
file(REMOVE_RECURSE "${venv_dir}")
130134

131-
execute_process(
132-
COMMAND "${USERVER_PYTHON_PATH}" -m venv "${venv_dir}" ${venv_additional_args} RESULT_VARIABLE status
133-
)
135+
if(USERVER_PIP_USE_UV)
136+
execute_process(
137+
COMMAND uv venv "${venv_dir}" --python "${USERVER_PYTHON_PATH}" ${venv_additional_args}
138+
RESULT_VARIABLE status
139+
)
140+
else()
141+
execute_process(
142+
COMMAND "${USERVER_PYTHON_PATH}" -m venv "${venv_dir}" ${venv_additional_args}
143+
RESULT_VARIABLE status
144+
)
145+
endif()
134146
if(status)
135147
file(REMOVE_RECURSE "${venv_dir}")
136148
message(
@@ -139,8 +151,8 @@ function(userver_venv_setup)
139151
)
140152
endif()
141153

142-
# to be sure 'python -m venv' is atomic
143-
file(TOUCH "${venv_dir}/.venv-settled")
154+
# To make sure that venv creation is atomic.
155+
file(TOUCH "${venv_dir}/.venv-settled")
144156
endif()
145157

146158
# If pip has already installed packages using the same requirements, then don't run it again. This optimization
@@ -161,18 +173,18 @@ function(userver_venv_setup)
161173
endforeach()
162174
list(TRANSFORM ARG_REQUIREMENTS PREPEND "--requirement=" OUTPUT_VARIABLE pip_requirements)
163175

164-
# psycopg2 implicitly requires 'wheel' to be already installed
165-
execute_process(
166-
COMMAND "${venv_bin_dir}/python3" -m pip install -U wheel ${ARG_PIP_ARGS} RESULT_VARIABLE status
167-
)
168-
if(status)
169-
message(FATAL_ERROR "Failed to install venv requirements")
176+
if(USERVER_PIP_USE_UV)
177+
execute_process(
178+
COMMAND uv pip install --python "${venv_bin_dir}/python3" -U ${pip_requirements} ${ARG_PIP_ARGS}
179+
RESULT_VARIABLE status
180+
)
181+
else()
182+
execute_process(
183+
COMMAND "${venv_bin_dir}/python3" -m pip install --disable-pip-version-check -U ${pip_requirements}
184+
${ARG_PIP_ARGS}
185+
RESULT_VARIABLE status
186+
)
170187
endif()
171-
172-
execute_process(
173-
COMMAND "${venv_bin_dir}/python3" -m pip install --disable-pip-version-check -U ${pip_requirements}
174-
${ARG_PIP_ARGS} RESULT_VARIABLE status
175-
)
176188
if(status)
177189
message(FATAL_ERROR "Failed to install venv requirements")
178190
endif()

scripts/docs/en/userver/build/options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ The exact format of setting cmake options varies depending on the method of buil
187187
| `USERVER_FEATURE_ERASE_LOG_WITH_LEVEL` | Logs of this and below levels are removed from binary. Possible values: trace, info, debug, warning, error | `OFF` |
188188
| `USERVER_PIP_USE_SYSTEM_PACKAGES` | Use system python packages inside venv. Useful for Docker, CI and other controlled environments | `OFF` |
189189
| `USERVER_PIP_OPTIONS` | Options for all pip calls. Useful for passing `--no-index` option to prevent network usage | (no options) |
190+
| `USERVER_PIP_USE_UV` | Use `uv` tool for creating Python virtual environments instead of the built-in `venv` and `pip` | `OFF` |
190191
| `USERVER_INSTALL` | Build userver for further installation | `OFF` |
191192
| `USERVER_INSTALL_MULTIPACKAGE` | Whether create per-component packages | `OFF` |
192193
| `USERVER_CONAN` | Build userver using Conan packages | `ON` if build is launched from Conan, `OFF` otherwise |

0 commit comments

Comments
 (0)