Skip to content

Commit 11f0412

Browse files
bolinfestfacebook-github-bot
authored andcommitted
write "Depends" into .deb and build for Python 3.10 on Ubuntu 22.04
Summary: Although D39042765 (a04fc2e) appeared to successfully produce `.deb` files, it turns out that they would only work if you already had the requisite package dependencies installed. For example, running `hg --version` on a clean Ubuntu instance would yield: ``` hg: error while loading shared libraries: libpython3.8.so.1.0: cannot open shared object file: No such file or directory ``` It turned out that our `DEBIAN/control` file was missing a key `Depends:` line to tell `dpkg` what dependencies to install. Once again, I decided to look and see how wezterm deals with this, and the solution appears to be `dpkg-shlibdeps`: https://github.com/wez/wezterm/blob/97eaa58112a4/ci/deploy.sh#L234,L240 `dpkg-shlibdeps` looks at your executables and, based on the symbols, determines what the appropriate packages are. For our Ubuntu 22.04 `.deb`, this turns out to be: ``` Depends: libc6 (>= 2.34), libgcc-s1 (>= 4.2), libpython3.10 (>= 3.10.0), libssl3 (>= 3.0.0~~alpha1), zlib1g (>= 1:1.1.4) ``` Apparently you cannot have a package in the `Depends:` line that comes from a PPA, so if you want to make your `.deb` easy for users to install, that means you should limit your dependencies to "standard" packages for the distro. In our case, that meant that our Ubuntu 22.04 `.deb` should use Python 3.10 instead of Python 3.8 (which we previously fetched from `ppa:deadsnakes/ppa`). In order to support this, this diff makes a number of changes: - Adds logic to `setup.py` to check the `PY_VERSION` environment variable to decide whether to use Python 3.10 or something else. - Updates `gen_workflows.py` to define different Python deps based on the Ubuntu version. - Updates `gen_workflows.py` to remove the logic that uses the `ppa:deadsnakes/ppa`. - Ran `buck2 run //eden/oss/ci:gen_workflows -- eden/oss/.github/workflows/` to update the GitHub Actions - Moved the logic for the `deb` target in the `Makefile` into a separate shell script because it was getting too complex to express directly in Make. - Introduced separate `deb-ubuntu-20.04` and `deb-ubuntu-22.04` targets in the `Makefile`. - Updated `bytearrayobject.rs` to support Python 3.10 in addition to Python 3.9. - Updated `pick_python.py` to consider `python3.10` if `python3.8` is not found before going down the rest of the list. As you can see in the Test Plan, we are *really close* to things "just working," but we also have to register `git` as a dependency, which is not discovered by `dpkg-shlibdeps`. This will be addressed in D39156794. Reviewed By: DurhamG Differential Revision: D39156794 fbshipit-source-id: ca1e0a73096e0de97230804a97f316114b8bfc2e
1 parent 50bb93c commit 11f0412

File tree

7 files changed

+61
-27
lines changed

7 files changed

+61
-27
lines changed

ci/gen_workflows.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,25 @@
2222

2323
UBUNTU_VERSIONS = ["20.04", "22.04"]
2424

25+
UBUNTU_VERSION_DEPS = {
26+
"20.04": [
27+
"python3.8",
28+
"python3.8-dev",
29+
"python3.8-distutils",
30+
],
31+
"22.04": [
32+
"python3.10",
33+
"python3.10-dev",
34+
"python3.10-distutils",
35+
],
36+
}
37+
2538
UBUNTU_DEPS = [
2639
"nodejs",
27-
"python3.8",
28-
"python3.8-dev",
2940
"pkg-config",
3041
"libssl-dev",
3142
"cython3",
3243
"make",
33-
"python3.8-distutils",
3444
"g++",
3545
"cargo",
3646
# This is needed for dpkg-name.
@@ -79,16 +89,7 @@ def gen_build_ubuntu_image(self, *, ubuntu_version: str) -> None:
7989
+ cargo_prefetch_commands
8090
)
8191

82-
python38_ppa = ""
83-
if ubuntu_version == "22.04":
84-
python38_ppa = """\
85-
RUN apt-get -y install software-properties-common
86-
RUN add-apt-repository -y ppa:deadsnakes/ppa
87-
RUN apt-get -y update
88-
"""
89-
else:
90-
python38_ppa = ""
91-
92+
full_deps = UBUNTU_DEPS + UBUNTU_VERSION_DEPS[ubuntu_version]
9293
dockerfile = f"""\
9394
FROM {image_name}
9495
@@ -104,9 +105,9 @@ def gen_build_ubuntu_image(self, *, ubuntu_version: str) -> None:
104105
# Use a PPA to ensure a specific version of Node (the default Node on
105106
# Ubuntu 20.04 is v10, which is too old):
106107
RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
107-
{python38_ppa}
108+
108109
# Now we can install the bulk of the packages:
109-
RUN apt-get -y install {' '.join(UBUNTU_DEPS)}
110+
RUN apt-get -y install {' '.join(full_deps)}
110111
111112
# Copy the full repo over because `cargo fetch` follows deps within the repo,
112113
# so assume it needs everything.
@@ -256,7 +257,7 @@ def gen_build_ubuntu_cli_job(self, *, ubuntu_version: str, deb_version_expr: str
256257
{
257258
"name": "Create .deb",
258259
"working-directory": "./eden/scm",
259-
"run": f"${{{{ format('VERSION=0.0-{{0}} make deb', env.{DEB_UPSTREAM_VERISION}) }}}}",
260+
"run": f"${{{{ format('VERSION=0.0-{{0}} make deb-ubuntu-{ubuntu_version}', env.{DEB_UPSTREAM_VERISION}) }}}}",
260261
},
261262
{
262263
"name": "Rename .deb",

eden/scm/Makefile

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,17 @@ build:
107107

108108
deb:
109109
DESTDIR=install make install-oss
110-
mkdir -p "install/DEBIAN"
111-
cp packaging/debian/control install/DEBIAN/control
112-
sed -i "s/%VERSION%/$(VERSION)/g" install/DEBIAN/control
113-
dpkg-deb --build --root-owner-group install
114-
dpkg-name install.deb
110+
# Define the build script in a separate file so we don't have to escape shell
111+
# commands to work with Make inline.
112+
./packaging/debian/build_deb.sh
113+
114+
deb-ubuntu-20.04:
115+
# For Ubuntu 20.04, target Python 3.8.
116+
PY_VERSION=38 make deb
117+
118+
deb-ubuntu-22.04:
119+
# For Ubuntu 22.04, target Python 3.10.
120+
PY_VERSION=310 make deb
115121

116122
rpm:
117123
rpmbuild \

eden/scm/contrib/pick_python.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def main(args):
2323
names = args or ["python3"]
2424
if names == ["python3"]:
2525
# Try different pythons
26-
names = ["python3.8", "python3.7", "python3.6"] + names
26+
names = ["python3.8", "python3.10", "python3.7", "python3.6"] + names
2727
for name in names:
2828
for dir in dirs:
2929
path = os.path.join(dir, name)

eden/scm/lib/cpython-ext/src/bytearrayobject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct PyByteArrayObject {
5151
}
5252

5353
#[cfg(feature = "python3")]
54-
#[cfg(Py_39)]
54+
#[cfg(any(Py_39, Py_310))]
5555
#[repr(C)]
5656
struct PyByteArrayObject {
5757
pub ob_base: PyVarObject,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
#
4+
# This software may be used and distributed according to the terms of the
5+
# GNU General Public License version 2.
6+
7+
set -e
8+
9+
# dpkg-shlibdeps requires the file `debian/control` to exist in the folder
10+
# in which it is run.
11+
mkdir -p install/debian
12+
cp packaging/debian/control install/debian
13+
cd install
14+
DEB_DEPS=$(dpkg-shlibdeps -O -e usr/local/bin/*)
15+
cd ..
16+
17+
# In contrast to dpkg-shlibdeps, dpkg-deb requires the file to be named
18+
# `DEBIAN/control`, so we rename the directory and proceed.
19+
mv install/debian install/DEBIAN
20+
echo "$DEB_DEPS" | sed -e 's/shlibs:Depends=/Depends: /' >> install/DEBIAN/control
21+
sed -i "s/%VERSION%/$VERSION/g" install/DEBIAN/control
22+
23+
dpkg-deb --build --root-owner-group install
24+
dpkg-name install.deb

eden/scm/packaging/debian/control

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ Version: %VERSION%
33
Architecture: amd64
44
Maintainer: Meta Platforms, Inc.
55
Description: A source control client.
6+
Source: https://github.com/facebookexperimental/eden

eden/scm/setup.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@
4343
if sys.version_info.major == 2:
4444
raise RuntimeError("This setup.py is Python 3 only!")
4545

46-
if os.name == "nt":
47-
PY_VERSION = "39"
48-
else:
49-
PY_VERSION = "38"
46+
PY_VERSION = os.environ.get("PY_VERSION")
47+
if PY_VERSION is None:
48+
if os.name == "nt":
49+
PY_VERSION = "39"
50+
else:
51+
PY_VERSION = "38"
5052

5153
ossbuild = bool(os.environ.get("SAPLING_OSS_BUILD"))
5254

0 commit comments

Comments
 (0)