X-Git-Url: https://git.pld-linux.org/?a=blobdiff_plain;f=findbr;h=9e2c930a36b67e261c6d7771204dad3f4bebd08f;hb=d35930ef370c60180348aae3c601b6712ec32a44;hp=0bb8e90f36520b57f59ded0cf13bb45e70669688;hpb=022b6e5be6429ca6ab15cfd2d84ba9a657718d5d;p=projects%2Fcleanbuild.git diff --git a/findbr b/findbr index 0bb8e90..9e2c930 100755 --- a/findbr +++ b/findbr @@ -3,13 +3,25 @@ use strict; use warnings; use IPC::Open2; +use Cwd; +use constant DOCKER => -e '/.dockerenv'; +my $pwd = getcwd(); # how to run poldek my @ignore = qw(vserver-packages python-devel-src); -my @poldek = (qw(sudo poldek -n th -n th-ready --cachedir=./poldekcache --skip-installed), - qw(-O keep_downloads=yes -O suggests=no -O unique_package_names=yes), +my @poldek; +if (DOCKER) { + push(@poldek, qw[poldek]); +} else { + push(@poldek, qw[sudo poldek -n th-x86_64-ready], + "--cachedir=$pwd/poldekcache", + "--conf=$pwd/poldekconf/poldek.conf", + ); +} +push(@poldek, ( + "--skip-installed", "-O", "ignore=" . (join " ", @ignore) -); +)); # if multiple packages provide some funcionality those will be selected: my %preferred = ( @@ -19,6 +31,7 @@ my %preferred = ( "python" => +1, "python-modules" => +1, + "python-setuptools" => +1, "perl-modules" => +1, "perl-Encode" => +2, @@ -27,27 +40,36 @@ my %preferred = ( "libstdc++-devel" => +1, "libusb-compat-devel" => +1, "libjpeg-devel" => +1, + "libpng-devel" => +1, "libsamplerate-devel" => +1, "pulseaudio-devel" => +1, "xorg-lib-libXrandr-devel" => +1, + "sqlite-devel" => +1, + + "ice-devel" => -1, ); -# translate package name to privodes name +# translate package name to provides name my %translate = ( + "gcc-c++" => "libstdc++-devel", "rarian-compat" => "scrollkeeper", "Mesa-libGL" => "OpenGL", "Mesa-libGL-devel" => "OpenGL-devel", "Mesa-libGLU-devel" => "OpenGL-GLU-devel", ); +my @skip = qw(hostname git svn svnversion mt gawk); +my %skip; +@skip{ @skip } = (1) x scalar @skip; + # for m4 in *.m4; do R=$(rpm -qf $m4); R=${R%-*-*}; \ # awk -vr=$R '/^\s*(AC_DEFUN|AU_ALIAS)/ { gsub(/\].*/,""); gsub(/.*\[/,""); print r " " $0}' $m4; \ # done | sort | awk '{print "\t\"" $2 "\" => \"" $1 "\","}' -my %ac2br = do "findbr-ac2br"; +my %ac2br = do (DOCKER ? './cleanbuild/findbr-ac2br' : './findbr-ac2br'); my %cmake2br = ( "findkde4:44" => "kde4-kdelibs", - "findmsgfmt" => "gettext-devel", + "findmsgfmt" => "gettext-tools", "findpythoninterp" => "python", ); @@ -89,17 +111,20 @@ sub add_br sub poldek_cmd { my $cmd = shift; + warn "Poldek: $cmd\n"; - my $pid = open( READ, "-|", @poldek, "--shcmd=".$cmd ); - my @read = ; - close READ; + my @cmd = (@poldek, "--shcmd=".$cmd); + open my $fh, '-|', @cmd or die "$!: @cmd"; + my @read = <$fh>; + close $fh or die $!; - return @read if wantarray; - return \@read; + return wantarray ? @read : \@read; } my $check_ac = 0; +my $check_config_log = undef; +my $check_mkmf_log = undef; my %checked_files; sub poldek_file @@ -198,104 +223,230 @@ sub guess_package return undef; } -my $check_config_log = undef; - start_check: my %checked; my $cmake_get_call = 0; my $cmake_pkg_list = 0; +my $py_ver = undef; while ( $_ = shift @lines ) { chomp; #next if $checked{ $_ }; #$checked{ $_ } = 1; + # try to extract current python version from setup.py run + if (m{^copying .+ -> build-(\d+)/lib/}) { + $py_ver = $1; + warn "py_ver set to '$py_ver'\n"; + } + $reason = $_; if ( /^\S+: (\S+): (?:Command )?not found$/ or /.*configure\[\d+\]: (\S+): not found$/ or m{which: no (\S+) in \(.*/bin.*\)} or m{\S+: (\S+): command not found$} + or m{(?:/usr/bin/)?env: (\S+): No such file or directory} + or m{flock: (\S+): No such file or directory} or m{Can't exec "(\S+)": No such file or directory} ) { my $exec = $1; - next if $exec eq "hostname"; + $exec = $1 if $exec =~ m{^"(.*)"$}; + next if $skip{ $exec }; warn "Looking for executable $exec\n"; if ( $exec =~ m#^/# ) { poldek_file( $exec ); } poldek_file( "/usr/bin/$exec", "/bin/$exec" ); } - - if ( /\S+\.[ch](?:pp|xx)?:\d+:\d+: error: (\S+): No such file or directory$/ ) { + if ( /\S+\.[ch](?:pp|xx|c)?:\d+:\d+: error: (\S+): No such file or directory$/ or + /\S+\.[ch](?:pp|xx|c)?:\d+:\d+: fatal error: (\S+): No such file or directory$/ or + /Can't find the '(\S+\.h)'? header/ + ) { my $h = $1; warn "Looking for C(++) header $h\n"; poldek_file( "/usr/include*/$h" ); } - if ( m{^ImportError: No module named (\S+)$} ) { + + if (m{^ImportError: No module named (\S+)$} + or m{^ERROR: Cannot find .+: No module named (\S+)$} + or m{^ERROR: Failed to import the ".+" module: No module named (\S+)$} + or m{^distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse\('([^'>=]+).*'\)} + or m{^error: Could not find suitable distribution for Requirement.parse\('([^'>=]+).*'\)} + or m{^Couldn't find index page for '(\S+)'} + ) { my $mod = $1; $mod =~ s#\.#/#g; - warn "Looking for python module $mod\n"; - poldek_file( "/usr/share/python2*/$mod/__init__.py*", - "/usr/share/python2*/$mod.py*", - "/usr/lib*/python2*/$mod.py*", - "/usr/lib*/python2*/_$mod.so" ); - } - if ( /configure(?:\.in|\.ac)?:\d+: error: possibly undefined macro: (\S+)/ - or m{configure(?:\.in|\.ac)?:\d+: error: m4 macro `(\S+)' is not defined} ) { + warn "Looking for Python$py_ver module $mod\n"; + poldek_file( + "/usr/share/python$py_ver*/site-packages/$mod/__init__.py*", + "/usr/share/python$py_ver*/$mod/__init__.py*", + "/usr/share/python$py_ver*/site-packages/$mod.py*", + "/usr/share/python$py_ver*/$mod.py*", + "/usr/lib*/python$py_ver*/site-packages/$mod/__init__.py*", + "/usr/lib*/python$py_ver*/$mod/__init__.py*", + "/usr/lib*/python$py_ver*/site-packages/$mod.py*", + "/usr/lib*/python$py_ver*/$mod.py*", + "/usr/lib*/python$py_ver*/site-packages/_$mod.so", + "/usr/lib*/python$py_ver*/_$mod.so", + "/usr/lib*/python$py_ver*/site-packages/$mod.so", + "/usr/lib*/python$py_ver*/$mod.so", + ); + } + + if ( + m{^-- Could NOT find Sphinx \(missing: SPHINX_EXECUTABLE\)} + ) { + add_br("sphinx-pdg"); + next; + } + + if ( + m{^You need to install the (\S+) module} or + m{\*\*\*Error\*\*\*: You must have (\S+) >= (\S+) installed} + ) { + add_br($1); + next; + } + + if ( + m{^cannot load such file -- (\S+)} or + m{in `require': cannot load such file -- (\S+) \(LoadError\)} + ) { + my $mod = $1; + warn "Looking for ruby module $mod\n"; + poldek_file( + "/usr/share/ruby/*/$mod.rb", + "/usr/share/ruby/vendor_ruby/*/$mod.rb", + "/usr/lib64/ruby/vendor_ruby/*/$mod.so", + ); + } + + if ( /configure(?:\.in|\.ac)?:\d+: error: possibly undefined macro: (\S+)/ + or m{configure(?:\.in|\.ac)?:\d+: error: m4 macro `(\S+)' is not defined} + or m{warning: macro `(\S+)' not found in library} ) { my $macro = $1; warn "Looking for autotools macro $macro\n"; if ( my $br = $ac2br{ $macro } ) { add_br( $br ); next; + } else { + $check_ac = 1; } } if ( /^No package '(\S+)' found$/ or /Package (\S+) was not found in the pkg-config search path/ or m{None of the required '(\S+?)(?:[<>=].*)?' found} or m{--\s+package '(\S+?)(?:[<>=].*)?' not found} + or m{ERROR: cannot find a valid pkg-config package for \['(\S+?)(?:[<>=].*)?'\]} ) { my $pkg = $1; warn "Looking for package $pkg\n"; - poldek_file( "/usr/lib*/pkgconfig/$pkg.pc" ); + poldek_file( "/usr/lib*/pkgconfig/$pkg.pc", "/usr/share/pkgconfig/$pkg.pc" ); } + + if (/^ocamlfind: Package `(\S+)' not found - required by/ + or m{Camlp4: Uncaught exception: DynLoader.Error \("(\S+)", "file not found in path"\)} + ) { + my $pkg = $1; + warn "Looking for ocaml package $pkg\n"; + poldek_file( "/usr/lib*/ocaml/*/$pkg.a", "/usr/lib*/ocaml/*/$pkg"); + } + if ( m{^cp: cannot stat `(/.*)': No such file or directory$} ) { my $f = $1; warn "Looking for file $f\n"; poldek_file( $f ); } + + if ( m{ERROR: Could not find KDE4 (kde4-config)}) { + my $f = "/usr/bin/$1"; + warn "Looking for file $f\n"; + poldek_file( $f ); + } + + if (m{Ragel State Machine Compiler not found}) { + add_br( "ragel" ); + next; + } + + if (m{ERROR: CMake is required to build}) { + add_br("cmake"); + next; + } + + # lucky guessing + if (m{'yum install (\S+)'}) { + add_br($1); + next; + } + if ( m{^find-lang.sh: Error: international files not found for '} or m{ gettext tools not found} ) { - add_br( "gettext-devel" ); - #exit; + add_br( "gettext-tools" ); next; } + if ( m{ pkg-config .*not .*found} - or m{^checking for pkg-config\.\.\. no} ) { + or m{^checking for pkg-config\.\.\. no} + or m{^pkg-config unavailable, build terminated} + or m{^\*\*\*Error\*\*\*: You must have pkg-config >= .* installed} + or m{^-- Could NOT find PkgConfig \(missing: PKG_CONFIG_EXECUTABLE\)} + or m{exec: "pkg-config": executable file not found in \$PATH} + ) { add_br( "pkgconfig" ); - #exit; next; } - if ( m{^Can't locate (.*?\.pm) in \@INC} ) { + + if ( m{Can't locate (.*?\.pm) in \@INC} ) { my $mod = $1; warn "Looking for perl module $mod\n"; poldek_file( "/usr/lib*/perl*/$mod", "/usr/share/perl*/$mod" ); } - if ( m{^/usr/bin/ld: cannot find -l(.*?)$} ) { + + if ( + m{^(?:/usr/bin/ld: )?cannot find -l(.*?)$} + ) { my $lib = $1; warn "Looking for library $lib\n"; - poldek_file( "/usr/lib*/lib$lib.so" ); + poldek_file( "/usr/lib64/lib$lib.so", "/usr/lib/lib$lib.so", + "/usr/lib*/lib$lib.so" ); } - if ( m{^error: Couldn't exec (/\S+): No such file or directory$} + + # full path to ldd files + if ( + m{^WARNING; can.*t resolve .* dependency: (.*?)$} + ) { + my $lib = $1; + warn "Looking for library '$lib'\n"; + poldek_file( "/usr/lib64/$lib", "/usr/lib/$lib", "/lib64/$lib", "/lib/$lib"); + } + + if ( m{^error: Couldn't exec (/\S+): No such file or directory$} or m{^Can't open perl script "(/\S+)": No such file or directory$} or m{unable to open (/\S+) \(No such file or directory\)$} or m{GConf-CRITICAL \*\*: No such file `(/.\S+?)'$} or m{make.*: \*\*\* No rule to make target `(/\S+)'} or m{g(?:cc|\+\+): (/\S+): No such file or directory$} + or m{env: (/\S+): No such file or directory$} ) { my $file = $1; warn "Looking for file $file\n"; poldek_file( $file ); } + + if ( m{^ValueError: Couldn't find include '(.*\.gir)'} ) { + my $file = $1; + warn "Looking for gir file $file\n"; + poldek_file( "/usr/share/gir-1.0/" . $file ); + } + + if ( m{^error: Package `(\S+)' not found in specified Vala API directories or GObject-Introspection GIR directories} + ) { + my $file = $1; + warn "Looking for gir file $file\n"; + poldek_file( "/usr/share/vala/vapi/$file.vapi"); + } + if ( m{failed.*http://www\.oasis-open\.org/docbook/xml/([\d\.]+/\S+\.dtd)} ) { my $dtd = $1; warn "Looking for docbook file $dtd\n"; @@ -307,15 +458,51 @@ while ( $_ = shift @lines ) { warn "Looking for docbook file $db\n"; poldek_file( "/usr/share/sgml/*/$db" ); } + if (m{Could not find HTML docbook.xsl}) { + add_br("docbook-style-xsl"); + } + + if ( m{LaTeX Error: File `(\S+)' not found} ) { + my $tex = $1; + warn "Looking for tex file $tex\n"; + poldek_file( "/usr/share/tex*/$tex" ); + } + if ( m{mv: cannot move `\S+' to `(/var/lib/texmf.*?)':} ) { + my $tex = $1; + warn "Looking for tex file $tex\n"; + poldek_file( $tex ); + } + if ( m{configure: error: C\+\+ preprocessor "/lib/cpp" fails sanity check} ) { add_br( "gcc-c++", "try: %undefine\t__cxx" ); } if ( m{configure: error: C\+\+ compiler cannot create executables} ) { add_br( "libstdc++-devel", "maybe try: %undefine\t__cxx" ); } + if ( m{ccache: error: Could not find compiler ".+-g\+\+" in PATH}) { + add_br("libstdc++-devel"); + } if ( m{configure: error: XML::Parser perl module is required for intltool} ) { add_br( "perl-XML-Parser" ); } + if ( m{iconv: conversion from `\S+' is not supported} ) { + add_br( "iconv" ); + } + + if (m{rst2man \(python-docutils\) is required to build man pages}) { + add_br("docutils"); + } + + if ( m{ (\S+) does not appear in AM_CONDITIONAL$} ) { + my $macro = $1; + warn "Looking for autotools macro $macro\n"; + if ( my $br = $ac2br{ $macro } ) { + add_br( $br ); + next; + } else { + $check_ac = 1; + } + } if ( m{configure\[\d+\]: syntax error: } or m{\./configure\[\d+\]: \S+_\S+: not found} @@ -329,7 +516,11 @@ while ( $_ = shift @lines ) { $check_config_log = 1 unless defined $check_config_log; } - if ( m{^CMake Error at (?:\S+/)?(\S+?)\.cmake:(\d+) } ) { + if ( m{Check the mkmf.log file for more details} ) { + $check_mkmf_log = 1 unless defined $check_mkmf_log; + } + + if ( m{^CMake (?:Error|Warning) at (?:\S+/)?(\S+?)\.cmake:(\d+) } ) { my ( $module, $line ) = ( lc $1, $2 ); my $br; if ( $module eq "findqt4" ) { @@ -377,12 +568,23 @@ while ( $_ = shift @lines ) { add_br( $br ); $cmake_get_call = 0; } + } elsif (m{Can not use "(.+)" module which has not yet been found} + or m{Could not find a package configuration file provided by "(.+)"}) { + my $cmake = $1; + + warn "Looking for cmake file: $cmake\n"; + poldek_file( + "/usr/*/cmake/*/$cmake.cmake", + "/usr/*/cmake/*/${cmake}Config.cmake", + "/usr/*/cmake/*/${cmake}-config.cmake", + ); + $cmake_get_call = 0; } } if ( m{^-- WARNING: you are using the obsolete 'PKGCONFIG' macro} ) { add_br( "pkgconfig" ); } - if ( m{QT_(QT\S+)_LIBRARY \(ADVANCED\)} + if ( m{QT_(QT\S+)_LIBRARY \(ADVANCED\)} or m{X11_(\S+)_LIB \(ADVANCED\)} or m{Qt (\S+) library not found} ) { my $find = $1; @@ -394,6 +596,16 @@ while ( $_ = shift @lines ) { } } + if ( m{Unable to find a javac compiler;$} ) { + add_br( "jdk" ); + } + if ( m{Could not find (\S+) Java extension for this JVM$} ) { + my $jar = $1; + warn "Looking for jar file: $jar\n"; + poldek_file( "/usr/share/java/$jar.jar", "*/$jar.jar" ) + } + + if ( m{^-- The following OPTIONAL packages could NOT be located on your system} ) { $cmake_pkg_list = 1; } @@ -410,11 +622,74 @@ while ( $_ = shift @lines ) { $cmake_pkg_list = 0; } } + + # CMake Error at CMakeLists.txt:86 (find_package): + # By not providing "FindQt5LinguistTools.cmake" in CMAKE_MODULE_PATH this + # project has asked CMake to find a package configuration file provided by + # "Qt5LinguistTools", but CMake did not find one. + # + # Could not find a package configuration file provided by "Qt5LinguistTools" + # with any of the following names: + # + # Qt5LinguistToolsConfig.cmake + # qt5linguisttools-config.cmake + # + # Add the installation prefix of "Qt5LinguistTools" to CMAKE_PREFIX_PATH or + # set "Qt5LinguistTools_DIR" to a directory containing one of the above + # files. If "Qt5LinguistTools" provides a separate development package or + # SDK, be sure it has been installed. + # --- + #CMake Warning at /usr/lib64/cmake/Qt5Core/Qt5CoreMacros.cmake:273 (find_package): + # Could not find a package configuration file provided by "Qt5Network" with + # any of the following names: + # + # Qt5NetworkConfig.cmake + # qt5network-config.cmake + # + # Add the installation prefix of "Qt5Network" to CMAKE_PREFIX_PATH or set + # "Qt5Network_DIR" to a directory containing one of the above files. If + # "Qt5Network" provides a separate development package or SDK, be sure it has + # been installed. + # Can not use "Network" module which has not yet been found. + + if (m{By not providing "Find(.+)\.cmake" in CMAKE_MODULE_PATH} + or m{Could not find a package configuration file provided by "(.+)" + }) { + my $cmake = $1; + my $lcmake = lc $cmake; + + warn "Looking for cmake file: $cmake\n"; + poldek_file( + "/usr/*/cmake/*/$cmake.cmake", + "/usr/*/cmake/*/${cmake}Config.cmake", + "/usr/*/cmake/*/${cmake}-config.cmake", + "/usr/*/cmake/*/${lcmake}Config.cmake", + "/usr/*/cmake/*/${lcmake}-config.cmake", + ) + } + + if ( m{^configure:\d+: checking for (?:"(\S+)"|(\S+))$} ) { + my $exec = $1 || $2; + if ( @lines and $lines[0] =~ m{^configure:\d+: result: no$} ) { + next if $skip{ $exec }; + warn "Looking for executable $exec\n"; + poldek_file( $exec ) if $exec =~ m#^/#; + poldek_file( "/usr/bin/$exec", "/bin/$exec" ); + } + } + + + if ( + m{Could not find (\S+)} + ) { + my $exec = $1; + poldek_file("/usr/bin/$exec", "/bin/$exec" ); + } } -sub wanted +sub find_configure { return unless /^configure(\.(?:ac|in|in\.in))?$/; return unless -r; @@ -438,10 +713,10 @@ sub wanted use File::Find; if ( $check_ac ) { - find( \&wanted, $builddir ); + find( \&find_configure, $builddir ); } -sub wanted2 +sub find_config_log { return unless /^config\.log$/; return unless -r; @@ -454,7 +729,21 @@ sub wanted2 if ( $check_config_log ) { $check_config_log = 0; - find( \&wanted2, $builddir ); + find( \&find_config_log, $builddir ); + goto start_check if @lines; +} + +if ($check_mkmf_log) { + $check_mkmf_log = 0; + find(sub { + return unless /^mkmf\.log$/; + return unless -r; + + warn "$File::Find::name\n"; + open F_IN, "<", $_; + push @lines, ; + close F_IN; + }, $builddir); goto start_check if @lines; }