Projects, targets & dependencies프로젝트, 타깃, 의존성

How a project is laid out, which targets exist, and how dependencies are scoped to them.

프로젝트 구조, 지원 타깃, 그리고 의존성을 타깃에 묶는 방법.

Layout구조

A project is a uv workspace. Each package is a workspace member and, under toolchain, one Gradle module.

프로젝트는 uv 워크스페이스입니다. 패키지마다 워크스페이스 멤버이며, toolchain 에서는 Gradle 모듈 하나입니다.

<project>/
├── .venv/                 # dev environment for building the project
├── pyproject.toml, uv.lock
└── <package>/
    ├── pyproject.toml
    ├── src/main/  src/<family>/  src/test/
    ├── build/crossenv/<triple>/                               # per-target installs
    ├── build/packpack/<bundle type>/<build type>/<level>/     # bundles
    └── dist/<triple>/<build type>/<level>/                    # `ppp build` output

Targets타깃

Targets are canonical triples; a few aliases are accepted and normalized. ppp target list prints them all.

타깃은 정식 트리플이며, 몇 가지 별칭은 받아서 정규화합니다. ppp target list 가 전부 보여 줍니다.

Family계열Triples트리플Aliases별칭
Androidaarch64-linux-android, x86_64-linux-androidandroid_24_arm64, android_24_x86_64 (and android_21_…)android_24_arm64, android_24_x86_64 (android_21_… 도)
iOSarm64-apple-ios, arm64-apple-ios-simulator, x86_64-apple-ios-simulator-
macOSaarch64-apple-darwin, x86_64-apple-darwinmacos, macos_arm64, macos_x86_64
Linuxx86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, musl and manylinux variantsx86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, musl 과 manylinux 변형linux, linux_amd64, linux_arm64
Windowsx86_64-pc-windows-msvc, aarch64-pc-windows-msvc, i686-pc-windows-msvcwindows, windows_amd64, windows_arm64
ppp target add <target>...            # the project and every workspace member
ppp target remove <target>...
ppp core target add <target>...       # one package

target add edits [tool.ppp.dependencies].platforms and creates src/<family>/__init__.py in each affected package. A new package inherits the project's targets.

target add 는 [tool.ppp.dependencies].platforms 를 고치고, 영향받는 패키지마다 src/<family>/__init__.py 를 만듭니다. 새 패키지는 프로젝트의 타깃을 물려받습니다.

The dev environment개발 환경

Root-level commands act on the project's .venv with plain uv:

루트 수준 명령은 프로젝트의 .venv 에 그대로 uv 를 실행합니다.

ppp add <pypi name>...        # uv add, in the project root
ppp remove <pypi name>...     # uv remove
ppp sync                      # uv sync
ppp tree [--target <t>...]    # uv tree --python-platform <t>, host by default

Per-package, per-target dependencies패키지별, 타깃별 의존성

Command명령What it does하는 일
ppp <pkg> add <dep> [--target …]uv add --package <pkg> --marker … once per target. Without --target, the package's platforms; with neither, an error.타깃마다 uv add --package <pkg> --marker …. --target 이 없으면 패키지의 platforms, 둘 다 없으면 오류.
ppp <pkg> remove <dep> [--target …]Removes only the entries for those targets from project.dependencies, then uv lock.project.dependencies 에서 그 타깃의 항목만 지우고 uv lock.
ppp <pkg> sync [--target …]uv sync --package, a uv tree check per target, then uv pip install --target build/crossenv/<triple> --python-platform <triple>. Host target by default.uv sync --package, 타깃마다 uv tree 확인, 그다음 uv pip install --target build/crossenv/<triple> --python-platform <triple>. 기본은 호스트 타깃.
ppp <pkg> tree [--target …]uv tree --package --python-platform per target.타깃마다 uv tree --package --python-platform.

A marker typed into the dependency string (numpy; …) is refused; use --target. ppp package sync|tree <pkg> are explicit spellings of the same commands.

의존성 문자열에 직접 쓴 마커 (numpy; …) 는 거부됩니다. --target 을 쓰세요. ppp package sync|tree <pkg> 는 같은 명령의 명시적 형태입니다.

Missing wheels and uv flags없는 휠과 uv 플래그

Whether a wheel exists for a target is only known by trying. When uv fails, the error names the package and the target and says whether only an sdist exists (NoWheelForTargetException).

타깃용 휠이 있는지는 설치해 봐야 압니다. uv 가 실패하면 오류가 패키지와 타깃을 밝히고, sdist 만 있는지 알려 줍니다 (NoWheelForTargetException).

Unknown --flag [value] tokens are passed to uv. --flag=value always carries its value. Written with a space, only --python-version, --only-binary, --python, --index, --default-index, --index-url, --extra-index-url, --find-links, --index-strategy and --resolution take the next token; every other flag is passed bare.

알 수 없는 --flag [value] 는 uv 로 넘어갑니다. --flag=value 형태는 언제나 값을 함께 넘깁니다. 공백으로 쓰면 --python-version, --only-binary, --python, --index, --default-index, --index-url, --extra-index-url, --find-links, --index-strategy, --resolution 만 다음 토큰을 값으로 받고, 나머지는 값 없이 넘어갑니다.

uv picks wheels for the host's Python version unless told otherwise. When the runtime's differs, pass it: ppp core sync --target aarch64-linux-android --python-version 3.14 --only-binary :all:. sync gives --python-version to uv tree and uv pip install, and --only-binary to uv pip install only.

uv 는 따로 지정하지 않으면 호스트 Python 버전으로 휠을 고릅니다. 런타임 버전이 다르면 넘기세요: ppp core sync --target aarch64-linux-android --python-version 3.14 --only-binary :all:. sync 는 --python-version 을 uv tree 와 uv pip install 에, --only-binary 는 uv pip install 에만 넘깁니다.