Coder Social home page Coder Social logo

cargo-deb's Introduction

Debian packages from Cargo projects

This is a Cargo helper command which automatically creates binary Debian packages (.deb) from Cargo projects.

Note

cargo-deb uses the xz2 crate that bundles an old safe version of liblzma 5.2 by the original maintainer, and a simple Cargo-based build script. It is unaffected by the CVE-2024-3094.

Installation

rustup update   # Debian's Rust is too outdated, use rustup.rs
cargo install cargo-deb

Requires Rust 1.63+, and optionally dpkg, dpkg-dev and liblzma-dev. Compatible with Ubuntu. If the LZMA dependency causes you headaches, try cargo install cargo-deb --no-default-features.

If you get a compilation error, run rustup update! If you get an error running rustup update, uninstall your rust/cargo package, and install the official Rust instead.

Usage

cargo deb

Upon running cargo deb from the base directory of your Rust project, the Debian package will be created in target/debian/<project_name>_<version>-1_<arch>.deb (or you can change the location with the --output option). This package can be installed with dpkg -i target/debian/*.deb.

Debug symbols are stripped from the main binary by default, unless [profile.release] debug = true is set in Cargo.toml. If cargo deb --separate-debug-symbols is run, the debug symbols will be packaged as a separate file installed at /usr/lib/debug/<path-to-binary>.debug. This can also be configured in the [package.metadata.deb] section with the separate-debug-symbols key. If it is enabled there the parameter cargo deb --no-separate-debug-symbols can be used to suppress inclusion of the debug symbols.

cargo deb --install builds and installs the project system-wide.

Configuration

Important

Since v2.0.0 the deb package version will have a "-1" suffix. You can disable this by adding --deb-revision="" flag or revision = "" in Cargo metadata. The default suffix is for compliance with Debian's packaging standard.

No configuration is necessary to make a basic package from a Cargo project with a binary. This command obtains basic information it needs from the Cargo.toml file. It uses Cargo fields: name, version, license, license-file, description, readme, homepage, and repository.

For a more complete Debian package, you may also define a new table, [package.metadata.deb] that contains maintainer, copyright, license-file, changelog, depends, conflicts, breaks, replaces, provides, extended-description/extended-description-file, section, priority, and assets.

For a Debian package that includes one or more systemd unit files you may also wish to define a new (inline) table, [package.metadata.deb.systemd-units], so that the unit files are automatically added as assets and the units are properly installed. Systemd integration

[package.metadata.deb] options

Everything is optional:

  • name: The name of the Debian package. If not present, the name of the crate is used.
  • maintainer: The person maintaining the Debian packaging. If not present, the first author is used.
  • copyright: To whom and when the copyright of the software is granted. If not present, the list of authors is used.
  • license-file: 2-element array with a location of the license file and the amount of lines to skip at the top. If not present, package-level license-file is used.
  • depends: The runtime dependencies of the project. Generated automatically when absent, or if the list includes the $auto keyword.
  • pre-depends: The pre-dependencies of the project. This will be empty by default.
  • recommends: The recommended dependencies of the project. This will be empty by default.
  • suggests: The suggested dependencies of the project. This will be empty by default.
  • enhances: A list of packages this package can enhance. This will be empty by default.
  • conflicts, breaks, replaces, providespackage transition control.
  • extended-description: An extended description of the project — the more detailed the better. Either extended-description-file (see below) or package's readme file is used if it is not provided.
  • extended-description-file: A file with extended description of the project. When specified, used if extended-description is not provided.
  • revision: An additional version of the Debian package (when the package is updated more often than the project). It defaults to "1", but can be set to an empty string to omit the revision.
  • section: The application category that the software belongs to.
  • priority: Defines if the package is required or optional.
  • assets: Files to be included in the package and the permissions to assign them. If assets are not specified, then defaults are taken from binaries listed in [[bin]] (copied to /usr/bin/) and package readme (copied to usr/share/doc/…).
    1. The first argument of each asset is the location of that asset in the Rust project. Glob patterns are allowed. You can use target/release/ in asset paths, even if Cargo is configured to cross-compile or use custom CARGO_TARGET_DIR. The target dir paths will be automatically corrected.
    2. The second argument is where the file will be copied.
      • If is argument ends with / it will be inferred that the target is the directory where the file will be copied.
      • Otherwise, it will be inferred that the source argument will be renamed when copied.
    3. The third argument is the permissions (octal string) to assign that file.
  • merge-assets: See "Merging Assets" section under "Advanced Usage"
  • maintainer-scripts: directory containing templates, preinst, postinst, prerm, or postrm scripts.
  • conf-files: List of configuration files that the package management system will not overwrite when the package is upgraded.
  • triggers-file: Path to triggers control file for use by the dpkg trigger facility.
  • changelog: Path to Debian-formatted changelog file.
  • features: List of Cargo features to use when building the package.
  • default-features: whether to use default crate features in addition to the features list (default true).
  • separate-debug-symbols: whether to keep debug symbols, but strip them from executables and save them in separate files (default false).
  • preserve-symlinks: Whether to preserve symlinks in the asset files (default false).
  • systemd-units: Optional configuration settings for automated installation of systemd units.

Example of custom Cargo.toml additions

[package.metadata.deb]
maintainer = "Michael Aaron Murphy <[email protected]>"
copyright = "2017, Michael Aaron Murphy <[email protected]>"
license-file = ["LICENSE", "4"]
extended-description = """\
A simple subcommand for the Cargo package manager for \
building Debian packages from Rust projects."""
depends = "$auto"
section = "utility"
priority = "optional"
assets = [
    ["target/release/cargo-deb", "usr/bin/", "755"],
    ["README.md", "usr/share/doc/cargo-deb/README", "644"],
]

Advanced usage

Debian packages can use a number of different compression formats, but the target system may only support some of them. The default format is currently xz, but this may change at any point to support newer formats. The format can be explicitly specified using the --compress-type command-line option. The supported formats are "gzip" and "xz".

--fast flag uses lighter compression. Useful for very large packages or quick deployment.

--compress-system forces the use of system command-line tools for data compression.

[package.metadata.deb.variants.$name]

There can be multiple variants of the metadata in one Cargo.toml file. --variant=name selects the variant to use. Options set in a variant override [package.metadata.deb] options. It automatically adjusts package name.

Merging Assets

When defining a variant it can be useful to also define a asset merging strategy.

If the merge-assets option is used, cargo-deb will merge the list of assets provided to the option with the parent asset list. There are three merging strategies, append, by.dest, and by.src.

  • merge-assets.append: Appends this list of assets to the parent list of assets.
  • merge-assets.by.dest: Merges this list of assets to the parent list of assets, joining on the destination path. Will replace both the source path and permissions.
  • merge-assets.by.src: Merges this list of assets to the parent list of assets, joining on the source path. Will replace both the destination path and permissions.

Note: Using both append, and a by.* option are allowed, w/ the former being applied before the latter.

Example of merge-assets

# Example parent asset list
[package.metadata.deb]
assets = [
    # binary
    ["target/release/example", "usr/bin/", "755"],
    # assets
    ["assets/*", "var/lib/example", "644"],
    ["target/release/assets/*", "var/lib/example", "644"],
    ["3.txt", "var/lib/example/3.txt", "644"],
    ["3.txt", "var/lib/example/merged.txt", "644"],
]

# Example merging by appending asset list
[package.metadata.deb.variants.mergeappend]
merge-assets.append = [
    ["4.txt", "var/lib/example/appended/4.txt", "644"]
]

# Example merging by `dest` path
[package.metadata.deb.variants.mergedest]
merge-assets.by.dest = [
    ["4.txt", "var/lib/example/merged.txt", "644"]
]

# Example merging by `src` path
[package.metadata.deb.variants.mergesrc]
merge-assets.by.src = [
    ["3.txt", "var/lib/example/merged-2.txt", "644"]
]

# Example merging by appending and by `src` path
[package.metadata.deb.variants.mergeappendandsrc]
merge-assets.append = [
    ["4.txt", "var/lib/example/appended/4.txt", "644"]
]
merge-assets.by.src = [
    ["3.txt", "var/lib/example/merged-2.txt", "644"]
]

[package.metadata.deb.systemd-units]

See systemd integration.

Cross-compilation

cargo deb supports cross-compilation. It can be run from any unix-like host, including macOS, provided that the build environment is set up for cross-compilation:

  • The cross-compilation target has to be installed via rustup (e.g. rustup target add i686-unknown-linux-gnu) and has to be installed for the host system (e.g. apt-get install libc6-dev-i386). Note that Rust's and Debian's architecture names are different. See rustc --print target-list for the list of supported values for the --target argument.
  • A Linux-compatible linker and system libraries (e.g. glibc or musl) must be installed and available to Rust/Cargo,
    • dpkg --add-architecture <debian architecture name>
    • apt-get install pkg-config build-essential crossbuild-essential-<debian architecture name>
  • Cargo must be configured to use a cross-linker.
  • Cargo dependencies that use C libraries probably won't work, unless you install a target's sysroot for pkg-config. Setting PKG_CONFIG_ALLOW_CROSS=1 will not help at all, and will only make things worse.
    • apt-get install libssl-dev:<debian architecture name>
  • Cargo dependencies that build C code probably won't work, unless you install a C compiler for the target system, and configure appropriate CC_<target> variables.
    • export HOST_CC=gcc
    • export CC_x86_64_unknown_linux_gnu=/usr/bin/x86_64-linux-gnu-gcc (correct the target and paths for your OS)
  • Stripping probably won't work, unless you install versions compatible with the target and configure their paths in .cargo/config by adding [target.<target triple>] strip = { path = "…" } objcopy = { path = "…" }. Alternatively, use --no-strip.

Yes, these requirements are onerous. You can also try cross or cargo zigbuild, since Zig is way better at cross-compiling, and then run cargo deb --target=… --no-build.

cargo deb --target=i686-unknown-linux-gnu

Cross-compiled archives are saved in target/<target triple>/debian/*.deb. The actual archive path is printed on success.

Note that you can't use cross-compilation to build for an older version of Debian. If you need to support Debian releases older than the host, consider using a container or a VM, or make a completely static binary for MUSL instead.

Separate debug info

To get debug symbols, set [profile.release] debug = true in Cargo.toml. Building using the dev profile is intentionally unsupported.

cargo deb --separate-debug-symbols

Removes debug symbols from executables and places them as separate files in /usr/lib/debug. Requires GNU objcopy tool.

Custom build flags

If you would like to handle the build process yourself, you can use cargo deb --no-build so that the cargo-deb command will not attempt to rebuild your project.

cargo deb -- <cargo build flags>

Flags after -- are passed to cargo build, so you can use options such as -Z, --frozen, and --locked. Please use that only for features that cargo-deb doesn't support natively.

Workspaces

Cargo-deb understands workspaces and can build all crates in the workspace if necessary. However, you must choose one crate to be the source of the package metadata. You can select which crate to build with -p crate_name or --manifest-path=<path/to/Cargo.toml>.

Custom version strings

cargo deb --deb-version my-custom-version

Overrides the version string generated from the Cargo manifest. It also suppresses the revision option.

Undefined reference to lzma_stream_encoder_mt error

This happens when the system-provided LZMA library is too old. Try with a bundled version:

cargo install cargo-deb --features=static-lzma

or use the xz command-line tool by setting the --compress-system flag.

cargo-deb's People

Contributors

acfoltzer avatar alextmjugador avatar drbrain avatar eggerk avatar eldesh avatar enizor avatar fredszaq avatar hongxuchen avatar imp avatar jdemler avatar jonlamb-gh avatar juliusl avatar kianmeng avatar kornelski avatar losynix avatar messense avatar mmstick avatar naokiri avatar nickbabcock avatar noyez avatar programmerjake avatar richardwhiuk avatar rschifflin avatar scootermon avatar slonopotamus avatar stappersg avatar taotao54321 avatar umanwizard avatar wgh- avatar ximon18 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

cargo-deb's Issues

Why is warning: This command is for Linux only, and will not make sense when run on other systems

Why is this cargo plugin only supposed to work on Linux? I am not familiar with how the Debian packaging system works, but cant it be made cross-platform? Ofc I mean being able to generate a Debian package on any platform to be clear.

Is there even a way to make that happen? If so I would be happy to help

warning: This command is for Linux only, and will not make sense when run on other systems

cargo deb all

Currently cargo-deb can build .deb package for a specific binary in a workspace (-p), it would be nice to have cargo-deb option to build all packages that has deb metadata

Cannot build cargo-deb

Running cargo install cargo-deb results in:

   Compiling cargo_toml v0.14.0
error[E0658]: use of unstable library feature 'scoped_threads'
   --> /home/james/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-deb-1.42.0/src/data.rs:128:5
    |
128 |     std::thread::scope(move |s| {
    |     ^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #93203 <https://github.com/rust-lang/rust/issues/93203> for more information

error[E0658]: use of unstable library feature 'scoped_threads'
   --> /home/james/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-deb-1.42.0/src/data.rs:130:29
    |
130 |         let hash_thread = s.spawn(move || {
    |                             ^^^^^
    |
    = note: see issue #93203 <https://github.com/rust-lang/rust/issues/93203> for more information

error[E0658]: use of unstable library feature 'scoped_threads'
   --> /home/james/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-deb-1.42.0/src/data.rs:162:24
    |
162 |         Ok(hash_thread.join().unwrap())
    |                        ^^^^
    |
    = note: see issue #93203 <https://github.com/rust-lang/rust/issues/93203> for more information

For more information about this error, try `rustc --explain E0658`.
error: could not compile `cargo-deb` due to 3 previous errors
error: failed to compile `cargo-deb v1.42.0`, intermediate artifacts can be found at `/tmp/cargo-installfbsSw4`

Apologies if I missed something in the README about this issue.

--profile with does not effect `--no-build`

when specifying --profile debug and --no-build cargo deb still looks in target/release

❯ cargo deb --verbose --no-build --no-strip --target x86_64-unknown-linux-gnu --output /home/heinz/tremor-runtime/packaging/out --deb-version 0.12.2 --profile debug
cargo-deb: Asset file path does not match any files: /home/heinz/tremor-runtime/target/release/tremor

Use a folder with subdirectories in assets

Hello,
is there a way to copy recursive a folder with subdirectories in the assets? The Readme says that glob is supported, but folder/* or folder/*.* copies only the files inside the folder, but not directories and folder/** did not work.

Workspace-level metadata

Some projects don't have a definite "main" crate in workspace, so it would be nice to be able to define all metadata at the workspace level, esp since workspace-level package metadata is a thing.

How can I implement a run-time conditional dependency?

This is probably a little off-topic for cargo-deb, because it's ultimately a Debian packaging question. But I thought I would ask here, because I don't really know where else to ask. Please feel free to close if you think it's too off-topic.

I've read through some of the Debian packaging documentation and searched around the internet, but I can't seem to find an example that fits my situation.

I have a Rust application that normally depends on packages A and B. However, if hardware virtualization is not supported on the machine (for instance, it's a virtual machine that doesn't support nested virtualization), then package B is unnecessary. I would like to somehow dynamically change my dependencies based on whether the machine supports hardware virtualization. Do you have any idea how I could implement that?

Right now, I'm using an install script that does something like this

if $(grep -E 'svm|vmx' /proc/cpuinfo > /dev/null 2>&1); then
    HAS_VIRTUALIZATION=true
else
    HAS_VIRTUALIZATION=false
fi

But I would really like to turn this into a proper package.

Consider supporting custom architectures

cargo-deb/src/manifest.rs

Lines 1179 to 1197 in 0a05980

("aarch64", _) => "arm64",
("mips64", "gnuabin32") => "mipsn32",
("mips64el", "gnuabin32") => "mipsn32el",
("mipsisa32r6", _) => "mipsr6",
("mipsisa32r6el", _) => "mipsr6el",
("mipsisa64r6", "gnuabi64") => "mips64r6",
("mipsisa64r6", "gnuabin32") => "mipsn32r6",
("mipsisa64r6el", "gnuabi64") => "mips64r6el",
("mipsisa64r6el", "gnuabin32") => "mipsn32r6el",
("powerpc", "gnuspe") => "powerpcspe",
("powerpc64", _) => "ppc64",
("powerpc64le", _) => "ppc64el",
("riscv64gc", _) => "riscv64",
("i586", _) | ("i686", _) | ("x86", _) => "i386",
("x86_64", "gnux32") => "x32",
("x86_64", _) => "amd64",
(arm, gnueabi) if arm.starts_with("arm") && gnueabi.ends_with("hf") => "armhf",
(arm, _) if arm.starts_with("arm") => "armel",
(other_arch, _) => other_arch,

In debian, there are mipsel and mips64el, but not mipsr6el and mips64r6el as above.

By the way, on some distributions, if you use dpkg to install deb packages, it will require the musl-amd64 architecture instead of amd64.

I don't think relying on automated detection architecture will necessarily make everyone happy.

It will be even better, if we can configure architectures in [package.metadata.deb].

`unattended-upgrade` with locally edited conffile causes "Not found in archive" tar error

See: NLnetLabs/routinator#783

In short:

# unattended-upgrade
...
tar: ./etc/routinator/routinator.conf: Not found in archive
tar: Exiting with failure status due to previous errors

The routinator.conf file is in the archive, but stored as etc/routinator/routinator.conf - note without the leading ./.

In the linked issue I came up with a work around but unpacking the data tarball from inside the DEB archive and re-tarballing the same files but so that they end up with ./ in the path seems a bit ridiculous.

Apparently the code in unattended-upgrade has been requiring this leading . in the path of items in the data tarball for 10 years at least looking at the blame history, so this isn't a new issue, so I'm surprised it hasn't come up here before.

Does anyone have a way to configure cargo-deb assets that results in . leading paths in the data tarball? I suspect not because of this from the tar crate for fn set_path():

"Will strip out any “.” path component, which signifies the current directory."

Thoughts anyone?

[package.metadata.deb].name should override [package.name]

The README says:

name: The name of the Debian package. If not present, the name of the crate is used.

Yet in the code I see:

name: self.package.name.clone(),

Unlike the lines around it which look like:

deb_name: deb.name.take().unwrap_or_else(|| self.package.name.clone()),

I.e. they take from the cargo deb metadata or fall back, which is what the README says should happen for package name but doesn't seem to. I found this because my systemd unit file named <package>.<unit>.service was not being found because it is looking using the top level package name and not the name override given in the cargo deb metadata.

However, that line of code appears to have been the same since the "initial code drop" 6 years ago, so maybe I'm missing something.

I'm inclined to think it should be:

name: deb.name.clone()

As deb.name is set to the cargo deb metadata name value, or if not present is set to the main package name and so is always set.

I can push a one line PR for this if you concur? I'm wondering however if even if this functionality is not as documented (assuming I'm not confused), are there users of cargo deb out there whose builds depend on the current functionality and so we cannot change it...

Running on x86_64 arch always produces *_amd64.deb

First of all, thanks for this great tool! I'm running into an issue - I'm trying to create a package on an x86_64 arch, but the output is always _amd64.deb suffixed. I run this in a docker container:

root@a3ce369d8454:~/okapi/native# uname -a
Linux a3ce369d8454 5.10.47-linuxkit #1 SMP Sat Jul 3 21:51:47 UTC 2021 x86_64 GNU/Linux
root@a3ce369d8454:~/okapi/native# arch
x86_64

Even running cargo deb --target=x86_64-unknown-linux-gnu has the same results. Not an expert on DEB packaging, so I may be missing something here. Any help would be appreciated.

rustc: err in 1.64.0 workspace common settings correspondence

Due to the impact of corresponding to the workspace common settings ([workspace.package], [workspace.dependencies]) introduced in 1.64
I'm getting the following error. Please teach me how to deal with it.

cargo-deb: Unable to parse /home/thinkingreed/rust/ewin/Cargo.toml
because: value from workspace hasn't been set

Although it is divided by workspace, the final deb file is one,
There was no problem before the workspace common setting of 1.64, so I think that the setting is just insufficient
How to handle is unknown.

environment.
OS: windows 11 pro
rustc: 1.64.0 (a55dd71d5 2022-09-19)

The whole of Cargo.toml.


[workspace]
members = [
"crates/base/ewin-cfg",
"crates/base/ewin-const",
"crates/base/ewin-utils",
"crates/base/ewin-key",
"crates/base/ewin-view",
"crates/base/ewin-job",
"crates/ewin-term",
"crates/ewin-tabs",
"crates/ewin-state",
"crates/ewin-plugin",
"crates/parts/ewin-editor",
"crates/parts/ewin-prom",
"crates/parts/ewin-menu_bar",
"crates/parts/ewin-dialog",
"crates/parts/ewin-ctx_menu",
"crates/parts/ewin-file_bar",
"crates/parts/ewin-help",
"crates/parts/ewin-status_bar",
"crates/parts/ewin-msg_bar",
"crates/parts/ewin-side_bar",
"crates/parts/ewin-activity_bar",
"crates/parts/ewin-tooltip"
]

[workspace.package]
version="0.0.2"
authors = ["thinkingreed"]
description = "Simple editor for Window(GUI) users. No need to remember commands."
rust-version="1.56.0"
edition="2021"
readme="README.md"
repository = "https://github.com/thinkingreed/ewin"
license="MIT"
keywords = ["text", "editor", "terminal", "cli", "tui"]
categories = ["text-editors", "command-line-utilities", ]

[package]
name="ewin"
version. workspace = true
authors.workspace = true
description. workspace = true
rust-version.workspace = true
edition.workspace = true
readme.workspace = true
repository.workspace = true
license. workspace = true
keywords.workspace = true
categories. workspace = true

build="build.rs"

[[bin]]
name="ew"
path = "crates/ewin-main/main.rs"

[package.metadata.deb]
extended-description = """
Simple editor for Window(GUI) users.
No need to learn new commands.\

It provides basic features as a minimal text editor.
depends = "$auto"
"""
assets = [
["target/release/ew", "usr/bin/", "755"],
["README.md", "usr/share/doc/ewin/README", "644"],
]

[workspace.dependencies]
crossterm = {version="0.25.0", features = ["event-stream"]}
once_cell = "1.5.2"
parking_lot = "0.12.1"
anyhow="1.0.57"
downcast="0.11.0"
directories = "4.0.1"
dyn-clone = "1.0.5"
tokio = { version = "1.21.2", features = ["time", "process", "macros", "rt-multi-thread"] }
tokio-util = { version = "0.7.4", features = ["codec"] }
chrono="0.4.19"
indexmap="1.8.1"
grep="0.2.8"
grep-matcher = "0.1.5"
grep-regex = "0.1.9"
grep-searcher = "0.1.8"
ignore="0.4.18"
globset="0.4.8"
regex="1.6.0"
ropey="1.2.0"
serde = { version = "1.0.123", features = ["derive"] }
serde_json = "1.0"
syntax = "5.0.0"
unicode-width="0.1.10"
unicode-jp="0.4.0"
byteorder="1.4.3"
num-format = "0.4.0"
encoding_rs = "0.8.31"
faccess="0.2.4"
number_prefix = "0.4.0"
clap = { version = "3.2.16", features = ["derive", "env"]}
futures = "0.3"
futures-util = "0.3.12"
toml = "0.5.9"
clipboard = "0.5.0"
colors-transform = "0.2.11"
crossbeam-channel = "0.5.2"
json5="0.4.1"
notify="5.0.0"
subprocess="0.2.8"
whoami="1.2.0"
futures-timer = "3.0.2"

ewin-cfg = {version = "0.0.2", path = "crates/base/ewin-cfg" }
ewin-const = {version = "0.0.2", path = "crates/base/ewin-const" }
ewin-key = {version = "0.0.2", path = "crates/base/ewin-key" }
ewin-view = {version = "0.0.2", path = "crates/base/ewin-view" }
ewin-job = {version = "0.0.2", path = "crates/base/ewin-job" }
ewin-utils = {version = "0.0.2", path = "crates/base/ewin-utils" }
ewin-state = {version = "0.0.2", path = "crates/ewin-state" }
ewin-term = {version = "0.0.2", path = "crates/ewin-term" }
ewin-plugin = {version = "0.0.2", path = "crates/ewin-plugin" }
ewin-tabs = {version = "0.0.2", path = "crates/ewin-tabs" }
ewin-editor = {version = "0.0.2", path = "crates/parts/ewin-editor" }
ewin-prom = {version = "0.0.2", path = "crates/parts/ewin-prom" }
ewin-menu_bar = {version = "0.0.2", path = "crates/parts/ewin-menu_bar" }
ewin-dialog = {version = "0.0.2", path = "crates/parts/ewin-dialog" }
ewin-ctx_menu = {version = "0.0.2", path = "crates/parts/ewin-ctx_menu" }
ewin-file_bar = {version = "0.0.2", path = "crates/parts/ewin-file_bar" }
ewin-help = {version = "0.0.2", path = "crates/parts/ewin-help" }
ewin-status_bar = {version = "0.0.2", path = "crates/parts/ewin-status_bar" }
ewin-msg_bar = {version = "0.0.2", path = "crates/parts/ewin-msg_bar" }
ewin-side_bar = {version = "0.0.2", path = "crates/parts/ewin-side_bar" }
ewin-activity_bar = {version = "0.0.2", path = "crates/parts/ewin-activity_bar" }
ewin-tooltip = {version = "0.0.2", path = "crates/parts/ewin-tooltip" }

[dependencies]
crossterm.workspace = true
parking_lot.workspace = true
tokyo.workspace = true
futures.workspace = true
futures-util.workspace = true
futures-timer.workspace = true
clap.workspace = true

ewin-cfg.workspace = true
ewin-key.workspace = true
ewin-const.workspace = true
ewin-job.workspace = true
ewin-utils.workspace = true
ewin-view.workspace = true
ewin-term.workspace = true
ewin-tabs.workspace = true
ewin-prom.workspace = true
ewin-tooltip.workspace = true

[dev-dependencies]
cargo-husky = "1.5.0"

[target.'cfg(windows)'.build-dependencies]
windres = "0.2.2"


Improve error "cargo-deb: missing chmod (third array entry) for asset in Cargo.toml"

As assets is an array of arrays, it was not directly clear to me to which entry it was referring to.

I had an error in the fourth entry of assets and thought initially the error message was wrong and should have been "fourth array entry". Then I noticed it was because the third entry of the fourth asset was missing. Maybe it should mention the index of the asset too?

`cargo test` failed on Debian Buster

The cargo test works fine on Debian Bullseye, but not on Buster. The test reports:

...
test manifest::tests::add_systemd_assets_with_no_config_does_nothing ... ok
test manifest::tests::add_systemd_assets_with_config_adds_unit_assets ... ok
test dependencies::resolve_test ... FAILED

failures:

---- dependencies::resolve_test stdout ----
thread 'dependencies::resolve_test' panicked at 'assertion failed: !deps.iter().any(|d| d.starts_with(\"libgcc\"))', src/dependencies.rs:53:5


failures:
    dependencies::resolve_test

test result: FAILED. 108 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.02s

error: test failed, to rerun pass '--lib'

When running tests with --test-threads=1 there are failures

When packaging this project for NixOS the tests are run on a machine with only one hardware thread and so it has the same effect as running cargo test -- --test-threads=1 which means that all tests are run in series but this causes some tests to fail.

Support for cargo custom profiles

Hello and thank you for maintaining cargo-deb ;)

Recently, cargo custom profiles https://blog.rust-lang.org/2021/12/02/Rust-1.57.0.html#cargo-support-for-custom-profiles have been stabilized and it's now possible to build a crate with --profile <profile-name> instead of regular --release.

I did not seem to find a way to tell cargo-deb to package using a specific custom profile. Instead specifying cargo deb -- --profile release-production lead to the following error:

error: conflicting usage of --profile=release-production and --release
The `--release` flag is the same as `--profile=release`.
Remove one flag or the other to continue.
cargo-deb: build failed

Is there a workaround at the moment? Right now I am creating a symbolic link release -> release-production.

Thank you for your time :)

mapping package release and project release

Hi,

I’m using cargo-deb to automate the package generation and I would like that my project version remains consistent with the package one.

For example, if my project has version 1.2.3, I would generate a package as myproject_1.2-3_amd64.deb, i.e. I would like to use the last field of semver as the package release.

Is there an option to do that ? (at this moment, I should manually maintain the consistency between project version and cargo-deb configuration)

Regards, Ch.

Unable to compile on Mac for Debian

I'm running MacOS on Intel and getting the following error when I try to compile with targets: aarch64-unknown-linux-gnu, i686-unknown-linux-gnu and x86_64-unknown-linux-gnu.

$ sudo cargo deb --target=x86_64-unknown-linux-gnu
warning: license field is missing in Cargo.toml
   Compiling libc v0.2.137
   Compiling cfg-if v1.0.0
   Compiling parking_lot_core v0.9.4
   Compiling lock_api v0.4.9
   Compiling log v0.4.17
   Compiling smallvec v1.10.0
   Compiling scopeguard v1.1.0
   Compiling serde v1.0.145
   Compiling memchr v2.5.0
   Compiling indexmap v1.9.1
   Compiling hashbrown v0.12.3
   Compiling tokio v1.22.0
   Compiling ryu v1.0.11
   Compiling mio v0.8.5
   Compiling socket2 v0.4.7
   Compiling signal-hook-registry v1.4.0
   Compiling parking_lot v0.12.1
   Compiling num_cpus v1.14.0
   Compiling itoa v1.0.3
   Compiling pin-project-lite v0.2.9
   Compiling unsafe-libyaml v0.2.4
   Compiling bytes v1.2.1
   Compiling serde_yaml v0.9.14
   Compiling demoprj v0.1.0 (/Users/b/o/d/rust/demoprj)
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "/tmp/rustc5zB91z/symbols.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.0.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.1.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.10.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.11.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.12.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.13.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.14.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.15.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.2.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.3.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.4.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.5.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.6.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.7.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.8.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.server.eaf65156-cgu.9.rcgu.o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a.k84j6jkazra99rc.rcgu.o" "-Wl,--as-needed" "-L" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps" "-L" "/Users/b/o/d/rust/demoprj/target/release/deps" "-L" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libserde_yaml-40a090efcb6e3ca1.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libryu-525bd9b4a541cd1e.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libitoa-a7f49c8af29a3048.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libindexmap-01cff7c36445293e.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libhashbrown-816ca2e34f0825a6.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libunsafe_libyaml-fde97438592a42ff.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libserde-0f92570efc48b240.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libtokio-78e7d69c8b30a7dc.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libsignal_hook_registry-bda84cc3e2cf0248.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libnum_cpus-c27edd3d8290acc6.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libsocket2-7e6e2e63fdbf6338.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libmemchr-da3f0164a4504a7e.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libbytes-07d33d5e9a6840e8.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libmio-8c86ee07666a60ca.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/liblog-2dcd1b97cacb7972.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libpin_project_lite-d035bd2af876e5fe.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libparking_lot-590e841de40d59e8.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libparking_lot_core-8ac6b80dbfa8f66f.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/liblibc-3e87f785f32dccdb.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libcfg_if-c7e466740d7e05f2.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libsmallvec-0326b983044ebf85.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/liblock_api-e2917566a951e90f.rlib" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/libscopeguard-85179ca1007a17a4.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-05737cf45bd30456.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-9f873b61fdec9b03.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-7f13930fcac1846f.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-098633b847612f3b.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-f14b73d282b0245e.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-2c5b4433ebc1d822.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-59591a7b405fe395.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-384947c6d5f697ff.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-b08a86c6880b47a8.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-58adeee671f9ba8e.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-f156b880fc73e7f0.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-4458c5022988e1ab.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-02e61e5ec4aa9e8b.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-a0d9b33b5161957b.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-04cec55a79224c36.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-3fb6d8496dc7d6a6.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-7d46c016841a97d4.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-a1f7b8b60464cc57.rlib" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-272ca28f0b8538d5.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/Users/boris/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/Users/b/o/d/rust/demoprj/target/x86_64-unknown-linux-gnu/release/deps/server-f69841404ba8121a" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-Wl,-O1" "-nodefaultlibs"
  = note: clang: warning: argument unused during compilation: '-pie' [-Wunused-command-line-argument]
          ld: unknown option: --as-needed
          clang: error: linker command failed with exit code 1 (use -v to see invocation)
          

error: could not compile `demoprj` due to previous error
cargo-deb: build failed

strip failed when cross compiling

Hi,

I trying to create a .deb with my app for aarch64 from x86_64 hosts.

I install g++-aarch64-linux-gnu libc6-dev-arm64-cross, run cargo build --release --target aarch64-unknown-linux-gnu all is fine

When running cargo deb -p myapp --target aarch64-unknown-linux-gnu, I get

strip: Unable to recognise the format of the input file `/home/runner/work/myapp/myapp/target/aarch64-unknown-linux-gnu/release/myapp'
cargo-deb: unable to strip binary '/home/runner/work/myapp/myapp/target/aarch64-unknown-linux-gnu/release/myapp': strip: exit status: 1.
hint: Target-specific strip commands are configured in [target.aarch64-unknown-linux-gnu] strip = { path = "strip" } in .cargo/config

I do something wrong ?

Error with cargo-deb and dpkg-shlibdeps

Hi,

I have the following issue. i have two different rust projects, which I can build with cargo build --target=arm-unknown-linux-gnueabi normally, works fine (on Ubuntu 20.04).

Now, when running cargo deb --target=arm-unknown-linux-gnueabi it gives me the following error:

Finished release [optimized] target(s) in 0.10s
warning: dpkg-shlibdeps (/root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway): dpkg-shlibdeps: error: cannot find library libstdc++.so.6 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: error: cannot find library libgcc_s.so.1 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: error: cannot find library libpthread.so.0 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: error: cannot find library libm.so.6 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: error: cannot find library libdl.so.2 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: error: cannot find library libc.so.6 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: error: cannot find library ld-linux.so.3 needed by /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway (ELF format: 'elf32-littlearm-sfabi' abi: '0101002800000200'; RPATH: '')
dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
dpkg-shlibdeps: error: cannot continue due to the errors listed above
Note: libraries are not searched in other binary packages that do not have any shlibs or symbols file.
To help dpkg-shlibdeps find private libraries, you might need to use -l.
 (no auto deps for /root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/release/ms-01-azure-gateway)
/root/greniot4all/firmware/raspberry-pi-zero-w/ms-01-azure-gateway/target/arm-unknown-linux-gnueabi/debian/ms-01-azure-gateway_1.0.5_armel.deb

I have all these files on the system. I set these projects up a couple of months ago, and they worked fine. Now i am trying to reorginazing them, but cargo deb gives me troubles. Any help is welcome!

Question: How to handle dependency for static binary

I have a Rust project where I build a static binary which I want to include into the deb package.

depends = "$auto"

yields

warning: Failed to find dependency specification. (no auto deps for....

Question: How would I code the depends statement correctly?

Add support for multiple systemd file

After looking at the code and the source, it seems like it's not possible to provide multiple service file. As a package can provide multiple binaries, it can be usefull to have support for multiple service too.

Maybe by using somethings like that in Cargo.toml:

[package.metadata.deb]
maintainer-scripts = "debian/"

[package.metadata.deb.systemd-units]
enable = false
unit-names = ["binaryname1", "binaryname2"]

Debian package name validation

Currently there is no validation (or automatic translation) of the Debian package name when building the .deb package. This can result in a situation where the produced Debian packages are not actually installable via apt as packages which do not conform to the naming convention are ignored.

Below is an example which will produce a .deb file, however when it is uploaded to a Debian repository (such as jfrog.io) it will not be installable as apt just says that the package could not be found.

[package]
name = "tedge_agent"

The problem is also not just limited to Debian repositories/apt, but also additional tooling such as equivs-build which is used to create meta Debian packages. The command fails when you try to reference any non-name-conform package in the dependencies fields (e.g. Pre-Depends, Depends, Recommends etc.).

Currently the only work around is to set the package name in the configuration under [packages.metadata.deb].name. This is unexpected for people who are not familiar with Debian packaging.

[package]
name = "tedge_agent"

[package.metadata.deb]
# Change to use `-` instead of `_`
name = "tedge-agent"

Background

The Debian standard states that following under the package naming convention:

Package names (both source and binary, see Package) must consist only of lower case letters (a-z), digits (0-9), plus (+) and minus (-) signs, and periods (.). They must be at least two characters long and must start with an alphanumeric character.

Possible solutions

  • Throw an error (with warning) if package names do not conform to regex pattern ^[a-z0-9][a-z0-9\-\.\+]+$ (not 100% sure about the escape chars in rust). This would at least give the user a hint that there is something that they need to change.
  • Automatically transform the package name, e.g. replace _ with - (though this might be unexpected for some users, and use lower case characters. Then still throw an error if it still does not conform. This would be more convenient for users, and encourages bad habits for users.

Changelog filename for native package

Thanks for your great job. Cargo-deb is very usefull.

However we still have an issue regarding native packages and their changelog name.

If we refer to debian policy (https://www.debian.org/doc/debian-policy/ch-docs.html#s-changelogs)
"Packages that are not Debian-native [...] with the name changelog.Debian.gz"

However it seems that "native package" (aka package related to Debian distro only) must have a filename like "/package/changelog.gz".

https://www.debian.org/doc/manuals/developers-reference/pkgs.en.html explains:

"This file will be installed in /usr/share/doc/package/changelog.Debian.gz, or /usr/share/doc/package/changelog.gz for native packages."

Can you please add a flag and/or an option to choice bw "changelog.Debian.gz" and "changelog.gz" ?

Many thanks.

set user permission

Hello,
thank you for your project, it is very useful!

I only wanted to ask, if it is possible to set user permission?

I have some assets which goes to /usr/share/ffplayout. My program runs under user www-data and first run it will initialize a sqlite db file in that folder. But because the deb installation creates the folder with root permission, my program can not create the db file.

Is there a option for that?

Edit: Sorry I was to fast with asking. I found a solution with a postinst script.

CARGO_BUILD_TARGET isn't respected

I have a container set up for cross compilation. CARGO_BUILD_TARGET is set and rust projects compile with just cargo build.

I'd expect cargo deb to also work but alas, I seem to require an explicit --target=$CARGO_BUILD_TARGET on invocation.

Dependencies not found when corss compiling

When cross compiling finding dependencies will fail.

For example on Ubuntu 20.04 amd64 host and compiling for arm64:

$ apt install gcc-aarch64-linux-gnu libc6-arm64-cross
$ rustup target add aarch64-unknown-linux-gnu
$ cargo deb --target aarch64-unknown-linux-gnu
[...]
warning: dpkg-shlibdeps (./project/target/aarch64-unknown-linux-gnu/release/server): dpkg-shlibdeps: error: cannot find library libgcc_s.so.1 needed by ./project/target/aarch64-unknown-linux-gnu/release/server (ELF format: 'elf64-little' abi: '020100b700000000'; RPATH: '')
dpkg-shlibdeps: error: cannot find library libpthread.so.0 needed by ./project/target/aarch64-unknown-linux-gnu/release/server (ELF format: 'elf64-little' abi: '020100b700000000'; RPATH: '')
dpkg-shlibdeps: warning: binaries to analyze should already be installed in their package's directory
dpkg-shlibdeps: error: cannot continue due to the errors listed above
Note: libraries are not searched in other binary packages that do not have any shlibs or symbols file.
To help dpkg-shlibdeps find private libraries, you might need to use -l.

The Debian archive is successfully created, but the Depends field in the control file is empty.

The libraries are available in /usr/aarch64-linux-gnu/lib/.
When manually setting export LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib/ the errors disappear and the Depends field is set.
However according to the man page and the error message you should use -l argument for dpkg-shlibdeps.

Edit: I just noticed event trough it works this way, it detects the wrong dependency:

Depends: libc6:arm64 (>= 2.28), libgcc1-arm64-cross  (>= 1:4.2)

libgcc1-arm64-cross should not be there.

Upon further investigation the following command will archive the desired result, however its not very generic:

$ dpkg-shlibdeps -O -l/usr/aarch64-linux-gnu/lib/ -xlibgcc1-arm64-cross target/aarch64-unknown-linux-gnu/release/server
shlibs:Depends=libc6:arm64 (>= 2.28)

cdynlib asset not recognized after upgrading 1.39.3→1.40.3

I stumbled over what looks to me like a regression somewhere between cargo-deb 1.39.3 and 1.40.3

You can find a reproducer repository here.

Cargo.toml contains

…
[lib]
crate-type = ["cdylib", "rlib"]
…
[package.metadata.deb]
assets = [
    ["target/header.h", …
    ["target/release/librepro.so", …
]

i.e. cargo build --release creates (among other files) target/release/librepro.so (triggered through the crate-type) and target/header.h (from build.rs).

Up until cargo-deb 1.39.3 cargo-deb creates a .deb file with content

drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/share/
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/share/doc/
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/share/doc/repro/
-rw-r--r-- 0/0             165 2022-11-28 17:23 usr/share/doc/repro/copyright
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/include/
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/include/sev/
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/include/sev/repro/
-rw-r--r-- 0/0             253 2022-11-28 17:23 usr/include/sev/repro/header.h
drwxr-xr-x 0/0               0 2022-11-28 17:23 usr/lib/
-rwxr-xr-x 0/0           14016 2022-11-28 17:23 usr/lib/librepro.so

as intended. After upgrading cargo-deb, cargo-deb fails with

error: no bin target named `librepro.so`.

trying some git bisect it seems to me like the regression got introduced in 93d50c3 .

Not sure where in that commit the issue is introduced but I hope the explanation above makes sense.

Any idea how to get this working again?

Thanks in advance,
Paul

Create empty dirs in package

Hi.

I am trying to create an empty folder in my package (my case - prepare folders for logs, something like /var/log/), but I didn't found any way to do that rather than in postinst, but this approach have a problem - package doesn't own folder and won't remove them on uninstall. And there is no way to modify rules to run https://man7.org/linux/man-pages/man1/dh_installdirs.1.html.

In RPM:

%install
mkdir -p %{buildroot}/var/log/service

%files
%dir %attr(755, user, group) /var/log/service-name/

I think it should be cool to have some way to hack rules, however right now I can't imagine how it might look.

Advice for cross-distro-release support would be nice

With Ubuntu 22.04 LTS out, I'm now using this on my development machine, while still wishing to support 20.04 LTS. It seems like others would be in the same boat. While --target x86_64-unknown-linux-gnu seems like part of the solution, any package dependencies aside from libc would also need to be accounted for. It seems like a job for cross-rs, except that cross doesn't seem to support cargo-deb.

Anyhow, some documentation on supporting alternate distro-releases (even "not currently supported") would be helpful.

[HELP] src/config.rs.ini vs src/config.rs

Hi, I need some help, I'm trying to create .deb files for the apps on circle.gnome.com. A particularity of those apps is that they use src/config.rs.ini instead of src/config.rs and the cargo-deb program fails to create .deb files despite all compiling going flawlessly.

For instant I'll post the error on Amberol app, but the same happens for Fragments and Podcast apps.

Compiling amberol v0.1.0 (/home/hamza/Downloads/amberol-0.9.1) error[E0432]: unresolved imports crate::config::APPLICATION_ID, crate::config::VERSION--> src/application.rs:14:14 | 14 | config::{APPLICATION_ID, VERSION}, | ^^^^^^^^^^^^^^ ^^^^^^^ noVERSIONinconfig| | | noAPPLICATION_IDinconfig`

error[E0432]: unresolved import crate::config::APPLICATION_ID
--> src/audio/mpris_controller.rs:14:5
|
14 | config::APPLICATION_ID,
| ^^^^^^^^^^^^^^^^^^^^^^ no APPLICATION_ID in config

error[E0432]: unresolved import crate::config::APPLICATION_ID
--> src/utils.rs:11:5
|
11 | use crate::config::APPLICATION_ID;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no APPLICATION_ID in config

error[E0432]: unresolved import crate::config::APPLICATION_ID
--> src/window.rs:20:5
|
20 | config::APPLICATION_ID,
| ^^^^^^^^^^^^^^^^^^^^^^ no APPLICATION_ID in config

error[E0432]: unresolved imports config::APPLICATION_ID, config::GETTEXT_PACKAGE, config::LOCALEDIR, config::PKGDATADIR, config::PROFILE
--> src/main.rs:23:14
|
23 | use config::{APPLICATION_ID, GETTEXT_PACKAGE, LOCALEDIR, PKGDATADIR, PROFILE};
| ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^ no PROFILE in config
| | | | |
| | | | no PKGDATADIR in config
| | | no LOCALEDIR in config
| | no GETTEXT_PACKAGE in config
| no APPLICATION_ID in config

For more information about this error, try rustc --explain E0432.
error: could not compile amberol due to 5 previous errors
cargo-deb: build failed
hamza@surface:~/Downloads/amberol-0.9.1$ `

the content of src/config.rs.ini is:
`// SPDX-FileCopyrightText: 2022 Emmanuele Bassi
// SPDX-License-Identifier: GPL-3.0-or-later

pub static VERSION: &str = @Version@;
pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@;
pub static LOCALEDIR: &str = @LOCALEDIR@;
pub static PKGDATADIR: &str = @PKGDATADIR@;
pub static APPLICATION_ID: &str = @APPLICATION_ID@;
pub static PROFILE: &str = @Profile@;

`

So I guess is pointing to somewhere, I just don't know.

I tried to create a empty src/config.rs there ended up with that error.

I tried to create a src/config.rs file with some contents trying to match those on src/config.rs.ini in fact it created the .deb file on the target, installed but the apps refused to start.

So first I think I should figure out is the best way to pass the first error i.e the app not being compiled with just it's original config.rs.ini.

So please help me on this.

I'm doing all this on Debian Testing.

Rust edition 2021 not recognized

cargo-deb: unable to parse Cargo.toml
  because: unknown variant `2021`, expected `2015` or `2018` for key `package.edition` at line 49 column 1

Running "update-rc.d defaults", "update-rc.d enable" and "service xxx start" on install?

Thanks for writing cargo-deb, my daemon packages already work with systemd-based OSs, such as Ubuntu and Debian.

I currently have /etc/init.d/xxx as a resource, and it is correctly installed with dpkg -i.

For sysv-init OSs, such as Devuan, I have to manually run update-rc.d defaults, update-rc.d enable and service xxx start after installing the package.

Does cargo-deb have any sysv-init support?

How can I automate these commands?

Test failure for `dependencies::resolve_test`

Hello!

I'm trying to package cargo-deb for Arch Linux community and I'm getting the following error during cargo test:

test dependencies::resolve_test ... FAILED

failures:

---- dependencies::resolve_test stdout ----
thread 'dependencies::resolve_test' panicked at 'called `Result::unwrap()` on an `Err` value: CommandError("dpkg-shlibdeps", "/build/cargo-deb/src/cargo-deb-1.42.2/target/debug/deps/cargo_deb-bca004bd35b19c19", [100, 112, 107, 103, 45, 115, 104, 108, 105, 98, 100, 101, 112, 115, 58, 32, 101, 114, 114, 111, 114, 58, 32, 110, 111, 32, 100, 101, 112, 101, 110, 100, 101, 110, 99, 121, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 102, 111, 117, 110, 100, 32, 102, 111, 114, 32, 47, 108, 105, 98, 47, 108, 105, 98, 108, 122, 109, 97, 46, 115, 111, 46, 53, 32, 40, 117, 115, 101, 100, 32, 98, 121, 32, 47, 98, 117, 105, 108, 100, 47, 99, 97, 114, 103, 111, 45, 100, 101, 98, 47, 115, 114, 99, 47, 99, 97, 114, 103, 111, 45, 100, 101, 98, 45, 49, 46, 52, 50, 46, 50, 47, 116, 97, 114, 103, 101, 116, 47, 100, 101, 98, 117, 103, 47, 100, 101, 112, 115, 47, 99, 97, 114, 103, 111, 95, 100, 101, 98, 45, 98, 99, 97, 48, 48, 52, 98, 100, 51, 53, 98, 49, 57, 99, 49, 57, 41, 10, 72, 105, 110, 116, 58, 32, 99, 104, 101, 99, 107, 32, 105, 102, 32, 116, 104, 101, 32, 108, 105, 98, 114, 97, 114, 121, 32, 97, 99, 116, 117, 97, 108, 108, 121, 32, 99, 111, 109, 101, 115, 32, 102, 114, 111, 109, 32, 97, 32, 112, 97, 99, 107, 97, 103, 101, 46, 10])', src/dependencies.rs:61:37


failures:
    dependencies::resolve_test

The error message corresponds to:

dpkg-shlibdeps: error: no dependency information found for /lib/liblzma.so.5 (used by /build/cargo-deb/src/cargo-deb-1.42.2/target/debug/deps/cargo_deb-bca004bd35b19c19)
Hint: check if the library actually comes from a package.

This is also the same as running:

$ dpkg-shlibdeps -O /build/cargo-deb/src/cargo-deb-1.42.2/target/debug/deps/cargo_deb-bca004bd35b19c19

dpkg-shlibdeps: error: no dependency information found for /lib/liblzma.so.5 (used by /build/cargo-deb/src/cargo-deb-1.42.2/target/debug/deps/cargo_deb-bca004bd35b19c19)
Hint: check if the library actually comes from a package.

I'm not experienced in Debian packaging/tooling so any guidance would help!

Systemd user units

At the moment it is not possible to install a systemd user unit. I am missing an option in package.metadata.deb.systemd-units that allows to define that the service should be installed for users.

I am not an expert with debian packaging but I am willing to implement it if I get some help.

From my point of view the following points have to be considered when an user option is enabled:

  • install service to /usr/lib/systemd/user/
  • call deb-systemd-helper, systemctl and deb-systemd-invoke with --user
  • systemctl and deb-systemd-invoke have to be called with the correct user and XDG_RUNTIME_DIR has to be set. (This is a bit cumbersome and only allows to start the service for the currently active user. Are there any other options?)

Any opinions on this?

I got it working with the following scripts:

postinst:

# Automatically added by cargo-deb
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
	# This will only remove masks created by d-s-h on package removal.
	deb-systemd-helper --user unmask service >/dev/null || true

	# was-enabled defaults to true, so new installations run enable.
	if deb-systemd-helper --user --quiet was-enabled time-tracker.service; then
		# Enables the unit on first installation, creates new
		# symlinks on upgrades if the unit file has changed.
		deb-systemd-helper --user enable service >/dev/null || true
	else
		# Update the statefile to add new symlinks (if any), which need to be
		# cleaned up on purge. Also remove old symlinks.
		deb-systemd-helper --user update-state service >/dev/null || true
	fi
fi

# End automatically added section
# Automatically added by cargo-deb
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
	if [ -d /run/systemd/system ]; then
		USER="$(who | head -1 | awk '{print $1;}')"
		runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) systemctl --user daemon-reload >/dev/null || true"
		if [ -n "$2" ]; then
			_dh_action=restart
		else
			_dh_action=start
		fi
		runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-invoke --user $_dh_action service >/dev/null || true"
	fi
fi
# End automatically added section

prerm:

# Automatically added by cargo-deb
if [ -d /run/systemd/system ] && [ "$1" = remove ]; then
	USER="$(who | head -1 | awk '{print $1;}')"
	runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) deb-systemd-invoke --user stop service >/dev/null || true"
fi
# End automatically added section

postrm:

# Automatically added by cargo-deb
if [ -d /run/systemd/system ]; then
	USER="$(who | head -1 | awk '{print $1;}')"
	runuser -l $USER -c "XDG_RUNTIME_DIR=/run/user/$(id -u $USER) systemctl --user daemon-reload >/dev/null || true"
fi
# End automatically added section
# Automatically added by cargo-deb
if [ "$1" = "remove" ]; then
	if [ -x "/usr/bin/deb-systemd-helper" ]; then
		deb-systemd-helper --user mask service >/dev/null || true
	fi
fi

if [ "$1" = "purge" ]; then
	if [ -x "/usr/bin/deb-systemd-helper" ]; then
		deb-systemd-helper --user purge service >/dev/null || true
		deb-systemd-helper --user unmask service >/dev/null || true
	fi
fi
# End automatically added section

Error "malformed-deb-archive newer compressed control.tar.xz" from Lintian on Ubuntu Xenial with cargo-deb > 1.28.0.

See: https://github.com/NLnetLabs/krill/runs/4803140070?check_suite_focus=true#step:13:28

This used to work with cargo-deb 1.28.0.

I tried using --fast to disable XZ compression but that didn't help.

What did help was compiling with --no-default-features to disable the lzma feature.

As there are no release notes that I'm aware of for cargo-deb I tried looking through the diff of tag 1.34.2 to tag 1.28.0 and I see a couple of references to LZMA and XZ but I haven't however tried divide and conquer to find out exactly which release since 1.28.0 introduced the problem.

However with the default features disabled cargo-deb now takes almost twice as long, roughly 15 minutes instead of 8 minutes for my build on GH Actions.

`cargo test` failed on specific target

Since the cmd_path was hard coded as "target/debug/cargo-deb" in tests/command.rs:161:5, any cargo test commands with specific target will fail, like cargo test --target=x86_64-unknown-linux-gnu or even cargo test --release.


  • The cmd_path for cargo test --release should be "target/release/cargo-deb".
  • The cmd_path for cargo test --target=x86_64-unknown-linux-gnu should be "target/x86_64_unknown-linux-gnu/debug/cargo-deb".

Add directory permissions to assets array?

Hi!

I have the need to create a directory with read and write permissions as part of package set up. The directory is already created by the cargo-deb generated package as it is where the systemd unit binary (app) lives:

assets = [
    ["target/release/app", "etc/abcdef/", "755"],
    ["target/release/app-configure", "usr/bin/", "755"]
]

A separate configuration binary (app-configure) allows users to configure app and the configuration files reside in /etc/abcdef. Because the default permissions of /etc/abcdef are set to read only, I need to modify the directory permissions so that app-configure can write files to /etc/abcdef.

I've read that there are two ways this can be achieved:

  1. override_dh_fixperms/execute_after_dh_fixperms followed by chmod <perms> <some directory>
  2. Adding a step to the postinst script with chmod <perms> <some directory>

I've opted for (2), with this postinst script:

#DEBHELPER#
chmod 0777 /etc/abcdef

I have two questions:

  1. Is (2) the best approach with cargo-deb?
  2. Would a nicer interface be to allow directories to be specified in the assets array?

Output dynamic libraries in architecture library path

[2022-06-17T04:55:18Z DEBUG cargo_deb] stripping /home/user/helloworld/target/x86_64-unknown-linux-gnu/release/libfoo.so with strip
info: Stripped '/home/user/helloworld/target/x86_64-unknown-linux-gnu/release/libfoo.so'
info: /home/user/helloworld/target/x86_64-unknown-linux-gnu/release/libfoo.so -> usr/lib/libfoo.so (7MB)
info: - -> usr/share/doc/helloworld/copyright (246B)

This makes the library end up in usr/lib/libfoo.so, where it's expected in e.g. usr/lib/x86_64-linux-gnu/libfoo.so.

Cf

// FIXME: std has constants for the host arch, but not for cross-compilation

Perhaps something like guess_host_triple can be adopted (I guess such an implementation should be contained here rather than relying on a third-party crate, though?).

Support for workspace inheritance

Hi,

the latest Rust release (1.64) includes support for sharing workspace package and dependencies information across workspace members (see the announcement). Using this feature causes cargo deb to fail with the error

cargo-deb: Unable to parse Cargo.toml
  because: invalid type: map, expected a string for key `package.version` at line 5 column 24
  because: invalid type: map, expected a string for key `package.version` at line 5 column 24

(using [workspace.package] version = "<VERSION>").

Looking at your Cargo.toml, I assume this is using cargo_toml to parse the manifest? If that is the case, this might be related to https://gitlab.com/crates.rs/cargo_toml/-/issues/19.

Compiling with `--no-default-features` broken since 1.37.0

Hi,

Prior to 1.37.0 it was possible to compile with --no-default-features to work around #12. However since 1.37.0 compilation with --no-default-features fails with error:

error[E0061]: this function takes 5 arguments but 4 arguments were supplied
  --> /home/ximon/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-deb-1.37.0/src/compress.rs:66:5
   |
66 |     zopfli::compress(&Options::default(), &Format::Gzip, data, &mut compressed)?;
   |     ^^^^^^^^^^^^^^^^ -------------------  -------------  ----  --------------- supplied 4 arguments
   |     |
   |     expected 5 arguments
   |
note: function defined here
  --> /home/ximon/.cargo/registry/src/github.com-1ecc6299db9ec823/zopfli-0.6.0/src/lib.rs:85:8
   |
85 | pub fn compress<R, W>(
   |        ^^^^^^^^

For more information about this error, try `rustc --explain E0061`.
error: could not compile `cargo-deb` due to previous error
error: failed to compile `cargo-deb v1.37.0`, intermediate artifacts can be found at `/tmp/cargo-installFsF2oo`

Cannot include symbolic link as asset

As a library developer, I want to build an lib*-dev.deb package.

Steps to reproduce

$ cargo deb --version
1.38.4
  1. Create symlinks
    # mkdir -p tmp_asset
    # cd tmp_asset
    # ln -sf libfoo.so.0 libfoo.so.0.7.0
    # ln -sf libfoo.so libfoo.so.0.7.0
  1. Add these into assets configuration
[package.metadata.deb]
assets = [["tmp_asset/lib*", "/usr/local/lib/", "777"]]
preserve-symlinks = true
  1. Run cargo deb

Expected

symbolic link is included in the deb package

Actual

cargo-deb: unable to read asset to add to archive: OMIT/libfoo.so

Is there any workaround to make symlinks in deb package?

Error: on profile.release using "symbols"

With Rust 1.59 it is possible to use on stable

[profile.release]
strip = "symbols"

This is equivalent to

[profile.release]
strip = true

However, if somebody uses an option that is no a boolean, the following error will appear

cargo-deb: unable to parse Cargo.toml
  because: invalid type: string "symbols", expected a boolean for key `profile.release.strip` at line 34 column 9
cargo deb --version
1.36.0

Warn on nonexistent file listed as an asset

If a user lists a nonexistent file as an asset, it would be very helpful to get a warning about it.

e.g.

[package.metadata.deb.variants.debug]
assets =  [
    ["dir/fake_file.txt", "/var/log", "755"],
]

might yield
Warning: 'dir/fake_file.txt' does not exist and will not be added to deb

Missing unit-names would also be nice, while trying to use a systemd service template it wasn't obvious to exlude the @

Missing maintainer scripts does not output logs

I add a bit of trouble lately creating debian packages using cargo deb: while I specified in my cargo manifest the maintainer-scripts field, none of my scripts where being picked-up by the program. In fact: the path I used was erroneous. Unfortunately, cargo deb did not provide any useful log/message about the matter.

Could it be interesting to display a warning when no files are found for maintainer scripts if the maintainer-scripts field is present in the cargo manifest ?

If you think it could be useful, I would be happy to make a pull request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.