# Project Python venv and generator script paths. # Included by the components that generate code (e.g. MsgUtils and CloudConnect). # # qmake evaluates system() at qmake time, while QMAKE_EXTRA_COMPILERS / # QMAKE_EXTRA_TARGETS run at make time. The venv is created here once and shared. # The generators are wired as make-time rules in the including .pro so they # re-run on input change. PROJECT_ROOT = $$clean_path($$PWD/../..) MSGUTILS_SCRIPTS_DIR = $$PROJECT_ROOT/scripts/MsgUtils # BUILD_ROOT is set by the repo-root .qmake.conf — identical for every component # in the tree, so all components share ONE venv. Fall back to OUT_PWD when built # without the .qmake.conf in scope (e.g. a leaf .pro copied elsewhere). isEmpty(BUILD_ROOT): BUILD_ROOT = $$OUT_PWD PROJECT_VENV_DIR = $$BUILD_ROOT/.venv PROJECT_PYTHON = $$PROJECT_VENV_DIR/bin/python # Create the venv, then editable-install the msgutils package so the generator # scripts can `import msgutils`. # # A missing python3-venv reports nothing here and later becomes a generator rule # failing to find an interpreter. This checks and reports here if it is missing. !exists($$PROJECT_PYTHON) { message("Creating project Python venv at $$PROJECT_VENV_DIR") !system(python3 -m venv $$shell_quote($$PROJECT_VENV_DIR)) { # $${} braces: qmake allows '.' in a variable name, so "$$VAR." reads as a # variable named "VAR." and expands to nothing. error("Could not create the Python venv at $${PROJECT_VENV_DIR}. On Debian/Ubuntu this usually means the venv module is missing: sudo apt install python3-venv") } # venv can exit 0 and still leave no interpreter (interrupted, disk full). !exists($$PROJECT_PYTHON) { error("The venv at $${PROJECT_VENV_DIR} was created but has no interpreter at $${PROJECT_PYTHON}. Remove the directory and re-run qmake.") } } # Allow a machine with a working venv and no network can still build. !system($$shell_quote($$PROJECT_PYTHON) -m pip install --upgrade pip --quiet) { warning("Could not upgrade pip in $${PROJECT_VENV_DIR}; continuing with the installed version.") } # The generators import msgutils, but a failed reinstall is survivable when the venv # already has it. !system($$shell_quote($$PROJECT_PYTHON) -m pip install -e $$shell_quote($$MSGUTILS_SCRIPTS_DIR) --quiet) { !system($$shell_quote($$PROJECT_PYTHON) -c $$shell_quote(import msgutils)) { error("Could not install msgutils from $${MSGUTILS_SCRIPTS_DIR} into $${PROJECT_VENV_DIR}, and it is not importable. The code generators cannot run.") } warning("Could not reinstall msgutils from $${MSGUTILS_SCRIPTS_DIR}; continuing with the copy already in the venv.") } PROTOC = protoc # Missing protoc reports nothing here and later becomes a generator rule failing with "command not found". # This checks and reports here if it is missing. !system($$PROTOC --version > /dev/null 2>&1) { error("Could not run '$${PROTOC}'. On Debian/Ubuntu install it with: sudo apt install protobuf-compiler") }