]>
git.proxmox.com Git - dh-cargo.git/blob - cargo.pm
1 # debhelper buildsystem for Rust crates using Cargo
3 # Josh Triplett <josh@joshtriplett.org>
5 package Debian
::Debhelper
::Buildsystem
::cargo
;
10 use Debian
::Debhelper
::Dh_Lib
;
11 use Dpkg
::Changelog
::Debian
;
12 use Dpkg
::Control
::Info
;
15 use base
'Debian::Debhelper::Buildsystem';
23 open(F
, "cargo metadata --manifest-path $src --no-deps --format-version 1 |");
25 my $json = JSON
::PP-
>new;
26 my $manifest = $json->decode(<F
>);
27 return %{@{%{$manifest}{'packages'}}[0]}{'version'} . "\n";
30 sub check_auto_buildable
{
32 if (-f
$this->get_sourcepath("Cargo.toml")) {
40 my $this = $class->SUPER::new
(@_);
41 $this->enforce_in_source_building();
45 sub pre_building_step
{
49 $this->{cargo_home
} = Cwd
::abs_path
($this->get_sourcepath("debian/cargo_home"));
50 $this->{cargo_registry
} = Cwd
::abs_path
($this->get_sourcepath("debian/cargo_registry"));
52 my $control = Dpkg
::Control
::Info-
>new();
54 my $source = $control->get_source();
55 my $crate = $source->{'X-Cargo-Crate'};
57 $crate = $source->{Source
};
59 $crate =~ s/-[0-9]+(\.[0-9]+)*$//;
61 $this->{crate
} = $crate;
62 my $changelog = Dpkg
::Changelog
::Debian-
>new(range
=> { count
=> 1 });
63 $changelog->load($this->get_sourcepath("debian/changelog"));
64 $this->{version
} = Dpkg
::Version-
>new(@{$changelog}[0]->get_version())->version();
66 my @packages = $control->get_packages();
69 $this->{featurepkg
} = [];
70 foreach my $package (@packages) {
71 if ($package->{Package
} =~ /^librust-.*-dev$/ && $package->{Architecture
} eq 'all') {
72 if ($package->{Package
} =~ /\+/) {
73 push(@{$this->{featurepkg
}}, $package->{Package
});
76 if ($this->{libpkg
}) {
77 error
("Multiple Cargo lib packages found: " . $this->{libpkg
} . " and " . $package->{Package
});
79 $this->{libpkg
} = $package->{Package
};
80 } elsif ($package->{Architecture
} ne 'all') {
81 $this->{binpkg
} = $package->{Package
};
84 if (!$this->{libpkg
} && !$this->{binpkg
}) {
85 error
("Could not find any Cargo lib or bin packages to build.");
87 if (@{$this->{featurepkg
}} && !$this->{libpkg
}) {
88 error
("Found feature packages but no lib package.");
91 my $parallel = $this->get_parallel();
92 $this->{j
} = $parallel > 0 ?
["-j$parallel"] : [];
94 $this->SUPER::pre_building_step
($step);
99 opendir(my $dirhandle, $this->get_sourcedir());
100 my @sources = grep { $_ ne '.' && $_ ne '..' && $_ ne '.git' && $_ ne 'debian' } readdir($dirhandle);
101 closedir($dirhandle);
107 # Create a fake local registry $this->{cargo_registry} with only our dependencies
108 my $crate = $this->{crate
} . '-' . $this->{version
};
109 my $registry = $this->{cargo_registry
};
110 doit
("mkdir", "-p", $this->{cargo_home
}, $registry);
111 opendir(my $dirhandle, '/usr/share/cargo/registry');
112 my @crates = map { "/usr/share/cargo/registry/$_" } grep { $_ ne '.' && $_ ne '..' } readdir($dirhandle);
113 closedir($dirhandle);
115 doit
("ln", "-st", "$registry", @crates);
117 # Handle the case of building the package with the same version of the
119 if (-l
"$registry/$crate") {
120 unlink("$registry/$crate");
122 mkdir("$registry/$crate");
123 my @sources = $this->get_sources();
124 doit
("cp", "-at", "$registry/$crate", @sources);
125 doit
("cp", $this->get_sourcepath("debian/cargo-checksum.json"), "$registry/$crate/.cargo-checksum.json");
127 open(CONFIG
, ">" . $this->{cargo_home
} . "/config");
130 replace-with = "dh-cargo-registry"
132 [source.dh-cargo-registry]
133 directory = "$registry"
140 $ENV{'CARGO_HOME'} = $this->{cargo_home
};
141 # Check that the thing compiles. This might fail if e.g. the package
142 # requires non-rust system dependencies and the maintainer didn't provide
143 # this additional information to debcargo.
144 doit
("cargo", "build", "--verbose", "-Zavoid-dev-deps");
149 $ENV{'CARGO_HOME'} = $this->{cargo_home
};
150 my $crate = $this->{crate
} . '-' . $this->{version
};
151 if ($this->{libpkg
}) {
152 my $target = $this->get_sourcepath("debian/" . $this->{libpkg
} . "/usr/share/cargo/registry/$crate");
153 my @sources = $this->get_sources();
154 doit
("mkdir", "-p", $target);
155 doit
("cp", "-at", $target, @sources);
156 doit
("rm", "-rf", "$target/target");
157 doit
("cp", $this->get_sourcepath("debian/cargo-checksum.json"), "$target/.cargo-checksum.json");
159 foreach my $pkg (@{$this->{featurepkg
}}) {
160 my $target = $this->get_sourcepath("debian/$pkg/usr/share/doc");
161 doit
("mkdir", "-p", $target);
162 doit
("ln", "-s", $this->{libpkg
}, "$target/$pkg");
164 if ($this->{binpkg
}) {
165 my $target = $this->get_sourcepath("debian/" . $this->{binpkg
} . "/usr");
166 doit
("cargo", "install", $this->{crate
}, "--verbose", @{$this->{j
}},
167 "--vers", cargo_version
($this->get_sourcepath("Cargo.toml")),
169 doit
("rm", "$target/.crates.toml");
175 $ENV{'CARGO_HOME'} = $this->{cargo_home
};
176 doit
("cargo", "clean", "--verbose");
177 doit
("rm", "-rf", $this->{cargo_home
}, $this->{cargo_registry
});