diff --git a/CMakeLists.txt b/CMakeLists.txt index 43e67b4..8e762ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,13 @@ install(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/kdesrc-build-setup DESTINATION ${KD install(PROGRAMS ${CMAKE_SOURCE_DIR}/sample-kde-env-master.sh ${CMAKE_SOURCE_DIR}/sample-xsession.sh - DESTINATION ${KDE_INSTALL_DATADIR}/kdesrc-build) + ${CMAKE_SOURCE_DIR}/kf5-applications-build-include + ${CMAKE_SOURCE_DIR}/kf5-extragear-build-include + ${CMAKE_SOURCE_DIR}/kf5-frameworks-build-include + ${CMAKE_SOURCE_DIR}/kf5-kdepim-build-include + ${CMAKE_SOURCE_DIR}/kf5-qt5-build-include + ${CMAKE_SOURCE_DIR}/kf5-workspace-build-include + DESTINATION ${KDE_INSTALL_DATADIR}/kdesrc-build) if (ECM_FOUND) feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/custom-qt5-libs-build-include b/custom-qt5-libs-build-include index b555171..be17e0b 100644 --- a/custom-qt5-libs-build-include +++ b/custom-qt5-libs-build-include @@ -8,7 +8,7 @@ module poppler repository git://git.freedesktop.org/git/poppler/poppler branch master - cmake-options -DWITH_GLIB=OFF -DLIB_SUFFIX=64 + cmake-options -DWITH_GLIB=OFF -DLIB_SUFFIX=64 -DENABLE_XPDF_HEADERS=1 end module # For kaccounts-integration @@ -51,7 +51,7 @@ module sphinxbase end module module qwt6 - override-url svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.1 + override-url svn://svn.code.sf.net/p/qwt/code/branches/qwt-6.2 # The qwt6 build system is very unflexible. # For this to work you need to comment out all lines setting QWT_INSTALL_PREFIX in qwtconfig.pri... qmake-options QWT_INSTALL_PREFIX=${kdedir} diff --git a/doc/index.docbook b/doc/index.docbook index 1f169cd..f1ccd08 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -269,7 +269,7 @@ does not cover this installation type, since we assume you know what you are doi -Ensure your system is ready to build &kde; source +Ensure your system is ready to build &kde; software Before using the &kdesrc-build; script (or any other building strategy) you must install the development tools and libraries needed for &kde;. @@ -545,7 +545,7 @@ it is a good idea to at least load the &kde; project metadata. Loading project metadata -From a terminal window, log in to the user you are using to compile &kde; and +From a terminal window, log in to the user you are using to compile &kde; software and execute the script: @@ -627,8 +627,8 @@ Your logs are saved in /home/kde-src/kdesrc/log/2018-01-20-07 Depending on how many modules you are downloading, it is possible that -&kdesrc-build; will not succeed the first time you compile &kde;. Do not -despair! +&kdesrc-build; will not succeed the first time you compile &kde; software. +Do not despair! &kdesrc-build; logs the output of every command it runs. By default, @@ -660,7 +660,7 @@ to mail the kde-devel@kde.org mailing list (subscription may be required first) in order to report the build failure. You can find more common examples of things that can go wrong and their -solutions, as well as general tips and strategies to build &kde; in the +solutions, as well as general tips and strategies to build &kde; software in the Build from Source. @@ -742,9 +742,9 @@ linkend="conf-include-dependencies">include-dependencies option). Setting the Environment to Run Your &kde; &plasma; Desktop -Assuming you are using a dedicated user to build &kde;, and you already have an -installed &kde; version, running your new &kde; may be a bit tricky, as the new -&kde; has to take precedence over the old. You must change the environment +Assuming you are using a dedicated user to build &kde; &plasma;, and you already have an +installed &plasma; version, running your new &plasma; may be a bit tricky, as the new +&plasma; has to take precedence over the old. You must change the environment variables of your login scripts to make sure the newly-built desktop is used. @@ -1295,7 +1295,7 @@ distribution). &kdesrc-build; does not require a GUI present to operate. So, -you can build &kde; without needing an alternate graphical environment. +you can build &kde; software without needing a graphical environment. @@ -2644,7 +2644,7 @@ installed. Note that using this option can have a significant detrimental impact on -both your bandwidth usage (if you use all) and the time taken to compile &kde;, +both your bandwidth usage (if you use all) and the time taken to compile &kde; software, since &kdesrc-build; will be unable to perform incremental builds. diff --git a/doc/kdesrc-build.desktop b/doc/kdesrc-build.desktop index 08295fb..e56c4d4 100644 --- a/doc/kdesrc-build.desktop +++ b/doc/kdesrc-build.desktop @@ -25,6 +25,7 @@ Name[mr]=केडीई स्रोतबिल्डर Name[nb]=KDE kildebygger Name[nds]=KDE-Bornkode-Buumoduul Name[nl]=KDE Source Builder +Name[nn]=Byggjar for KDE-kjeldekode Name[pa]=KDE ਸਰੋਤ ਬਿਲਡਰ Name[pl]=Budowanie KDE ze źródeł Name[pt]=Compilação do Código do KDE @@ -65,6 +66,7 @@ Comment[lt]=Kompiliuoja KDE platformą ir susijusią programinę įrangą iš i Comment[nb]=Bygger KDE-plattformen og tilordnede programmer fra kildekoden. Dette er et program med bare kommandolinje. Comment[nds]=Buut de KDE-Systemümgeven un tohören Programmen ut den Bornkode. Bloots en Konsoolprogramm. Comment[nl]=Bouwt het KDE-platform en geassocieerde software uit zijn broncode. Werkt alleen op de opdrachtregel. +Comment[nn]=Byggjer KDE-plattforma og tilhøyrande programvare frå kjeldekoden. Er eit kommandolinjebasert program. Comment[pl]=Budowanie Środowiska KDE i związanego z nim oprogramowania z kodu źródłowego. Program działa tylko w linii poleceń. Comment[pt]=Compila a Plataforma do KDE e os programas associados a partir do seu código-fonte. Um programa apenas para a linha de comandos. Comment[pt_BR]=Compila a Plataforma do KDE e os programas associados a partir do seu código-fonte. Um programa apenas para a linha de comando. diff --git a/kdesrc-build-setup b/kdesrc-build-setup index fdf8fe0..2999c70 100755 --- a/kdesrc-build-setup +++ b/kdesrc-build-setup @@ -374,6 +374,16 @@ EOF # Assume we can refer to files present alongside kdesrc-build in the source # directory my $basedir = dirname(abs_path($0)); +if (! -e "$basedir/kf5-frameworks-build-include") { + # Check if it's installed to a share/ prefix + $basedir = abs_path(dirname($0) . "/../share/kdesrc-build/"); + + if (! -e "$basedir/kf5-frameworks-build-include") { + close $output; + showInfo("Unable to find kdesrc-build installation to build a configuration!"); + exit 1; + } +} if (grep /^frameworks$/, @chosenModules) { print $output <_readCommandLineOptionsAndSelectors($cmdlineOptions, \@selectors, $ctx, @argv); - my %ignoredSelectors; - @ignoredSelectors{@{$cmdlineGlobalOptions->{'ignore-modules'}}} = undef; + # Convert list to hash for lookup + my %ignoredSelectors = + map { $_, 1 } @{$cmdlineGlobalOptions->{'ignore-modules'}}; my @startProgramAndArgs = @{$cmdlineGlobalOptions->{'start-program'}}; delete @{$cmdlineGlobalOptions}{qw/ignore-modules start-program/}; @@ -413,8 +411,13 @@ sub generateModuleList # available. $ctx->setKDEDependenciesMetadataModuleNeeded(); $ctx->setKDEProjectsMetadataModuleNeeded(); - ksb::Updater::Git::verifyGitConfig(); - $self->_downloadKDEProjectMetadata(); + + if (!exists $ENV{HARNESS_ACTIVE}) { + # Running in a test harness, avoid downloading metadata which will be + # ignored in the test or making changes to git config + ksb::Updater::Git::verifyGitConfig(); + $self->_downloadKDEProjectMetadata(); + } # The user might only want metadata to update to allow for a later # --pretend run, check for that here. @@ -455,15 +458,40 @@ sub generateModuleList ksb::Module->setModuleSource('config'); } - # Check for ignored modules (post-expansion) - @modules = grep { ! exists $ignoredSelectors{$_->name()} } @modules; - # If modules were on the command line then they are effectively forced to # process unless overridden by command line options as well. If phases # *were* overridden on the command line, then no update pass is required # (all modules already have correct phases) @modules = _updateModulePhases(@modules) unless $commandLineModules; + # TODO: Verify this does anything still + my $metadataModule = $ctx->getKDEDependenciesMetadataModule(); + $ctx->addToIgnoreList($metadataModule->scm()->ignoredModules()); + + # Remove modules that are explicitly blanked out in their branch-group + # i.e. those modules where they *have* a branch-group, and it's set to + # be empty (""). + my $resolver = $ctx->moduleBranchGroupResolver(); + my $branchGroup = $ctx->effectiveBranchGroup(); + + @modules = grep { + my $branch = $_->isKDEProject() + ? $resolver->findModuleBranch($_->fullProjectPath(), $branchGroup) + : 1; # Just a placeholder truthy value + whisper ("Removing ", $_->fullProjectPath(), " due to branch-group") if (defined $branch and !$branch); + (!defined $branch or $branch); # This is the actual test + } (@modules); + + @modules = $self->_resolveModuleDependencies(@modules); + + # Filter --resume-foo options. This might be a second pass, but that should + # be OK since there's nothing different going on from the first pass (in + # resolveSelectorsIntoModules) in that event. + @modules = _applyModuleFilters($ctx, @modules); + + # Check for ignored modules (post-expansion) + @modules = grep { ! exists $ignoredSelectors{$_->name()} } @modules; + return @modules; } @@ -576,34 +604,9 @@ sub runAllModulePhases { my $self = shift; my $ctx = $self->context(); - my $metadataModule = $ctx->getKDEDependenciesMetadataModule(); my @modules = $self->modules(); - $ctx->addToIgnoreList($metadataModule->scm()->ignoredModules()); - - # Remove modules that are explicitly blanked out in their branch-group - # i.e. those modules where they *have* a branch-group, and it's set to - # be empty (""). - my $resolver = $ctx->moduleBranchGroupResolver(); - my $branchGroup = $ctx->effectiveBranchGroup(); - - @modules = grep { - my $branch = $_->isKDEProject() - ? $resolver->findModuleBranch($_->fullProjectPath(), $branchGroup) - : 1; # Just a placeholder truthy value - whisper ("Removing ", $_->fullProjectPath(), " due to branch-group") if (defined $branch and !$branch); - (!defined $branch or $branch); # This is the actual test - } (@modules); - - @modules = $self->_resolveModuleDependencies(@modules); - - # Filter --resume-foo options. This might be a second pass, but that should - # be OK since there's nothing different going on from the first pass (in - # resolveSelectorsIntoModules) in that event. - @modules = _applyModuleFilters($ctx, @modules); - if ($ctx->getOption('print-modules')) { - info (" * Module list", $metadataModule ? " in dependency order" : ''); for my $m (@modules) { say ((" " x ($m->getOption('#dependency-level', 'module') // 0)), "$m"); } @@ -1012,7 +1015,7 @@ sub _parseModuleSetOptions # filehandle - The I/O object to read from. Must handle _eof_ and _readline_ # methods (e.g. subclass). # -# deferredOptions - An out paramter: a hashref holding the options set by any +# deferredOptions - An out parameter: a hashref holding the options set by any # 'options' blocks read in by this function. Each key (identified by the name # of the 'options' block) will point to a hashref value holding the options to # apply. diff --git a/modules/ksb/BuildContext.pm b/modules/ksb/BuildContext.pm index 600ad58..ad0b90a 100644 --- a/modules/ksb/BuildContext.pm +++ b/modules/ksb/BuildContext.pm @@ -227,8 +227,6 @@ sub addToIgnoreList { my $self = shift; push @{$self->{ignore_list}}, @_; - - debug ("Set context ignore list to ", join(', ', @_)); } sub setupOperatingEnvironment @@ -261,7 +259,6 @@ sub setupOperatingEnvironment sub resetEnvironment { my $self = assert_isa(shift, 'ksb::BuildContext'); - $self->{env} = { }; } @@ -313,7 +310,7 @@ sub commitEnvironmentChanges # queued. Either way the current environment will be unmodified afterward. # # First parameter is the name of the environment variable to modify -# All remaining paramters are prepended to the current environment path, in +# All remaining parameters are prepended to the current environment path, in # the order given. (i.e. param1, param2, param3 -> # param1:param2:param3:existing) sub prependEnvironmentValue @@ -474,19 +471,31 @@ sub getLogDirFor } $logDir = $self->{logPaths}{$baseLogPath}; - return $logDir if pretending(); + super_mkdir($logDir); + + # global logs go to basedir directly + $logDir .= "/$module" unless $module->isa('ksb::BuildContext'); + + return $logDir; +} + +# Constructs the appropriate full path to a log file based on the given +# basename (including extensions). Use this instead of getLogDirFor when you +# actually intend to create a log, as this function will also adjust the +# 'latest' symlink properly. +sub getLogPathFor +{ + my ($self, $module, $path) = @_; - super_mkdir($logDir) unless -e $logDir; + my $baseLogPath = $module->getSubdirPath('log-dir'); + my $logDir = $self->getLogDirFor($module); - # No symlink munging or module-name-adding is needed for the default - # log dir. - return $logDir if $module->isa('ksb::BuildContext'); + # We create this here to avoid needless empty module directories everywhere + super_mkdir($logDir); - # Add a symlink to the latest run for this module. 'latest' itself is - # a directory under the default log directory that holds module - # symlinks, pointing to the last log directory run for that module. We - # do need to be careful of modules that have multiple directory names - # though (like extragear/foo). + # Add a symlink to the latest run for this module. 'latest' itself is + # a directory under the base log directory that holds symlinks mapping + # each module name to the specific log directory most recently used. my $latestPath = "$baseLogPath/latest"; @@ -496,22 +505,20 @@ sub getLogDirFor super_mkdir($latestPath); - my $symlinkTarget = "$logDir/$moduleName"; my $symlink = "$latestPath/$moduleName"; - if (-l $symlink and readlink($symlink) ne $symlinkTarget) + if (-l $symlink and readlink($symlink) ne $logDir) { unlink($symlink); - symlink($symlinkTarget, $symlink); + symlink($logDir, $symlink); } elsif(not -e $symlink) { # Create symlink initially if we've never done it before. - symlink($symlinkTarget, $symlink); + symlink($logDir, $symlink); } - super_mkdir($symlinkTarget); - return $symlinkTarget; + return "$logDir/$path"; } # Returns rc file in use. Call loadRcFile first. diff --git a/modules/ksb/BuildSystem.pm b/modules/ksb/BuildSystem.pm index b52c87b..87988e8 100644 --- a/modules/ksb/BuildSystem.pm +++ b/modules/ksb/BuildSystem.pm @@ -144,7 +144,7 @@ sub buildInternal subdirs => [ split(' ', $self->module()->getOption("checkout-only")) ], - }) == 0; + })->{was_successful}; } # Return value style: boolean @@ -191,7 +191,7 @@ sub installInternal message => 'Installing..', 'prefix-options' => [@cmdPrefix], subdirs => [ split(' ', $module->getOption("checkout-only")) ], - }) == 0; + })->{was_successful}; } # Used to uninstall a previously installed module. @@ -208,7 +208,7 @@ sub uninstallInternal message => "Uninstalling g[$module]", 'prefix-options' => [@cmdPrefix], subdirs => [ split(' ', $module->getOption("checkout-only")) ], - }) == 0; + })->{was_successful}; } # Subroutine to clean the build system for the given module. Works by @@ -319,7 +319,10 @@ sub createBuildSystem # The first argument should be the ksb::Module object to be made. # The second argument should be the reference to the hash described above. # -# Returns 0 on success, non-zero on failure (shell script style) +# Returns a hashref: +# { +# was_successful => $bool, (if successful) +# } sub safe_make (@) { my ($self, $optsRef) = @_; @@ -343,7 +346,7 @@ sub safe_make (@) if (!$buildCommand) { $buildCommand = $userCommand || $self->buildCommands(); error (" r[b[*] Unable to find the g[$buildCommand] executable!"); - return 1; + return { was_successful => 0 }; } # Make it prettier if pretending (Remove leading directories). @@ -404,11 +407,10 @@ sub safe_make (@) p_chdir ($builddir); - my $result = $self->_runBuildCommand($buildMessage, $logname, \@args); - return $result if $result; + return $self->_runBuildCommand($buildMessage, $logname, \@args); }; - return 0; + return { was_successful => 1 }; } # Subroutine to run make and process the build process output in order to @@ -422,12 +424,13 @@ sub safe_make (@) # directory). # Third parameter is a reference to an array with the command and its # arguments. i.e. ['command', 'arg1', 'arg2'] -# The return value is the shell return code, so 0 is success, and non-zero -# is failure. +# +# The return value is a hashref as defined by safe_make sub _runBuildCommand { my ($self, $message, $filename, $argRef) = @_; my $module = $self->module(); + my $resultRef = { was_successful => 0 }; my $ctx = $module->buildContext(); # There are situations when we don't want progress output: @@ -436,7 +439,8 @@ sub _runBuildCommand if (! -t STDERR || debugging()) { note("\t$message"); - return log_command($module, $filename, $argRef); + $resultRef->{was_successful} = (0 == log_command($module, $filename, $argRef)); + return $resultRef; } my $time = time; @@ -445,12 +449,13 @@ sub _runBuildCommand $statusViewer->setStatus("\t$message"); $statusViewer->update(); + # TODO More details + my $warnings = 0; + # w00t. Check out the closure! Maks would be so proud. my $log_command_callback = sub { my $input = shift; - if (not defined $input) { - return; - } + return if not defined $input; my ($percentage) = ($input =~ /^\[\s*([0-9]+)%]/); if ($percentage) { @@ -465,18 +470,31 @@ sub _runBuildCommand $statusViewer->setProgress($x); } } + + $warnings++ if ($input =~ /warning: /); }; - my $result = log_command($module, $filename, $argRef, { + $resultRef->{was_successful} = + (0 == log_command($module, $filename, $argRef, { callback => $log_command_callback - }); + })); + $resultRef->{warnings} = $warnings; # Cleanup TTY output. $time = prettify_seconds(time - $time); - my $status = $result == 0 ? "g[b[succeeded]" : "r[b[failed]"; + my $status = $resultRef->{was_successful} ? "g[b[succeeded]" : "r[b[failed]"; $statusViewer->releaseTTY("\t$message $status (after $time)\n"); - return $result; + if ($warnings) { + my $count = ($warnings < 3 ) ? 1 : + ($warnings < 10 ) ? 2 : + ($warnings < 30 ) ? 3 : 4; + my $msg = sprintf("%s b[y[$warnings] %s", '-' x $count, '-' x $count); + note ("\tNote: $msg compile warnings"); + $self->{module}->setPersistentOption('last-compile-warnings', $warnings); + } + + return $resultRef; } 1; diff --git a/modules/ksb/BuildSystem/KDE4.pm b/modules/ksb/BuildSystem/KDE4.pm index a491055..08fd63a 100644 --- a/modules/ksb/BuildSystem/KDE4.pm +++ b/modules/ksb/BuildSystem/KDE4.pm @@ -32,12 +32,19 @@ sub prepareModuleBuildEnvironment { my ($self, $ctx, $module, $prefix) = @_; - $ctx->prependEnvironmentValue('CMAKE_PREFIX_PATH', $prefix); - $ctx->prependEnvironmentValue('XDG_DATA_DIRS', "$prefix/share"); + # Avoid moving /usr up in env vars + if ($prefix ne '/usr') { + # Find the normal CMake "config" mode files for find_package() + $ctx->prependEnvironmentValue('CMAKE_PREFIX_PATH', $prefix); + # Try to ensure that older "module" mode find_package() calls also point to right directory + $ctx->prependEnvironmentValue('CMAKE_MODULE_PATH', "$prefix/lib64/cmake:$prefix/lib/cmake"); + $ctx->prependEnvironmentValue('XDG_DATA_DIRS', "$prefix/share"); + } my $qtdir = $module->getOption('qtdir'); if ($qtdir && $qtdir ne $prefix) { # Ensure we can find Qt5's own CMake modules + $ctx->prependEnvironmentValue('CMAKE_PREFIX_PATH', $qtdir); $ctx->prependEnvironmentValue('CMAKE_MODULE_PATH', "$qtdir/lib/cmake"); } } @@ -119,7 +126,7 @@ sub installInternal message => 'Installing..', 'prefix-options' => [@cmdPrefix], subdirs => [ split(' ', $module->getOption("checkout-only")) ], - }) == 0; + })->{was_successful}; } sub configureInternal @@ -172,9 +179,12 @@ sub _safe_run_cmake push @commands, "-DCMAKE_INSTALL_PREFIX=$prefix"; - # Add custom Qt to the prefix + # Add custom Qt to the prefix (but don't overwrite a user-set prefix) my $qtdir = $module->getOption('qtdir'); - if ($qtdir && $qtdir ne $prefix) { + if ($qtdir && $qtdir ne $prefix && + !grep { /^\s*-DCMAKE_PREFIX_PATH/ } (@commands) + ) + { push @commands, "-DCMAKE_PREFIX_PATH=$qtdir"; } diff --git a/modules/ksb/Module.pm b/modules/ksb/Module.pm index b749af4..695cc55 100644 --- a/modules/ksb/Module.pm +++ b/modules/ksb/Module.pm @@ -657,14 +657,17 @@ sub setupEnvironment # Add global set-envs and context $self->buildContext()->applyUserEnvironment(); - my @pkg_config_dirs = ("$kdedir/lib/pkgconfig"); - $ctx->prependEnvironmentValue('PKG_CONFIG_PATH', @pkg_config_dirs); + # Avoid moving /usr up in env vars + if ($kdedir ne '/usr') { + my @pkg_config_dirs = ("$kdedir/lib/pkgconfig"); + $ctx->prependEnvironmentValue('PKG_CONFIG_PATH', @pkg_config_dirs); - my @ld_dirs = ("$kdedir/lib", $self->getOption('libpath')); - $ctx->prependEnvironmentValue('LD_LIBRARY_PATH', @ld_dirs); + my @ld_dirs = ("$kdedir/lib", $self->getOption('libpath')); + $ctx->prependEnvironmentValue('LD_LIBRARY_PATH', @ld_dirs); - my @path = ("$kdedir/bin", $self->getOption('binpath')); - $ctx->prependEnvironmentValue('PATH', @path); + my @path = ("$kdedir/bin", $self->getOption('binpath')); + $ctx->prependEnvironmentValue('PATH', @path); + } # Build system's environment injection my $buildSystem = $self->buildSystem(); @@ -675,16 +678,24 @@ sub setupEnvironment } # Returns the path to the log directory used during this run for this -# ksb::Module. -# -# In addition it handles the 'latest' symlink to allow for ease of access -# to the log directory afterwards. +# ksb::Module, based on an autogenerated unique id. The id doesn't change +# once generated within a single run of the script. sub getLogDir { my ($self) = @_; return $self->buildContext()->getLogDirFor($self); } +# Returns a full path that can be open()'d to write a log +# file, based on the given basename (with extension). +# Updates the 'latest' symlink as well, unlike getLogDir +# Use when you know you're going to create a new log +sub getLogPath +{ + my ($self, $path) = @_; + return $self->buildContext()->getLogPathFor($self, $path); +} + sub toString { my $self = shift; diff --git a/modules/ksb/Updater/KDEProjectMetadata.pm b/modules/ksb/Updater/KDEProjectMetadata.pm index c0489fc..ddeb9ad 100644 --- a/modules/ksb/Updater/KDEProjectMetadata.pm +++ b/modules/ksb/Updater/KDEProjectMetadata.pm @@ -49,7 +49,8 @@ sub logicalModuleGroups my $self = shift; my $path = $self->module()->fullpath('source') . "/logical-module-structure"; - my $fh = pretend_open($path) or + # The {} is an empty JSON obj to support pretend mode + my $fh = pretend_open($path, '{}') or croak_internal("Unable to read logical module structure: $!"); my ($json_hashref, $e) = do { @@ -61,7 +62,7 @@ sub logicalModuleGroups ($json, $@); # Implicit return }; - croak_runtime ("Unable to load module group data! :(\n\t$e") if $e; + croak_runtime ("Unable to load module group data from $path! :(\n\t$e") if $e; return $json_hashref; } diff --git a/modules/ksb/Util.pm b/modules/ksb/Util.pm index 48d84ce..ee5f034 100644 --- a/modules/ksb/Util.pm +++ b/modules/ksb/Util.pm @@ -447,6 +447,9 @@ sub log_command return 0; } + # Do this before we fork so we can see errors + my $logpath = $module->getLogPath("$filename.log"); + # Fork a child, with its stdout connected to CHILD. my $pid = open(CHILD, '-|'); if ($pid) @@ -486,13 +489,6 @@ sub log_command # Apply altered environment variables. $module->buildContext()->commitEnvironmentChanges(); - my $logdir = $module->getLogDir(); - if (!$logdir || ! -e $logdir) - { - # Error creating directory for some reason. - error ("\tLogging to std out due to failure creating log dir."); - } - $SIG{PIPE} = "IGNORE"; $SIG{INT} = sub { close (STDOUT); # This should be a pipe @@ -506,13 +502,15 @@ sub log_command open (STDIN, '<', "/dev/null") unless exists $ENV{'KDESRC_BUILD_USE_TTY'}; if ($callbackRef || debugging()) { - open (STDOUT, "|tee $logdir/$filename.log") or do { + open (STDOUT, "|tee $logpath") or do { error ("Error opening pipe to tee command."); # Don't abort, hopefully STDOUT still works. }; } else { - open (STDOUT, '>', "$logdir/$filename.log"); + open (STDOUT, '>', $logpath) or do { + error ("Error $! opening log to $logpath!"); + }; } # Make sure we log everything. @@ -628,6 +626,7 @@ sub download_file # # Parameters: # filename - Path to the file to open. +# default - String to use if the file doesn't exist in pretend mode # # Returns: # filehandle on success (supports readline() and eof()), can return boolean @@ -636,11 +635,11 @@ sub download_file sub pretend_open { my $path = shift; + my $defaultText = shift // ''; my $fh; if (pretending() && ! -e $path) { - my $simulatedFile = ''; - open $fh, '<', \$simulatedFile or return; + open $fh, '<', \$defaultText or return; } else { open $fh, '<', $path or return; @@ -667,7 +666,7 @@ sub unique_items } # Subroutine to delete a directory and all files and subdirectories within. -# Does nothing in pretend mode. An analogue to "rm -rf" from Linux. +# Does nothing in pretend mode. An analog to "rm -rf" from Linux. # Requires File::Find module. # # First parameter: Path to delete diff --git a/modules/ksb/l10nSystem.pm b/modules/ksb/l10nSystem.pm index 4f7e86e..f2a0ea1 100644 --- a/modules/ksb/l10nSystem.pm +++ b/modules/ksb/l10nSystem.pm @@ -111,14 +111,12 @@ sub buildInternal my $self = assert_isa(shift, 'ksb::l10nSystem'); my $builddir = $self->module()->fullpath('build'); my @langs = $self->languages(); - my $result = 0; - - $result = ($self->safe_make({ + my $result = ($self->safe_make({ target => undef, message => "Building localization for language...", logbase => "build", subdirs => \@langs, - }) == 0) || $result; + }))->{was_successful}; return $result; } diff --git a/t/bug-394497-ignore-dep-module.t b/t/bug-394497-ignore-dep-module.t new file mode 100644 index 0000000..f67d7f5 --- /dev/null +++ b/t/bug-394497-ignore-dep-module.t @@ -0,0 +1,51 @@ +use 5.014; +use strict; +use warnings; + +# Verify that --ignore-modules works for modules that would be included with +# --include-dependencies in effect. +# See bug 394497 -- https://bugs.kde.org/show_bug.cgi?id=394497 + +use Test::More; + +use ksb::Application; +use ksb::Module; + +# Redefine ksb::Application::_resolveModuleDependencies to avoid requiring metadata +# module. +package ksb::Application { + no warnings 'redefine'; + + sub _resolveModuleDependencies { + my ($self, @modules) = @_; + # simulate effect of --include-dependencies, using ksb::Application's + # built-in module-name to ksb::Module resolver. + my $newModule = $self->{module_factory}->('setmod2'); + splice @modules, 1, 0, $newModule; + return @modules; + } +}; + +my @args = qw(--pretend --rc-file t/data/sample-rc/kdesrc-buildrc --include-dependencies setmod1 setmod3); + +{ + my $app = ksb::Application->new(@args); + my @moduleList = @{$app->{modules}}; + + is (scalar @moduleList, 3, 'Right number of modules (include-dependencies)'); + is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1'); + is ($moduleList[1]->name(), 'setmod2', 'mod list[1] == setmod2'); + is ($moduleList[2]->name(), 'setmod3', 'mod list[2] == setmod3'); +} + +{ + push @args, '--ignore-modules', 'setmod2'; + my $app = ksb::Application->new(@args); + my @moduleList = @{$app->{modules}}; + + is (scalar @moduleList, 2, 'Right number of modules (include-dependencies+ignore-modules)'); + is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1'); + is ($moduleList[1]->name(), 'setmod3', 'mod list[1] == setmod3'); +} + +done_testing(); diff --git a/t/bug-395627-keep-cmake-prefix.t b/t/bug-395627-keep-cmake-prefix.t new file mode 100644 index 0000000..4e3a1b3 --- /dev/null +++ b/t/bug-395627-keep-cmake-prefix.t @@ -0,0 +1,78 @@ +use 5.014; +use strict; +use warnings; + +# Verify that a user-set CMAKE_PREFIX_PATH is not removed, even if we supply +# "magic" of our own +# See bug 395627 -- https://bugs.kde.org/show_bug.cgi?id=395627 + +my @savedCommand; +my $log_called = 0; + +# Redefine log_command to capture whether it was properly called. This is all +# very order-dependent, we need to load ksb::Util before kdesrc-build itself +# does to install the new subroutine before it's copied over into the other +# package symbol tables. +BEGIN { + use ksb::Util; + + no strict 'refs'; + no warnings 'redefine'; + + *ksb::Util::log_command = sub { + $log_called = 1; + + my ($module, $filename, $argRef, $optionsRef) = @_; + my @command = @{$argRef}; + @savedCommand = @command; + return 0; # success + }; +} + +use Test::More; + +use ksb::Application; +use ksb::Module; + +my @args = qw(--pretend --rc-file t/data/bug-395627/kdesrc-buildrc); + +{ + my $app = ksb::Application->new(@args); + my @moduleList = @{$app->{modules}}; + + is (scalar @moduleList, 6, 'Right number of modules'); + isa_ok ($moduleList[0]->buildSystem(), 'ksb::BuildSystem::KDE4'); + + my $result; + my @prefixes; + my $prefix; + + # This requires log_command to be overridden above + $result = $moduleList[0]->setupBuildSystem(); + is ($log_called, 1, 'Overridden log_command was called'); + ok ($result, 'Setup build system for auto-set prefix path'); + + # We should expect an auto-set -DCMAKE_PREFIX_PATH passed to cmake somewhere + ($prefix) = grep { /-DCMAKE_PREFIX_PATH/ } @savedCommand; + is ($prefix, '-DCMAKE_PREFIX_PATH=/tmp/qt5', 'Prefix path set to custom Qt prefix'); + + $result = $moduleList[2]->setupBuildSystem(); + ok ($result, 'Setup build system for manual-set prefix path'); + + (@prefixes) = grep { /-DCMAKE_PREFIX_PATH/ } @savedCommand; + is (scalar @prefixes, 1, 'Only one set prefix path in manual mode'); + if (@prefixes) { + is ($prefixes[0], '-DCMAKE_PREFIX_PATH=FOO', 'Manual-set prefix path is as set by user'); + } + + $result = $moduleList[4]->setupBuildSystem(); + ok ($result, 'Setup build system for manual-set prefix path'); + + (@prefixes) = grep { /-DCMAKE_PREFIX_PATH/ } @savedCommand; + is (scalar @prefixes, 1, 'Only one set prefix path in manual mode'); + if (@prefixes) { + is ($prefixes[0], '-DCMAKE_PREFIX_PATH:PATH=BAR', 'Manual-set prefix path is as set by user'); + } +} + +done_testing(); diff --git a/t/data/bug-395627/kdesrc-buildrc b/t/data/bug-395627/kdesrc-buildrc new file mode 100644 index 0000000..ad9891c --- /dev/null +++ b/t/data/bug-395627/kdesrc-buildrc @@ -0,0 +1,26 @@ +global + source-dir /tmp + qtdir /tmp/qt5 + git-repository-base fake git://localhost/git-set/ + override-build-system KDE # Use CMake everywhere w/out source probing +end global + +module-set test + repository fake + use-modules sample1 sample2 + # Should have auto-set CMAKE_PREFIX_PATH +end module-set + +module-set test2-set + repository fake + use-modules sample3 sample4 + cmake-options -DCMAKE_PREFIX_PATH=FOO + # Should not auto-set CMAKE_PREFIX_PATH since it's already set +end module-set + +module-set test3-set + repository fake + use-modules sample5 sample6 + cmake-options -DCMAKE_PREFIX_PATH:PATH=BAR + # Uses a slightly different syntax, should still be retained +end module-set