biglybt: 3.5.0.0 -> 3.6.0.0
[NixPkgs.git] / pkgs / servers / x11 / xorg / generate-expr-from-tarballs.pl
blobd0f88c4dfdbc1427ac0a6efc4854bc28c9586645
1 #!/usr/bin/env nix-shell
2 #!nix-shell --pure --keep NIX_PATH -i perl -p cacert nix perl
4 # Usage: manually update tarballs.list then run: ./generate-expr-from-tarballs.pl tarballs.list
6 use strict;
7 use warnings;
9 use File::Basename;
10 use File::Spec::Functions;
11 use File::Temp;
14 my %pkgURLs;
15 my %pkgHashes;
16 my %pkgNames;
17 my %pkgVersions;
18 my %pkgRequires;
19 my %pkgNativeRequires;
21 my %pcProvides;
22 my %pcMap;
24 my %extraAttrs;
27 my @missingPCs = ("fontconfig", "libdrm", "libXaw", "zlib", "perl", "python3", "mkfontscale", "bdftopcf", "libxslt", "openssl", "gperf", "m4", "libinput", "libevdev", "mtdev", "xorgproto", "cairo", "gettext", "meson", "ninja", "wrapWithXFileSearchPathHook" );
28 $pcMap{$_} = $_ foreach @missingPCs;
29 $pcMap{"freetype2"} = "freetype";
30 $pcMap{"libpng12"} = "libpng";
31 $pcMap{"libpng"} = "libpng";
32 $pcMap{"dbus-1"} = "dbus";
33 $pcMap{"uuid"} = "libuuid";
34 $pcMap{"libudev"} = "udev";
35 $pcMap{"gl"} = "libGL";
36 $pcMap{"GL"} = "libGL";
37 $pcMap{"gbm"} = "mesa";
38 $pcMap{"hwdata"} = "hwdata";
39 $pcMap{"\$PIXMAN"} = "pixman";
40 $pcMap{"\$RENDERPROTO"} = "xorgproto";
41 $pcMap{"\$DRI3PROTO"} = "xorgproto";
42 $pcMap{"\$DRI2PROTO"} = "xorgproto";
43 $pcMap{"\${XKBMODULE}"} = "libxkbfile";
46 my $downloadCache = "./download-cache";
47 mkdir $downloadCache, 0755;
50 while (<>) {
51 chomp;
52 my $tarball = "$_";
53 print "\nDOING TARBALL $tarball\n";
55 my $pkg;
56 if ($tarball =~ s/:([a-zA-Z0-9_]+)$//) {
57 $pkg = $1;
58 } else {
59 $tarball =~ /\/((?:(?:[A-Za-z0-9]|(?:-[^0-9])|(?:-[0-9]*[a-z]))+))[^\/]*$/;
60 die unless defined $1;
61 $pkg = $1;
62 $pkg =~ s/(-|[a-f0-9]{40})//g; # Remove hyphen-minus and SHA-1
63 #next unless $pkg eq "xcbutil";
66 $tarball =~ /\/([^\/]*)\.(tar\.(bz2|gz|xz)|tgz)$/;
67 my $pkgName = $1;
69 print " $pkg $pkgName\n";
71 if (defined $pkgNames{$pkg}) {
72 print " SKIPPING\n";
73 next;
76 # Split by first occurrence of hyphen followed by only numbers, ends line, another hyphen follows, or SHA-1
77 my ($name, $version) = split(/-(?=[.0-9]+(?:$|-)|[a-f0-9]{40})/, $pkgName, 2);
79 $pkgURLs{$pkg} = $tarball;
80 $pkgNames{$pkg} = $name;
81 $pkgVersions{$pkg} = $version;
83 my $cachePath = catdir($downloadCache, basename($tarball));
84 my $hash;
85 my $path;
86 if (-e $cachePath) {
87 $path = readlink($cachePath);
88 $hash = `nix-hash --type sha256 --base32 --flat $cachePath`;
90 else {
91 ($hash, $path) = `PRINT_PATH=1 QUIET=1 nix-prefetch-url '$tarball'`;
92 `nix-store --realise --add-root $cachePath --indirect $path`;
94 chomp $hash;
95 chomp $path;
96 $pkgHashes{$pkg} = $hash;
98 print "\nunpacking $path\n";
99 my $tmpDir = File::Temp->newdir();
100 system "cd '$tmpDir' && tar xf '$path'";
101 die "cannot unpack `$path'" if $? != 0;
102 print "\n";
104 my $pkgDir = `echo $tmpDir/*`;
105 chomp $pkgDir;
107 my $provides = `find $pkgDir -name "*.pc.in"`;
108 my @provides2 = split '\n', $provides;
109 my @requires = ();
110 my @nativeRequires = ();
112 foreach my $pcFile (@provides2) {
113 my $pc = $pcFile;
114 $pc =~ s/.*\///;
115 $pc =~ s/.pc.in//;
116 push @{$pcProvides{$pkg}}, $pc;
117 print "PROVIDES $pc\n";
118 die "collision with $pcMap{$pc}" if defined $pcMap{$pc};
119 $pcMap{$pc} = $pkg;
121 open FOO, "<$pcFile" or die;
122 while (<FOO>) {
123 if (/Requires:(.*)/) {
124 my @reqs = split ' ', $1;
125 foreach my $req (@reqs) {
126 next unless $req =~ /^[a-z]+$/;
127 print "REQUIRE (from $pc): $req\n";
128 push @requires, $req;
132 close FOO;
136 my $file;
138 local $/;
139 open FOO, "cd '$tmpDir'/* && grep -v '^ *#' configure.ac |";
140 $file = <FOO>;
141 close FOO;
144 if ($file =~ /XAW_CHECK_XPRINT_SUPPORT/) {
145 push @requires, "libXaw";
148 if ($file =~ /zlib is required/ || $file =~ /AC_CHECK_LIB\(z\,/) {
149 push @requires, "zlib";
152 if ($file =~ /Perl is required/) {
153 push @requires, "perl";
156 if ($file =~ /AC_PATH_PROG\(BDFTOPCF/) {
157 push @nativeRequires, "bdftopcf";
160 if ($file =~ /AC_PATH_PROG\(MKFONTSCALE/ || $file =~ /XORG_FONT_REQUIRED_PROG\(MKFONTSCALE/) {
161 push @nativeRequires, "mkfontscale";
164 if ($file =~ /AC_PATH_PROG\(MKFONTDIR/) {
165 push @nativeRequires, "mkfontscale";
168 if ($file =~ /AM_PATH_PYTHON/) {
169 push @nativeRequires, "python3";
172 if ($file =~ /AC_PATH_PROG\(FCCACHE/) {
173 # Don't run fc-cache.
174 die if defined $extraAttrs{$pkg};
175 push @{$extraAttrs{$pkg}}, "preInstall = \"installFlags=(FCCACHE=true)\";";
178 my $isFont;
180 if ($file =~ /XORG_FONT_BDF_UTILS/) {
181 push @nativeRequires, "bdftopcf", "mkfontscale";
182 $isFont = 1;
185 if ($file =~ /XORG_FONT_SCALED_UTILS/) {
186 push @nativeRequires, "mkfontscale";
187 $isFont = 1;
190 if ($file =~ /XORG_FONT_UCS2ANY/) {
191 push @nativeRequires, "fontutil", "mkfontscale";
192 $isFont = 1;
195 if ($isFont) {
196 push @requires, "fontutil";
197 push @{$extraAttrs{$pkg}}, "configureFlags = [ \"--with-fontrootdir=\$(out)/lib/X11/fonts\" ];";
198 push @{$extraAttrs{$pkg}}, "postPatch = ''substituteInPlace configure --replace 'MAPFILES_PATH=`pkg-config' 'MAPFILES_PATH=`\$PKG_CONFIG' '';";
201 if (@@ = glob("$tmpDir/*/app-defaults/")) {
202 push @nativeRequires, "wrapWithXFileSearchPathHook";
205 sub process {
206 my $requires = shift;
207 my $s = shift;
208 $s =~ s/\[/\ /g;
209 $s =~ s/\]/\ /g;
210 $s =~ s/\,/\ /g;
211 foreach my $req (split / /, $s) {
212 next if $req eq ">=";
213 #next if $req =~ /^\$/;
214 next if $req =~ /^[0-9]/;
215 next if $req =~ /^\s*$/;
216 next if $req eq '$REQUIRED_MODULES';
217 next if $req eq '$REQUIRED_LIBS';
218 next if $req eq '$XDMCP_MODULES';
219 next if $req eq '$XORG_MODULES';
220 print "REQUIRE: $req\n";
221 push @{$requires}, $req;
225 #process \@requires, $1 while $file =~ /PKG_CHECK_MODULES\([^,]*,\s*[\[]?([^\)\[]*)/g;
226 process \@requires, $1 while $file =~ /PKG_CHECK_MODULES\([^,]*,([^\)\,]*)/g;
227 process \@requires, $1 while $file =~ /AC_SEARCH_LIBS\([^,]*,([^\)\,]*)/g;
228 process \@requires, $1 while $file =~ /MODULES=\"(.*)\"/g;
229 process \@requires, $1 while $file =~ /REQUIRED_LIBS=\"(.*)\"/g;
230 process \@requires, $1 while $file =~ /REQUIRED_MODULES=\"(.*)\"/g;
231 process \@requires, $1 while $file =~ /REQUIRES=\"(.*)\"/g;
232 process \@requires, $1 while $file =~ /X11_REQUIRES=\'(.*)\'/g;
233 process \@requires, $1 while $file =~ /XDMCP_MODULES=\"(.*)\"/g;
234 process \@requires, $1 while $file =~ /XORG_MODULES=\"(.*)\"/g;
235 process \@requires, $1 while $file =~ /NEEDED=\"(.*)\"/g;
236 process \@requires, $1 while $file =~ /ivo_requires=\"(.*)\"/g;
237 process \@requires, $1 while $file =~ /XORG_DRIVER_CHECK_EXT\([^,]*,([^\)]*)\)/g;
239 push @nativeRequires, "gettext" if $file =~ /USE_GETTEXT/;
240 push @requires, "libxslt" if $pkg =~ /libxcb/;
241 push @nativeRequires, "meson", "ninja" if $pkg =~ /libxcvt/;
242 push @nativeRequires, "m4" if $pkg =~ /xcbutil/;
243 push @requires, "gperf", "xorgproto" if $pkg =~ /xcbutil/;
245 print "REQUIRES $pkg => @requires\n";
246 print "NATIVE_REQUIRES $pkg => @nativeRequires\n";
247 $pkgRequires{$pkg} = \@requires;
248 $pkgNativeRequires{$pkg} = \@nativeRequires;
250 print "done\n";
254 print "\nWRITE OUT\n";
256 open OUT, ">default.nix";
258 print OUT "";
259 print OUT <<EOF;
260 # THIS IS A GENERATED FILE. DO NOT EDIT!
261 { lib, pixman }:
263 self: with self; {
265 inherit pixman;
270 foreach my $pkg (sort (keys %pkgURLs)) {
271 print "$pkg\n";
273 my %nativeRequires = ();
274 my @nativeBuildInputs;
275 foreach my $req (sort @{$pkgNativeRequires{$pkg}}) {
276 if (defined $pcMap{$req}) {
277 # Some packages have .pc that depends on itself.
278 next if $pcMap{$req} eq $pkg;
279 if (!defined $nativeRequires{$pcMap{$req}}) {
280 push @nativeBuildInputs, $pcMap{$req};
281 $nativeRequires{$pcMap{$req}} = 1;
283 } else {
284 print " NOT FOUND: $req\n";
287 my %requires = ();
288 my @buildInputs;
289 foreach my $req (sort @{$pkgRequires{$pkg}}) {
290 if (defined $pcMap{$req}) {
291 # Some packages have .pc that depends on itself.
292 next if $pcMap{$req} eq $pkg;
293 if (!defined $requires{$pcMap{$req}}) {
294 push @buildInputs, $pcMap{$req};
295 $requires{$pcMap{$req}} = 1;
297 } else {
298 print " NOT FOUND: $req\n";
302 my $nativeBuildInputsStr = join "", map { $_ . " " } @nativeBuildInputs;
303 my $buildInputsStr = join "", map { $_ . " " } @buildInputs;
305 sub uniq {
306 my %seen;
307 my @res = ();
308 foreach my $s (@_) {
309 if (!defined $seen{$s}) {
310 $seen{$s} = 1;
311 push @res, $s;
314 return @res;
317 my @arguments = @buildInputs;
318 push @arguments, @nativeBuildInputs;
319 unshift @arguments, "stdenv", "pkg-config", "fetchurl";
320 my $argumentsStr = join ", ", uniq @arguments;
322 my $extraAttrsStr = "";
323 if (defined $extraAttrs{$pkg}) {
324 $extraAttrsStr = join "", map { "\n " . $_ } @{$extraAttrs{$pkg}};
327 my $pcProvidesStr = "";
328 if (defined $pcProvides{$pkg}) {
329 $pcProvidesStr = join "", map { "\"" . $_ . "\" " } (sort @{$pcProvides{$pkg}});
332 print OUT <<EOF
333 # THIS IS A GENERATED FILE. DO NOT EDIT!
334 $pkg = callPackage ({ $argumentsStr, testers }: stdenv.mkDerivation (finalAttrs: {
335 pname = "$pkgNames{$pkg}";
336 version = "$pkgVersions{$pkg}";
337 builder = ./builder.sh;
338 src = fetchurl {
339 url = "$pkgURLs{$pkg}";
340 sha256 = "$pkgHashes{$pkg}";
342 hardeningDisable = [ "bindnow" "relro" ];
343 strictDeps = true;
344 nativeBuildInputs = [ pkg-config $nativeBuildInputsStr];
345 buildInputs = [ $buildInputsStr];$extraAttrsStr
346 passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
347 meta = {
348 pkgConfigModules = [ $pcProvidesStr];
349 platforms = lib.platforms.unix;
351 })) {};
356 print OUT "}\n";
358 close OUT;