]> git.pld-linux.org Git - projects/cleanbuild.git/blame - findbr
- ignore git and svn requirements
[projects/cleanbuild.git] / findbr
CommitLineData
c494424e 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use IPC::Open2;
c728428f 6use Cwd;
c494424e 7
c728428f 8my $pwd = getcwd();
c494424e 9# how to run poldek
10my @ignore = qw(vserver-packages python-devel-src);
c728428f 11my @poldek = (qw(sudo poldek -n th-x86_64-ready), "--cachedir=$pwd/poldekcache",
12 "--skip-installed", "--conf=$pwd/poldekconf/poldek.conf",
c494424e 13 "-O", "ignore=" . (join " ", @ignore)
14);
15
16# if multiple packages provide some funcionality those will be selected:
17my %preferred = (
18 "automake" => +1,
19 "autoconf" => +1,
20 "pkgconfig" => +1,
21
22 "python" => +1,
23 "python-modules" => +1,
24
25 "perl-modules" => +1,
26 "perl-Encode" => +2,
27
28 "zlib-devel" => +1,
29 "libstdc++-devel" => +1,
a75e2ecf 30 "libusb-compat-devel" => +1,
022b6e5b 31 "libjpeg-devel" => +1,
c728428f 32 "libpng-devel" => +1,
022b6e5b 33 "libsamplerate-devel" => +1,
34 "pulseaudio-devel" => +1,
35 "xorg-lib-libXrandr-devel" => +1,
c728428f 36 "sqlite-devel" => +1,
c494424e 37);
38
44dfaf2a 39# translate package name to provides name
c494424e 40my %translate = (
41 "rarian-compat" => "scrollkeeper",
022b6e5b 42 "Mesa-libGL" => "OpenGL",
43 "Mesa-libGL-devel" => "OpenGL-devel",
c494424e 44 "Mesa-libGLU-devel" => "OpenGL-GLU-devel",
45);
46
47# for m4 in *.m4; do R=$(rpm -qf $m4); R=${R%-*-*}; \
48# awk -vr=$R '/^\s*(AC_DEFUN|AU_ALIAS)/ { gsub(/\].*/,""); gsub(/.*\[/,""); print r " " $0}' $m4; \
49# done | sort | awk '{print "\t\"" $2 "\" => \"" $1 "\","}'
50my %ac2br = do "findbr-ac2br";
51
52my %cmake2br = (
53 "findkde4:44" => "kde4-kdelibs",
54 "findmsgfmt" => "gettext-devel",
55 "findpythoninterp" => "python",
56);
57
58BEGIN {
59 $SIG{__WARN__} = sub
60 {
61 local $_ = shift;
62 chomp;
63 print STDERR "\033[31;1m" . $_ . "\033[0m\n"
64 };
65}
66
67my $builddir = shift @ARGV;
68my @lines = <ARGV>;
69
70my $reason;
71
72my %out;
73sub add_br
74{
75 my $pkg = shift;
76 my $msg = shift || $reason;
77 if ( ref $pkg ) {
78 foreach my $p ( @$pkg ) {
79 add_br( $p, $msg );
80 }
81 return;
82 }
83
84 $msg =~ s/\n/ # /sg;
85
86 $pkg = $translate{ $pkg } || $pkg;
87
88 return if exists $out{ $pkg };
89 $out{ $pkg } = $msg;
90 print STDERR "\033[33;1madding: $pkg => $msg\033[0m\n";
91}
92
93sub poldek_cmd
94{
95 my $cmd = shift;
96 warn "Poldek: $cmd\n";
97 my $pid = open( READ, "-|", @poldek, "--shcmd=".$cmd );
98
99 my @read = <READ>;
100 close READ;
101
102 return @read if wantarray;
103 return \@read;
104}
105
106my $check_ac = 0;
c728428f 107my $check_config_log = undef;
c494424e 108
109my %checked_files;
110sub poldek_file
111{
112 my @files;
113 foreach ( @_ ) {
114 next if $checked_files{ $_ };
115 $checked_files{ $_ } = 1;
116 push @files, $_;
117 }
118 return unless @files;
119
120 my $search = join "; ", map "search -f $_", @files;
121 warn "Reason: $reason\n";
122 my @read = poldek_cmd( $search );
123
124 local $_;
125 my @found;
126 while ( $_ = shift @read ) {
127 if ( /(\d+) package\(s\) found:$/ ) {
128 foreach my $i ( 1..$1 ) {
129 $_ = shift @read;
130 chomp;
131 $_ =~ /^(.*)-.*?-.*?$/;
132 push @found, $1;
133 }
134 }
135 }
136
137 return unless @found;
138
139 my $found = $found[0];
140 if ( @found > 1 ) {
141 my $i = 0.0;
142 my %pts = map { ( $_ => ( ($i += 0.001) + ( $preferred{ $_ } || 0 ) ) ) }
143 reverse @found;
144 my @pref = sort { $pts{$b} <=> $pts{$a} } @found;
145 my $pref = join ", ", map "$_ => $pts{$_}", @pref;
146 warn "Multiple found: $pref\n";
147 $found = $pref[0];
148 }
149
150 $found = $translate{ $found } if $translate{ $found };
151
152 add_br( $found );
153}
154
155my $pkglist;
156sub get_pkglist
157{
158 my %pkglist;
159 my $read = poldek_cmd( "ls" );
160 foreach ( @$read ) {
161 chomp;
162 next unless /(\S+)-.*?-.*?\.[a-z0-9_]+$/;
163 my $pkg = $1;
164 $pkglist{ lc $pkg } = $pkg;
165 }
166 $pkglist = \%pkglist;
167}
168
169sub guess_package
170{
171 my $origname = shift;
172 get_pkglist() unless $pkglist;
173 return unless defined $origname;
174 my $name = lc $origname;
175 my @try = (
176 "lib$name-devel",
177 "$name-devel",
178 "$name",
179 "lib$name-.*-devel",
180 "$name-.*-devel",
181 ".*-lib$name-devel",
182 ".*-$name-devel",
183 ".*-lib$name-.*-devel",
184 ".*-$name-.*-devel",
185 );
186 my @select;
187 for my $k ( keys %$pkglist ) {
188 if ( $k =~ /$name/ ) {
189 push @select, $k;
190 }
191 }
192 @select = sort @select;
193
194 foreach my $try ( @try ) {
195 foreach my $pkg ( @select ) {
196 if ( $pkg =~ /^$try$/ ) {
197 warn "guessed: $origname => $pkglist->{ $pkg }\n";
198 return $pkglist->{ $pkg };
199 }
200 }
201 }
202 warn "$origname not guessed\n";
203 return undef;
204}
205
022b6e5b 206start_check:
207
c494424e 208my %checked;
209my $cmake_get_call = 0;
210my $cmake_pkg_list = 0;
211while ( $_ = shift @lines ) {
212 chomp;
213 #next if $checked{ $_ };
214 #$checked{ $_ } = 1;
215
216 $reason = $_;
217 if ( /^\S+: (\S+): (?:Command )?not found$/ or /.*configure\[\d+\]: (\S+): not found$/
218 or m{which: no (\S+) in \(.*/bin.*\)}
219 or m{\S+: (\S+): command not found$}
4dc40081 220 or m{/usr/bin/env: (\S+): No such file or directory}
c494424e 221 or m{Can't exec "(\S+)": No such file or directory} ) {
222 my $exec = $1;
c728428f 223 $exec = $1 if $exec =~ m{^"(.*)"$};
c494424e 224 next if $exec eq "hostname";
3c9ebd69 225 next if $exec eq "git";
226 next if $exec eq "svn";
c494424e 227 warn "Looking for executable $exec\n";
228 if ( $exec =~ m#^/# ) {
229 poldek_file( $exec );
230 }
231 poldek_file( "/usr/bin/$exec", "/bin/$exec" );
232 }
233
234
bfe0e7d5 235 if ( /\S+\.[ch](?:pp|xx|c)?:\d+:\d+: error: (\S+): No such file or directory$/ or
236 /\S+\.[ch](?:pp|xx|c)?:\d+:\d+: fatal error: (\S+): No such file or directory$/ ) {
c494424e 237 my $h = $1;
238 warn "Looking for C(++) header $h\n";
239 poldek_file( "/usr/include*/$h" );
240 }
241 if ( m{^ImportError: No module named (\S+)$} ) {
242 my $mod = $1;
243 $mod =~ s#\.#/#g;
244 warn "Looking for python module $mod\n";
245 poldek_file( "/usr/share/python2*/$mod/__init__.py*",
246 "/usr/share/python2*/$mod.py*",
247 "/usr/lib*/python2*/$mod.py*",
248 "/usr/lib*/python2*/_$mod.so" );
249 }
250 if ( /configure(?:\.in|\.ac)?:\d+: error: possibly undefined macro: (\S+)/
e6da4d63 251 or m{configure(?:\.in|\.ac)?:\d+: error: m4 macro `(\S+)' is not defined}
252 or m{warning: macro `(\S+)' not found in library} ) {
c494424e 253 my $macro = $1;
254 warn "Looking for autotools macro $macro\n";
255 if ( my $br = $ac2br{ $macro } ) {
256 add_br( $br );
257 next;
c728428f 258 } else {
259 $check_ac = 1;
c494424e 260 }
261 }
262 if ( /^No package '(\S+)' found$/ or
263 /Package (\S+) was not found in the pkg-config search path/
264 or m{None of the required '(\S+?)(?:[<>=].*)?' found}
265 or m{--\s+package '(\S+?)(?:[<>=].*)?' not found}
266 ) {
267 my $pkg = $1;
268 warn "Looking for package $pkg\n";
269 poldek_file( "/usr/lib*/pkgconfig/$pkg.pc" );
270 }
271 if ( m{^cp: cannot stat `(/.*)': No such file or directory$} ) {
272 my $f = $1;
273 warn "Looking for file $f\n";
274 poldek_file( $f );
275 }
276 if ( m{^find-lang.sh: Error: international files not found for '}
277 or m{ gettext tools not found}
278 ) {
279 add_br( "gettext-devel" );
280 #exit;
281 next;
282 }
283 if ( m{ pkg-config .*not .*found}
284 or m{^checking for pkg-config\.\.\. no} ) {
285 add_br( "pkgconfig" );
286 #exit;
287 next;
288 }
289 if ( m{^Can't locate (.*?\.pm) in \@INC} ) {
290 my $mod = $1;
291 warn "Looking for perl module $mod\n";
292 poldek_file( "/usr/lib*/perl*/$mod", "/usr/share/perl*/$mod" );
293 }
c728428f 294 if ( m{^(?:/usr/bin/ld: )?cannot find -l(.*?)$} ) {
c494424e 295 my $lib = $1;
296 warn "Looking for library $lib\n";
c728428f 297 poldek_file( "/usr/lib64/lib$lib.so", "/usr/lib/lib$lib.so",
298 "/usr/lib*/lib$lib.so" );
c494424e 299 }
300 if ( m{^error: Couldn't exec (/\S+): No such file or directory$}
301 or m{^Can't open perl script "(/\S+)": No such file or directory$}
302 or m{unable to open (/\S+) \(No such file or directory\)$}
303 or m{GConf-CRITICAL \*\*: No such file `(/.\S+?)'$}
304 or m{make.*: \*\*\* No rule to make target `(/\S+)'}
305 or m{g(?:cc|\+\+): (/\S+): No such file or directory$}
c728428f 306 or m{env: (/\S+): No such file or directory$}
c494424e 307 ) {
308 my $file = $1;
309 warn "Looking for file $file\n";
310 poldek_file( $file );
311 }
c728428f 312 if ( m{^ValueError: Couldn't find include '(.*\.gir)'} ) {
313 my $file = $1;
314 warn "Looking for gir file $file\n";
315 poldek_file( "/usr/share/gir-1.0/" . $file );
316 }
c494424e 317 if ( m{failed.*http://www\.oasis-open\.org/docbook/xml/([\d\.]+/\S+\.dtd)} ) {
318 my $dtd = $1;
319 warn "Looking for docbook file $dtd\n";
320 poldek_file( "/usr/share/sgml/docbook/xml-dtd-$dtd" );
321 }
322 if ( m{http://docbook.sourceforge.net/release/xsl/current/(\S+\.xsl)} ) {
323 my $db = $1;
324 next if m{^\s*(/usr/bin/)?xsltproc };
325 warn "Looking for docbook file $db\n";
326 poldek_file( "/usr/share/sgml/*/$db" );
327 }
a755261c 328
329 if ( m{LaTeX Error: File `(\S+)' not found} ) {
330 my $tex = $1;
331 warn "Looking for tex file $tex\n";
332 poldek_file( "/usr/share/tex*/$tex" );
333 }
334 if ( m{mv: cannot move `\S+' to `(/var/lib/texmf.*?)':} ) {
335 my $tex = $1;
336 warn "Looking for tex file $tex\n";
337 poldek_file( $tex );
338 }
339
c494424e 340 if ( m{configure: error: C\+\+ preprocessor "/lib/cpp" fails sanity check} ) {
341 add_br( "gcc-c++", "try: %undefine\t__cxx" );
342 }
343 if ( m{configure: error: C\+\+ compiler cannot create executables} ) {
344 add_br( "libstdc++-devel", "maybe try: %undefine\t__cxx" );
345 }
346 if ( m{configure: error: XML::Parser perl module is required for intltool} ) {
347 add_br( "perl-XML-Parser" );
348 }
9ffdd22c 349 if ( m{iconv: conversion from `\S+' is not supported} ) {
350 add_br( "iconv" );
351 }
c494424e 352
bfe0e7d5 353 if ( m{ (\S+) does not appear in AM_CONDITIONAL$} ) {
354 my $macro = $1;
355 warn "Looking for autotools macro $macro\n";
356 if ( my $br = $ac2br{ $macro } ) {
357 add_br( $br );
358 next;
359 } else {
360 $check_ac = 1;
361 }
362 }
363
c494424e 364 if ( m{configure\[\d+\]: syntax error: }
a75e2ecf 365 or m{\./configure\[\d+\]: \S+_\S+: not found}
366 or m{./configure\[\d+\]: .*unexpected}
367 or m{does not appear in AM_CONDITIONAL$}
368 ) {
c494424e 369 warn "Need to check configure source: $reason\n";
370 $check_ac = 1;
371 }
022b6e5b 372 if ( m{^configure: error:} ) {
373 $check_config_log = 1 unless defined $check_config_log;
374 }
c494424e 375
376 if ( m{^CMake Error at (?:\S+/)?(\S+?)\.cmake:(\d+) } ) {
377 my ( $module, $line ) = ( lc $1, $2 );
378 my $br;
379 if ( $module eq "findqt4" ) {
380 my $l = $lines[0];
381 chomp $l;
382 if ( $l =~ /qmake/ ) {
383 add_br( "qt4-qmake", $l );
384 } elsif ( $l =~ /rcc/ ) {
385 add_br( "qt4-build", $l );
386 } elsif ( $l =~ /Could NOT find (Qt\S+) header/ ) {
387 add_br( "$1-devel", $l );
388 } else {
389 warn "unrecognized Qt requirement: $l\n";
390 }
391 } elsif ( $module eq "cmakedeterminecxxcompiler" ) {
392 add_br( "libstdc++-devel",
393 '"try: -DCMAKE_CXX_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER="%{__cc}"' );
394 } elsif ( $br = $cmake2br{ $module . ":" . $line } ) {
395 add_br( $br );
396 } elsif ( $br = $cmake2br{ $module } ) {
397 add_br( $br );
398 } elsif ( $br = guess_package( $module =~ /find(.+)/ ) ) {
399 add_br( $br );
400 } else {
401 $cmake_get_call = 1;
402 warn "Unrecognized cmake error: $reason\n";
403 }
404 }
405 if ( m{^\s*ERROR: (?:\S+/)?(\S+?\.cmake) not found} ) {
406 my $cmake = $1;
407 warn "Looking for cmake file: $cmake\n";
408 poldek_file( "/usr/*/cmake/*/$cmake" )
409 }
410 if ( $cmake_get_call ) {
411 if ( m{^\s*/\S+/(\S+)\.cmake:(\d+) } ) {
412 my ( $module, $line ) = ( lc $1, $2 );
413 my $br;
414 if ( $br = $cmake2br{ $module . ":" . $line } ) {
415 add_br( $br );
416 $cmake_get_call = 0;
417 } elsif ( $br = $cmake2br{ $module } ) {
418 add_br( $br );
419 $cmake_get_call = 0;
420 } elsif ( $br = guess_package( $module =~ /find(.+)/ ) ) {
421 add_br( $br );
422 $cmake_get_call = 0;
423 }
424 }
425 }
426 if ( m{^-- WARNING: you are using the obsolete 'PKGCONFIG' macro} ) {
427 add_br( "pkgconfig" );
428 }
429 if ( m{QT_(QT\S+)_LIBRARY \(ADVANCED\)}
430 or m{X11_(\S+)_LIB \(ADVANCED\)}
431 or m{Qt (\S+) library not found} ) {
432 my $find = $1;
433 my $pkg = guess_package( $find );
434 if ( $pkg ) {
435 add_br( $pkg );
436 } else {
437 warn "Cannot quess qt package: $find\n";
438 }
439 }
440
e6da4d63 441 if ( m{Unable to find a javac compiler;$} ) {
442 add_br( "jdk" );
443 }
9ffdd22c 444 if ( m{Could not find (\S+) Java extension for this JVM$} ) {
445 my $jar = $1;
446 warn "Looking for jar file: $jar\n";
447 poldek_file( "/usr/share/java/$jar.jar", "*/$jar.jar" )
448 }
e6da4d63 449
450
c494424e 451 if ( m{^-- The following OPTIONAL packages could NOT be located on your system} ) {
452 $cmake_pkg_list = 1;
453 }
454 if ( $cmake_pkg_list ) {
455 if ( /\s+\* (\S+) / ) {
456 my $find = $1;
457 my $pkg = guess_package( $find );
458 if ( $pkg ) {
459 add_br( $pkg );
460 } else {
461 warn "Cannot quess optional package: $find\n";
462 }
463 } elsif ( /^\s*$/ ) {
464 $cmake_pkg_list = 0;
465 }
466 }
c728428f 467
468 if ( m{^configure:\d+: checking for (?:"(\S+)"|(\S+))$} ) {
469 my $exec = $1 || $2;
470 if ( @lines and $lines[0] =~ m{^configure:\d+: result: no$} ) {
471 next if $exec eq "hostname";
472 warn "Looking for executable $exec\n";
473 poldek_file( $exec ) if $exec =~ m#^/#;
474 poldek_file( "/usr/bin/$exec", "/bin/$exec" );
475 }
476 }
c494424e 477}
478
479
480
481sub wanted
482{
483 return unless /^configure(\.(?:ac|in|in\.in))?$/;
484 return unless -r;
485
486 warn "$File::Find::name\n";
487 open F_IN, "<", $_;
488 my $file = $_;
489 while ( <F_IN> ) {
490 chomp;
491 if ( m{^\s*([A-Za-z0-9_]+)\s*(\(.*)?$} ) {
492 my $def = $1;
493 if ( my $br = $ac2br{ $def } ) {
494 add_br( $br, "$file: $_" );
495 } elsif ( $def !~ /^A[CM]_/ and $def =~ /^_?[A-Z]+_[A-Z_0-9a-z]+$/ ) {
496 #warn "Possible macro unrecognized: $def [[[$_]]]\n";
497 }
498 }
499 }
500 close F_IN;
501}
502
503use File::Find;
504if ( $check_ac ) {
505 find( \&wanted, $builddir );
506}
507
022b6e5b 508sub wanted2
509{
510 return unless /^config\.log$/;
511 return unless -r;
512
513 warn "$File::Find::name\n";
514 open F_IN, "<", $_;
515 push @lines, <F_IN>;
516 close F_IN;
517}
518
519if ( $check_config_log ) {
520 $check_config_log = 0;
521 find( \&wanted2, $builddir );
522 goto start_check if @lines;
523}
524
c494424e 525foreach my $pkg ( sort keys %out ) {
526 print "$pkg -- $out{$pkg}\n";
527}
528# vim: ts=4 sw=4
This page took 0.080892 seconds and 4 git commands to generate.