Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update linux binary expectations #12622

Merged
merged 6 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,15 @@ mod linux {
let cli = env::current_exe()?;
let dir = cli
.parent()
.and_then(Path::parent)
.ok_or_else(|| anyhow!("no parent path for cli"))?;

match dir.join("zed").canonicalize() {
match dir.join("libexec").join("zed-editor").canonicalize() {
Ok(path) => Ok(path),
// development builds have Zed capitalized
Err(e) => match dir.join("Zed").canonicalize() {
Ok(path) => Ok(path),
Err(_) => Err(e),
// In development cli and zed are in the ./target/ directory together
Err(e) => match cli.parent().unwrap().join("zed").canonicalize() {
Ok(path) if path != cli => Ok(path),
_ => Err(e),
},
}
}?;
Expand Down Expand Up @@ -254,10 +255,8 @@ mod linux {
eprintln!("failed to setsid: {}", std::io::Error::last_os_error());
process::exit(1);
}
if std::env::var("ZED_KEEP_FD").is_err() {
if let Err(_) = fork::close_fd() {
eprintln!("failed to close_fd: {}", std::io::Error::last_os_error());
}
if let Err(_) = fork::close_fd() {
eprintln!("failed to close_fd: {}", std::io::Error::last_os_error());
}
let error =
exec::execvp(path.clone(), &[path.as_os_str(), &OsString::from(ipc_url)]);
Expand Down Expand Up @@ -333,7 +332,7 @@ mod flatpak {

if !is_app_location_set {
args.push("--zed".into());
args.push(flatpak_dir.join("bin").join("zed-app").into());
args.push(flatpak_dir.join("libexec").join("zed-editor").into());
}

let error = exec::execvp("/usr/bin/flatpak-spawn", args);
Expand All @@ -347,7 +346,7 @@ mod flatpak {
&& env::var("FLATPAK_ID").map_or(false, |id| id.starts_with("dev.zed.Zed"))
{
if args.zed.is_none() {
args.zed = Some("/app/bin/zed-app".into());
args.zed = Some("/app/libexec/zed-editor".into());
env::set_var("ZED_IS_FLATPAK_INSTALL", "1");
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/zed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ authors = ["Zed Team <hi@zed.dev>"]
workspace = true

[[bin]]
name = "Zed"
name = "zed"
path = "src/main.rs"

[dependencies]
Expand Down
4 changes: 2 additions & 2 deletions crates/zed/resources/flatpak/manifest-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
"envsubst < zed.desktop.in > zed.desktop && install -Dm644 zed.desktop /app/share/applications/$APP_ID.desktop",
"envsubst < flatpak/zed.metainfo.xml.in > zed.metainfo.xml && install -Dm644 zed.metainfo.xml /app/share/metainfo/$APP_ID.metainfo.xml",
"sed -i -e '/@release_info@/{r flatpak/release-info/$CHANNEL' -e 'd}' /app/share/metainfo/$APP_ID.metainfo.xml",
"install -Dm755 bin/cli /app/bin/zed",
"install -Dm755 bin/zed /app/bin/zed-app",
"install -Dm755 bin/zed /app/bin/zed",
"install -Dm755 libexec/zed-editor /app/libexec/zed-editor",
"install -Dm755 lib/* -t /app/lib"
],
"sources": [
Expand Down
30 changes: 29 additions & 1 deletion docs/src/development/linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,38 @@ cargo test --workspace

Zed has basic support for both modes. The mode is selected at runtime. If you're on wayland and want to run in X11 mode, you can set `WAYLAND_DISPLAY='' cargo run` to do so.

## Notes for packaging Zed

Thank you for taking on the task of packaging Zed!

### Technical requirements

Zed has two main binaries:

* You will need to build `crates/cli` and make it's binary available in `$PATH` with the name `zed`.
* You will need to build `crates/zed` and put it at `$PATH/to/cli/../../libexec/zed-editor`. For example, if you are going to put the cli at `~/.local/bin/zed` put zed at `~/.local/libexec/zed-editor`.
* If you are going to provide a `.desktop` file you can find a template in `crates/zed/resources/zed.desktop.in`, and use `envsubst` to populate it with the values required.
* You will need to ensure that the necessary libraries are installed. You can get the current list by [inspecting the built binary](https://github.com/zed-industries/zed/blob/059a4141b756cf4afac4c977afc488539aec6470/script/bundle-linux#L65-L70) on your system.
* For an example of a complete build script, see [script/bundle-linux](https://github.com/zed-industries/zed/blob/main/script/bundle-linux).

### Other things to note

At Zed, our priority has been to move fast and bring the latest technology to our users. We've long been frustrated at having software that is slow, out of date, or hard to configure, and so we've built our editor to those tastes.

However, we realize that many distros have other priorities. We want to work with everyone to bring Zed to their favorite platforms. But there is a long way to go:

* Zed is a fast moving early-phase project. We typically release 2-3 builds a week to fix user-reported issues and release major features.
* There are a couple of other `zed` binaries that may be present on linux systems ([1](https://openzfs.github.io/openzfs-docs/man/v2.2/8/zed.8.html), [2](https://zed.brimdata.io/docs/commands/zed)).
* We automatically install updates to Zed by default (though we do need a way for [package managers to opt out](https://github.com/zed-industries/zed/issues/12588)).
* Zed automatically installs the correct version of common developer tools in the same way as rustup/rbenv/pyenv, etc. We understand that this is contentious, [see here](https://github.com/zed-industries/zed/issues/12589).
* We allow users to install extensions on their own and from [zed-industries/extensions](https://github.com/zed-industries/extensions). These extensions may install further tooling as needed, such as language servers. In the long run we would like to make this safer, [see here](https://github.com/zed-industries/zed/issues/12358).
* Zed connects to a number of online services by default (AI, telemetry, collaboration). AI and our telemetry can be disabled by your users with their own zed settings or by patching our [default settings file](https://github.com/zed-industries/zed/blob/main/assets/settings/default.json).
* As a result, zed currently does not play nice with sandboxes, [see here](https://github.com/zed-industries/zed/pull/12006#issuecomment-2130421220)

## Flatpak

> [!WARNING]
> Zed's current Flatpak integration simply exits the sandbox on startup. Workflows that rely on Flatpak's sandboxing may not work as expected.
> Zed's current Flatpak integration simply exits the sandbox on startup. Workflows that rely on Flatpak's sandboxing may not work as expected.

To build & install the Flatpak package locally follow the steps below:

Expand Down
10 changes: 5 additions & 5 deletions script/bundle-linux
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ cargo build --release --target "${target_triple}" --package zed --package cli

# Strip the binary of all debug symbols
# Later, we probably want to do something like this: https://github.com/GabrielMajeri/separate-symbols
strip "target/${target_triple}/release/Zed"
strip "target/${target_triple}/release/zed"
strip "target/${target_triple}/release/cli"

suffix=""
Expand All @@ -57,13 +57,13 @@ temp_dir=$(mktemp -d)
zed_dir="${temp_dir}/zed$suffix.app"

# Binary
mkdir -p "${zed_dir}/bin"
cp "target/${target_triple}/release/Zed" "${zed_dir}/bin/zed"
cp "target/${target_triple}/release/cli" "${zed_dir}/bin/cli"
mkdir -p "${zed_dir}/bin" "${zed_dir}/libexec"
cp "target/${target_triple}/release/zed" "${zed_dir}/libexec/zed-editor"
cp "target/${target_triple}/release/cli" "${zed_dir}/bin/zed"

# Libs
find_libs() {
ldd target/${target_triple}/release/Zed |\
ldd target/${target_triple}/release/zed |\
cut -d' ' -f3 |\
grep -v '\<\(libstdc++.so\|libc.so\|libgcc_s.so\|libm.so\|libpthread.so\|libdl.so\)'
}
Expand Down
22 changes: 10 additions & 12 deletions script/bundle-mac
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ local_arch=false
local_only=false
local_install=false
bundle_name=""
zed_crate="zed"
binary_name="Zed"

# This must match the team in the provisioning profile.
APPLE_NOTORIZATION_TEAM="MQ55VZLNZQ"
Expand Down Expand Up @@ -80,18 +78,18 @@ local_target_triple=${host_line#*: }

if [ "$local_arch" = true ]; then
echo "Building for local target only."
cargo build ${build_flag} --package ${zed_crate} --package cli
cargo build ${build_flag} --package zed --package cli
else
echo "Compiling zed binaries"
cargo build ${build_flag} --package ${zed_crate} --package cli --target aarch64-apple-darwin --target x86_64-apple-darwin
cargo build ${build_flag} --package zed --package cli --target aarch64-apple-darwin --target x86_64-apple-darwin
fi

echo "Creating application bundle"
pushd crates/zed
channel=$(<RELEASE_CHANNEL)
popd

pushd crates/${zed_crate}
pushd crates/zed
cp Cargo.toml Cargo.toml.backup
sed \
-i .backup \
Expand Down Expand Up @@ -186,7 +184,7 @@ function prepare_binaries() {
target/${architecture}/${target_dir}/Zed.dwarf.gz \
"$channel/Zed-$version-${architecture}.dwarf.gz"

cp target/${architecture}/${target_dir}/${binary_name} "${app_path}/Contents/MacOS/${zed_crate}"
cp target/${architecture}/${target_dir}/zed "${app_path}/Contents/MacOS/zed"
cp target/${architecture}/${target_dir}/cli "${app_path}/Contents/MacOS/cli"
}

Expand All @@ -207,7 +205,7 @@ function sign_binaries() {
download_git "${architecture}" "${app_path}/Contents/MacOS/git"

# Note: The app identifier for our development builds is the same as the app identifier for nightly.
cp crates/${zed_crate}/contents/$channel/embedded.provisionprofile "${app_path}/Contents/"
cp crates/zed/contents/$channel/embedded.provisionprofile "${app_path}/Contents/"

if [[ -n "${MACOS_CERTIFICATE:-}" && -n "${MACOS_CERTIFICATE_PASSWORD:-}" && -n "${APPLE_NOTARIZATION_USERNAME:-}" && -n "${APPLE_NOTARIZATION_PASSWORD:-}" ]]; then
echo "Signing bundle with Apple-issued certificate"
Expand All @@ -223,8 +221,8 @@ function sign_binaries() {
/usr/bin/codesign --deep --force --timestamp --sign "Zed Industries, Inc." "${app_path}/Contents/Frameworks/WebRTC.framework" -v
/usr/bin/codesign --deep --force --timestamp --options runtime --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/cli" -v
/usr/bin/codesign --deep --force --timestamp --options runtime --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/git" -v
/usr/bin/codesign --deep --force --timestamp --options runtime --entitlements crates/${zed_crate}/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/${zed_crate}" -v
/usr/bin/codesign --force --timestamp --options runtime --entitlements crates/${zed_crate}/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}" -v
/usr/bin/codesign --deep --force --timestamp --options runtime --entitlements crates/zed/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/zed" -v
/usr/bin/codesign --force --timestamp --options runtime --entitlements crates/zed/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}" -v

security default-keychain -s login.keychain
else
Expand All @@ -243,7 +241,7 @@ function sign_binaries() {
# - get a signing key for the MQ55VZLNZQ team from Nathan.
# - create your own signing key, and update references to MQ55VZLNZQ to your own team ID
# then comment out this line.
cat crates/${zed_crate}/resources/zed.entitlements | sed '/com.apple.developer.associated-domains/,+1d' > "${app_path}/Contents/Resources/zed.entitlements"
cat crates/zed/resources/zed.entitlements | sed '/com.apple.developer.associated-domains/,+1d' > "${app_path}/Contents/Resources/zed.entitlements"

codesign --force --deep --entitlements "${app_path}/Contents/Resources/zed.entitlements" --sign ${MACOS_SIGNING_KEY:- -} "${app_path}" -v
fi
Expand Down Expand Up @@ -364,9 +362,9 @@ else
app_path=target/release/$(basename "$app_path_x64")
lipo \
-create \
target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/${binary_name} \
target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/zed \
-output \
"${app_path}/Contents/MacOS/${zed_crate}"
"${app_path}/Contents/MacOS/zed"
lipo \
-create \
target/{x86_64-apple-darwin,aarch64-apple-darwin}/${target_dir}/cli \
Expand Down
7 changes: 6 additions & 1 deletion script/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ linux() {
mkdir -p "$HOME/.local/bin" "$HOME/.local/share/applications"

# Link the binary
ln -sf ~/.local/zed$suffix.app/bin/cli "$HOME/.local/bin/zed"
if [ -f ~/.local/zed$suffix.app/bin/zed ]; then
ln -sf ~/.local/zed$suffix.app/bin/zed "$HOME/.local/bin/zed"
else
# support for versions before 0.139.x.
ln -sf ~/.local/zed$suffix.app/bin/cli "$HOME/.local/bin/zed"
fi

# Copy .desktop file
desktop_file_path="$HOME/.local/share/applications/${appid}.desktop"
Expand Down
4 changes: 2 additions & 2 deletions script/zed-local
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ if (user) {
}

let buildArgs = ["build"];
let zedBinary = "target/debug/Zed";
let zedBinary = "target/debug/zed";
if (isReleaseMode) {
buildArgs.push("--release");
zedBinary = "target/release/Zed";
zedBinary = "target/release/zed";
}

try {
Expand Down
Loading