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-x86_64-ready), "--cachedir=$pwd/poldekcache",
- "--skip-installed", "--conf=$pwd/poldekconf/poldek.conf",
+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 = (
"python" => +1,
"python-modules" => +1,
+ "python-setuptools" => +1,
"perl-modules" => +1,
"perl-Encode" => +2,
"pulseaudio-devel" => +1,
"xorg-lib-libXrandr-devel" => +1,
"sqlite-devel" => +1,
+
+ "ice-devel" => -1,
);
# 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);
+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",
);
sub poldek_cmd
{
my $cmd = shift;
+
warn "Poldek: $cmd\n";
- my $pid = open( READ, "-|", @poldek, "--shcmd=".$cmd );
- my @read = <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
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{(?:/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;
$exec = $1 if $exec =~ m{^"(.*)"$};
}
poldek_file( "/usr/bin/$exec", "/bin/$exec" );
}
-
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$/ ) {
+ /\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" );
+ 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 ( /configure(?:\.in|\.ac)?:\d+: error: possibly undefined macro: (\S+)/
+
+ 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;
/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/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+?)'$}
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";
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;
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" );
}
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";
$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" ) {
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;
}
}
+ # 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$} ) {
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;
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;
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, <F_IN>;
+ close F_IN;
+ }, $builddir);
goto start_check if @lines;
}