Compare commits
4 Commits
zeromq/v4.
...
eigen/v3.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf379a6268 | ||
|
|
fcd4d49232 | ||
|
|
9a30c4f717 | ||
|
|
c57efe15bc |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,5 +1,6 @@
|
|||||||
.git/
|
.git/
|
||||||
repo/
|
repo/
|
||||||
|
.venv/
|
||||||
|
|
||||||
# agents
|
# agents
|
||||||
.claude/
|
.claude/
|
||||||
@@ -9,13 +10,12 @@ TASK.md
|
|||||||
# build artifacts (applies to all packages)
|
# build artifacts (applies to all packages)
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
|
install/
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
|
|
||||||
# downloaded toolchain binaries
|
# downloaded toolchain binaries
|
||||||
gcc-arm-none-eabi/gcc_arm_none_eabi/toolchain/
|
gcc-arm-none-eabi/gcc_arm_none_eabi/toolchain/
|
||||||
|
|
||||||
# built capnproto
|
|
||||||
capnproto/capnproto/install/
|
|
||||||
|
|
||||||
# built ffmpeg
|
# downloaded git-lfs
|
||||||
ffmpeg/ffmpeg/install/
|
git-lfs/git_lfs/bin/
|
||||||
|
|||||||
51
README.md
51
README.md
@@ -1,14 +1,24 @@
|
|||||||
# dependencies
|
# dependencies
|
||||||
|
|
||||||
a central repo for managing and vendoring third party dependencies for all comma projects.
|
a central repo for managing and [vendoring](https://htmx.org/essays/vendoring/) third party dependencies for all comma projects.
|
||||||
|
|
||||||
all of our projects are python projects, so each of these gets packaged as a pip project.
|
since all our projects are Python, we wrap each vendored dependency as a pip package. `git clone` and `uv sync` is all you need.
|
||||||
|
|
||||||
this vendoring serves a few goals:
|
motivations for this approach
|
||||||
- all dependencies are centrally managed here
|
- `apt-get` is slow
|
||||||
- we can slim them down to only what we need
|
- `apt-get` updates its packages on a schedule we don't control
|
||||||
- all platforms get the same versions installed
|
- `apt-get` package versions don't match `brew` versions
|
||||||
- tighter control of distribution for fast installs (e.g. Ubuntu's `apt-get` is slow)
|
- `apt-get` doesn't come with Arch Linux
|
||||||
|
- `apt-get` doesn't always have the exact package we need
|
||||||
|
- `apt-get` packages are often bloated
|
||||||
|
|
||||||
|
<!--
|
||||||
|
this critically adds friction to adding dependencies to our project
|
||||||
|
- `apt-get` installing a package is easy. is it 1MB, 10MB, or 100MB? no idea.
|
||||||
|
- `apt-get` installing a package is much easier than adding it here. how much do you want it?
|
||||||
|
-->
|
||||||
|
|
||||||
|
`uv`, as opposed to `apt-get`, `brew`, and friends, is fast and already used in our projects.
|
||||||
|
|
||||||
we target the following platforms:
|
we target the following platforms:
|
||||||
- Linux x86_64
|
- Linux x86_64
|
||||||
@@ -16,3 +26,30 @@ we target the following platforms:
|
|||||||
- Darwin aarch64 (Apple Silicon)
|
- Darwin aarch64 (Apple Silicon)
|
||||||
|
|
||||||
contributions welcome for other platforms!
|
contributions welcome for other platforms!
|
||||||
|
|
||||||
|
## packages
|
||||||
|
|
||||||
|
| package | description |
|
||||||
|
|-------------------|--------------------------------------------------------------------------|
|
||||||
|
| gcc-arm-none-eabi | builds [panda](https://github.com/commaai/panda) firmware for STM32 MCUs |
|
||||||
|
| capnproto | message serialization for openpilot |
|
||||||
|
| ffmpeg | video encode and decode for openpilot |
|
||||||
|
| git-lfs | for tracking large files in openpilot |
|
||||||
|
| zeromq | bridging the openpilot IPC between different hosts |
|
||||||
|
|
||||||
|
## usage
|
||||||
|
|
||||||
|
```python
|
||||||
|
dependencies = [
|
||||||
|
"capnproto @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=capnproto",
|
||||||
|
"ffmpeg @ git+https://github.com/commaai/dependencies.git@releases#subdirectory=ffmpeg",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## workflow
|
||||||
|
|
||||||
|
to add a new package:
|
||||||
|
* start a new top-level directory as a new package
|
||||||
|
* `./test.sh` tests the building of all packages
|
||||||
|
* on pushes to `master`, wheels are built for our target platforms and pushed to a GitHub release
|
||||||
|
* the `releases` branch contains shim packages that allow pointing to a git branch and always getting the appropriate wheel for your platform
|
||||||
|
|||||||
34
eigen/build.sh
Executable file
34
eigen/build.sh
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||||
|
cd "$DIR"
|
||||||
|
|
||||||
|
VERSION="3.4.0"
|
||||||
|
INSTALL_DIR="$DIR/eigen/install"
|
||||||
|
|
||||||
|
# Idempotent: skip if already present
|
||||||
|
if [ -d "$INSTALL_DIR/eigen3/Eigen" ]; then
|
||||||
|
echo "eigen already present, skipping download."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARBALL="eigen-${VERSION}.tar.gz"
|
||||||
|
URL="https://gitlab.com/libeigen/eigen/-/archive/${VERSION}/${TARBALL}"
|
||||||
|
|
||||||
|
echo "Downloading Eigen ${VERSION} ..."
|
||||||
|
curl -fSL -o "$TARBALL" "$URL"
|
||||||
|
|
||||||
|
echo "Extracting headers ..."
|
||||||
|
rm -rf "$INSTALL_DIR"
|
||||||
|
mkdir -p "$INSTALL_DIR/eigen3"
|
||||||
|
|
||||||
|
# Extract only the Eigen/ and unsupported/Eigen/ header directories
|
||||||
|
tar --strip-components=1 -xzf "$TARBALL" -C "$INSTALL_DIR/eigen3" \
|
||||||
|
"eigen-${VERSION}/Eigen" \
|
||||||
|
"eigen-${VERSION}/unsupported"
|
||||||
|
|
||||||
|
rm -f "$TARBALL"
|
||||||
|
|
||||||
|
echo "Installed eigen to $INSTALL_DIR"
|
||||||
|
du -sh "$INSTALL_DIR"
|
||||||
9
eigen/eigen/__init__.py
Normal file
9
eigen/eigen/__init__.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
DIR = os.path.join(os.path.dirname(__file__), "install")
|
||||||
|
INCLUDE_DIR = DIR
|
||||||
|
LIB_DIR = DIR # header-only; no libraries
|
||||||
|
|
||||||
|
|
||||||
|
def smoketest():
|
||||||
|
assert os.path.isdir(os.path.join(DIR, "eigen3", "Eigen")), "Eigen headers not found"
|
||||||
15
eigen/pyproject.toml
Normal file
15
eigen/pyproject.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=64", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "eigen"
|
||||||
|
version = "3.4.0"
|
||||||
|
description = "Eigen C++ linear algebra headers"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
include = ["eigen*"]
|
||||||
|
|
||||||
|
[tool.setuptools.package-data]
|
||||||
|
eigen = ["install/**/*"]
|
||||||
61
eigen/setup.py
Normal file
61
eigen/setup.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from setuptools.command.build_py import build_py
|
||||||
|
|
||||||
|
try:
|
||||||
|
from wheel.bdist_wheel import bdist_wheel
|
||||||
|
except ImportError:
|
||||||
|
bdist_wheel = None
|
||||||
|
|
||||||
|
|
||||||
|
class BuildEigen(build_py):
|
||||||
|
"""Run build.sh to download Eigen headers before collecting package data."""
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
marker = os.path.join(pkg_dir, "eigen", "install", "eigen3", "Eigen")
|
||||||
|
|
||||||
|
if not os.path.isdir(marker):
|
||||||
|
build_script = os.path.join(pkg_dir, "build.sh")
|
||||||
|
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||||
|
|
||||||
|
super().run()
|
||||||
|
|
||||||
|
|
||||||
|
cmdclass = {"build_py": BuildEigen}
|
||||||
|
|
||||||
|
if bdist_wheel is not None:
|
||||||
|
|
||||||
|
class PlatformWheel(bdist_wheel):
|
||||||
|
"""Produce a platform-specific, Python-version-agnostic wheel."""
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
super().finalize_options()
|
||||||
|
self.root_is_pure = False
|
||||||
|
|
||||||
|
def get_tag(self):
|
||||||
|
system = platform.system()
|
||||||
|
machine = platform.machine()
|
||||||
|
|
||||||
|
if system == "Linux":
|
||||||
|
plat = f"linux_{machine}"
|
||||||
|
elif system == "Darwin":
|
||||||
|
plat = "macosx_11_0_arm64"
|
||||||
|
else:
|
||||||
|
plat = f"{system.lower()}_{machine}"
|
||||||
|
|
||||||
|
return "py3", "none", plat
|
||||||
|
|
||||||
|
cmdclass["bdist_wheel"] = PlatformWheel
|
||||||
|
|
||||||
|
|
||||||
|
def setup():
|
||||||
|
from setuptools import setup as _setup
|
||||||
|
|
||||||
|
_setup(cmdclass=cmdclass)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
setup()
|
||||||
57
git-lfs/build.sh
Executable file
57
git-lfs/build.sh
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
|
||||||
|
cd "$DIR"
|
||||||
|
|
||||||
|
VERSION="3.6.1"
|
||||||
|
INSTALL_DIR="$DIR/git_lfs/bin"
|
||||||
|
|
||||||
|
# Idempotent: skip if already present
|
||||||
|
if [ -x "$INSTALL_DIR/git-lfs" ]; then
|
||||||
|
echo "git-lfs already present, skipping download."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
OS="$(uname -s)"
|
||||||
|
ARCH="$(uname -m)"
|
||||||
|
|
||||||
|
case "${OS}-${ARCH}" in
|
||||||
|
Linux-x86_64) PLATFORM="linux-amd64" ; EXT="tar.gz" ;;
|
||||||
|
Linux-aarch64) PLATFORM="linux-arm64" ; EXT="tar.gz" ;;
|
||||||
|
Darwin-arm64) PLATFORM="darwin-arm64" ; EXT="zip" ;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported platform: ${OS}-${ARCH}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
FILENAME="git-lfs-${PLATFORM}-v${VERSION}.${EXT}"
|
||||||
|
URL="https://github.com/git-lfs/git-lfs/releases/download/v${VERSION}/${FILENAME}"
|
||||||
|
|
||||||
|
echo "Downloading $FILENAME ..."
|
||||||
|
curl -fSL -o "$FILENAME" "$URL"
|
||||||
|
|
||||||
|
echo "Extracting ..."
|
||||||
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
if [ "$EXT" = "zip" ]; then
|
||||||
|
python3 -c "
|
||||||
|
import zipfile, sys
|
||||||
|
with zipfile.ZipFile('$FILENAME') as zf:
|
||||||
|
for info in zf.infolist():
|
||||||
|
if info.filename.endswith('/git-lfs'):
|
||||||
|
with open('$INSTALL_DIR/git-lfs', 'wb') as f:
|
||||||
|
f.write(zf.read(info))
|
||||||
|
break
|
||||||
|
"
|
||||||
|
else
|
||||||
|
tar --strip-components=1 -xzf "$FILENAME" -C "$INSTALL_DIR" --wildcards '*/git-lfs'
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod +x "$INSTALL_DIR/git-lfs"
|
||||||
|
strip "$INSTALL_DIR/git-lfs" 2>/dev/null || true
|
||||||
|
|
||||||
|
rm -f "$FILENAME"
|
||||||
|
|
||||||
|
echo "Installed git-lfs to $INSTALL_DIR"
|
||||||
|
du -sh "$INSTALL_DIR"
|
||||||
15
git-lfs/git_lfs/__init__.py
Normal file
15
git-lfs/git_lfs/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
BIN_DIR = os.path.join(os.path.dirname(__file__), "bin")
|
||||||
|
|
||||||
|
|
||||||
|
def _run():
|
||||||
|
binary = os.path.join(BIN_DIR, "git-lfs")
|
||||||
|
os.execvp(binary, [binary] + sys.argv[1:])
|
||||||
|
|
||||||
|
|
||||||
|
def smoketest():
|
||||||
|
import subprocess
|
||||||
|
binary = os.path.join(BIN_DIR, "git-lfs")
|
||||||
|
subprocess.run([binary, "--version"], check=True)
|
||||||
18
git-lfs/pyproject.toml
Normal file
18
git-lfs/pyproject.toml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=64", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "git-lfs"
|
||||||
|
version = "3.6.1"
|
||||||
|
description = "Git Large File Storage extension"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
git-lfs = "git_lfs:_run"
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
include = ["git_lfs*"]
|
||||||
|
|
||||||
|
[tool.setuptools.package-data]
|
||||||
|
git_lfs = ["bin/**/*"]
|
||||||
61
git-lfs/setup.py
Normal file
61
git-lfs/setup.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from setuptools.command.build_py import build_py
|
||||||
|
|
||||||
|
try:
|
||||||
|
from wheel.bdist_wheel import bdist_wheel
|
||||||
|
except ImportError:
|
||||||
|
bdist_wheel = None
|
||||||
|
|
||||||
|
|
||||||
|
class BuildGitLfs(build_py):
|
||||||
|
"""Run build.sh to download git-lfs before collecting package data."""
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
pkg_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
marker = os.path.join(pkg_dir, "git_lfs", "bin", "git-lfs")
|
||||||
|
|
||||||
|
if not os.path.exists(marker):
|
||||||
|
build_script = os.path.join(pkg_dir, "build.sh")
|
||||||
|
subprocess.check_call(["bash", build_script], cwd=pkg_dir)
|
||||||
|
|
||||||
|
super().run()
|
||||||
|
|
||||||
|
|
||||||
|
cmdclass = {"build_py": BuildGitLfs}
|
||||||
|
|
||||||
|
if bdist_wheel is not None:
|
||||||
|
|
||||||
|
class PlatformWheel(bdist_wheel):
|
||||||
|
"""Produce a platform-specific, Python-version-agnostic wheel."""
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
super().finalize_options()
|
||||||
|
self.root_is_pure = False
|
||||||
|
|
||||||
|
def get_tag(self):
|
||||||
|
system = platform.system()
|
||||||
|
machine = platform.machine()
|
||||||
|
|
||||||
|
if system == "Linux":
|
||||||
|
plat = f"linux_{machine}"
|
||||||
|
elif system == "Darwin":
|
||||||
|
plat = "macosx_11_0_arm64"
|
||||||
|
else:
|
||||||
|
plat = f"{system.lower()}_{machine}"
|
||||||
|
|
||||||
|
return "py3", "none", plat
|
||||||
|
|
||||||
|
cmdclass["bdist_wheel"] = PlatformWheel
|
||||||
|
|
||||||
|
|
||||||
|
def setup():
|
||||||
|
from setuptools import setup as _setup
|
||||||
|
|
||||||
|
_setup(cmdclass=cmdclass)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
setup()
|
||||||
Reference in New Issue
Block a user