[sdk/kdesrc-build/make_it_mojo] /: Merge remote-tracking branch 'origin/master' into make_it_mojo
Michael Pyne
null at kde.org
Sun Feb 14 02:20:58 GMT 2021
Git commit 136fdcdf3c918f94a334e9ca494bb8a3d07aead2 by Michael Pyne.
Committed on 14/02/2021 at 02:18.
Pushed by mpyne into branch 'make_it_mojo'.
Merge remote-tracking branch 'origin/master' into make_it_mojo
Still passes revised test suite.
Conflicts:
modules/ksb/Application.pm
modules/ksb/BuildSystem/CMake.pm
M +1 -1 README.md
M +67 -11 doc/index.docbook
M +1 -1 doc/man-kdesrc-build.1.docbook
M +17 -11 modules/ksb/Application.pm
M +3 -1 modules/ksb/BuildContext.pm
R +35 -2 modules/ksb/BuildSystem/CMake.pm
M +141 -7 modules/ksb/FirstRun.pm
M +44 -3 modules/ksb/Module.pm
M +76 -0 t/smoke/issue-64-cmdline-opt-override.t
M +6 -5 t/smoke/read-module-options.t
M +18 -0 t/unit/build-environment/platform-env-prepend.t
M +5 -4 vim/syntax/kdesrc-buildrc.vim
https://invent.kde.org/sdk/kdesrc-build/commit/136fdcdf3c918f94a334e9ca494bb8a3d07aead2
diff --cc modules/ksb/Application.pm
index 41ae4c4,e0dc14f..f7563bc
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@@ -29,10 -29,9 +29,11 @@@ use ksb::DependencyResolver 0.20
use ksb::Updater::Git;
use ksb::Version qw(scriptVersion);
+use Mojo::IOLoop;
+use Mojo::Promise;
+
+use Fcntl; # For sysopen
+ use Scalar::Util qw(blessed);
use List::Util qw(first min);
use File::Basename; # basename, dirname
use File::Glob ':glob';
@@@ -397,247 -370,116 +398,247 @@@ sub _findMissingModule
return @missingModules;
}
-sub _yieldModuleDependencyTreeEntry
+# Method: _handleEarlyOptions
+#
+# Uses the user-requested options (as returned by
+# readCommandLineOptionsAndSelectors) and handles any options that can be
+# handled without launching the backend or reading the configuration file, and
+# which would cause the script to exit, such as --help.
+#
+# This function may exit entirely for some options, and since the rc-file has
+# not been read yet, does not handle all possible cases where an early exit is
+# required. For that, see handleQueryOptions.
+#
+# Phase:
+# initialization - Do not call <finish> from this function.
+#
+# Parameters:
+# optsAndSelectors - As from readCommandLineOptionsAndSelectors
+#
+# Returns:
+# There is no return value. The function may not return at all, and exit instead.
+sub _handleEarlyOptions
{
- my ($nodeInfo, $module, $context) = @_;
+ my $optsAndSelectors = shift;
- my $depth = $nodeInfo->{depth};
- my $index = $nodeInfo->{idx};
- my $count = $nodeInfo->{count};
- my $build = $nodeInfo->{build};
- my $currentItem = $nodeInfo->{currentItem};
- my $currentBranch = $nodeInfo->{currentBranch};
- my $parentItem = $nodeInfo->{parentItem};
- my $parentBranch = $nodeInfo->{parentBranch};
+ croak_internal("No options and selectors passed")
+ unless $optsAndSelectors;
- my $buildStatus = $build ? 'built' : 'not built';
- my $statusInfo = $currentBranch ? "($buildStatus: $currentBranch)" : "($buildStatus)";
+ my $version = "kdesrc-build " . scriptVersion();
+ my $author = <<DONE;
+$version was written (mostly) by:
+ Michael Pyne <mpyne\@kde.org>
- my $connectorStack = $context->{stack};
+Many people have contributed code, bugfixes, and documentation.
+Please report bugs using the KDE Bugzilla, at https://bugs.kde.org/
+DONE
- my $prefix = pop(@$connectorStack);
+ my %optionHandlers = (
+ 'show-info' => sub { say "$version\nOS: ", ksb::OSSupport->new->vendorID(); },
+ version => sub { say $version },
+ author => sub { say $author },
+ help => sub { _showHelpMessage() },
+ );
- while($context->{depth} > $depth) {
- $prefix = pop(@$connectorStack);
- --($context->{depth});
+ my $globalOpts = $optsAndSelectors->{options}->{global};
+ foreach my $early_opt (keys %optionHandlers) {
+ if (exists $globalOpts->{$early_opt}) {
+ $optionHandlers{$early_opt}->();
+ exit;
+ }
}
+}
- push(@$connectorStack, $prefix);
+# Method: handleQueryOptions
+#
+# Uses the user-requested options (as held in the build context) and handles
+# any options that require the configuration file to be read (in particular
+# --query and potentially other debug-flags options), before the backend is
+# launched. Requires that selectors have been fully converted into modules.
+#
+# This function may exit entirely for some options!
+#
+# Phase:
+# initialization - Do not call <finish> from this function.
+#
+# Parameters:
+# None.
+#
+# Returns:
+# There is no return value. The function may not return at all, and exit instead.
+sub handleQueryOptions
+{
+ my $self = assert_isa(shift, 'ksb::Application');
+ my $ctx = $self->context();
- my $connector;
+ my %optionHandlers = (
+ query => sub {
+ my $queryMode = shift;
+ my @modules = @{$self->{modules}};
+
+ # Default to ->getOption as query method.
+ # $_[0] is short name for first param.
+ my $query = sub { $_[0]->getOption($queryMode) };
+ $query = sub { $_[0]->fullpath('source') } if $queryMode eq 'source-dir';
+ $query = sub { $_[0]->fullpath('build') } if $queryMode eq 'build-dir';
+ $query = sub { $_[0]->installationPath() } if $queryMode eq 'install-dir';
+ $query = sub { $_[0]->fullProjectPath() } if $queryMode eq 'project-path';
+ $query = sub { ($_[0]->scm()->_determinePreferredCheckoutSource())[0] // '' }
+ if $queryMode eq 'branch';
+
+ if (@modules == 1) {
+ # No leading module name, just the value
+ say $query->($modules[0]);
+ }
+ else {
+ for my $m (@modules) {
+ say "$m: ", $query->($m);
+ }
+ }
+ },
+ );
- if ($depth == 0) {
- $connector = $prefix . ' ── ';
- push(@$connectorStack, $prefix . (' ' x 4));
- }
- else {
- $connector = $prefix . ($index == $count ? '└── ': '├── ');
- push(@$connectorStack, $prefix . ($index == $count ? ' ' x 4: '│ '));
+ foreach my $query_opt (keys %optionHandlers) {
+ if (my $opt_value = $ctx->getOption($query_opt, 'module')) {
+ $optionHandlers{$query_opt}->($opt_value);
+ exit;
+ }
}
-
- $context->{depth} = $depth + 1;
- $context->{report}($connector . $currentItem . ' ' . $statusInfo);
}
-# Generates the build context and module list based on the command line options
-# and module selectors provided, resolves dependencies on those modules if needed,
-# filters out ignored or skipped modules, and sets up the module factory.
+# Method: _applyBuildContextPhasesFromCmdline
#
-# After this function is called all module set selectors will have been
-# expanded, and we will have downloaded kde-projects metadata.
+# Uses the user-requested options (as returned by
+# readCommandLineOptionsAndSelectors) to update the build context and
+# self-options as appropriate, including functions such as updating the
+# run-mode. Options that might cause early exit are not handled, see
+# _handleEarlyOptions for those.
#
-# Returns: a hash containing the following entries:
+# Since the rc-file has not been read yet, this does not handle all possible
+# cases where an early exit is required.
#
-# - selectedModules: the selected modules to build
-# - dependencyInfo: reference to dependency info object as created by ksb::DependencyResolver
-# - build: whether or not to actually perform a build action
+# Phase:
+# initialization - Do not call <finish> from this function.
#
-sub generateModuleList
+# Parameters:
+# ctx - <BuildContext> to hold the global build state.
+# optsAndSelectors - As from readCommandLineOptionsAndSelectors
+#
+# Returns:
+# There is no return value.
+sub _applyBuildContextPhasesFromCmdline
{
- my $self = shift;
- my @argv = @_;
+ my ($self, $ctx, $optsAndSelectors) = @_;
- # Note: Don't change the order around unless you're sure of what you're
- # doing.
+ my $phases = $ctx->phases();
- my $ctx = $self->context();
- my $cmdlineOptions = { global => { }, };
- my $cmdlineGlobalOptions = $cmdlineOptions->{global};
- my $deferredOptions = { }; # 'options' blocks
+ my %optionHandlers = (
+ 'no-src' => sub {
+ $phases->filterOutPhase('update');
+ },
+ 'no-install' => sub {
+ $phases->filterOutPhase('install');
+ },
+ # run-tests is handled as a 'flag' and is only cmdline accessible as
+ # --run-tests or --no-run-tests, both resulting in a value to run-tests hash
+ 'run-tests' => sub {
+ ($_[0] // 1) ? $phases->addPhase ('test')
+ : $phases->filterOutPhase('test');
+ },
+ 'no-build' => sub {
+ $phases->filterOutPhase('build');
+ },
+ install => sub {
+ $phases->phases('install');
+ },
+ uninstall => sub {
+ $phases->phases('uninstall');
+ },
+ # Mostly equivalent to the above
+ 'src-only' => sub {
+ $phases->phases('update');
+ },
+ 'build-only' => sub {
+ $phases->phases('build');
+ },
+ resume => sub {
+ $phases->filterOutPhase('update'); # Implied --no-src
+ },
+ );
- # Process --help, --install, etc. first.
- my @selectors;
- $self->_readCommandLineOptionsAndSelectors($cmdlineOptions, \@selectors,
- $ctx, @argv);
+ while (my ($opt, $value) = each %{$optsAndSelectors->{options}->{global}}) {
+ $optionHandlers{$opt}->($value) if exists $optionHandlers{$opt};
+ }
+}
- # Ensure some critical Perl modules are available so that the user isn't surprised
- # later with a Perl exception
- if(my @missingModuleDescriptions = _findMissingModules()) {
- say <<EOF;
-kdesrc-build requires some minimal support to operate, including support
-from the Perl runtime that kdesrc-build is built upon.
+# This subroutine creates the ksb::BuildContext using the provided cmdline
+# options/selectors and reads the config file and persistent options based on
+# those cmdline options.
+#
+# After this function completes the build context and module resolver are ready
+# for operations, but no module sets have been expanded and KDE project
+# metadata has not been loaded. No changes are made to the passed-in
+# options/selectors except to remove flags which do not apply to modules (like
+# --run).
+#
+# See also: establishContext, which is probably what you actually want.
+#
+# Exceptions are possible (e.g. for malformed rc-files)
+sub createBuildContextWithoutMetadata
+{
+ my ($self, $ctx, $optsAndSelectors) = @_;
-Some mandatory Perl modules are missing, and kdesrc-build cannot operate
-without them. Please ensure these modules are installed and available to Perl:
-EOF
- say "\t$_" foreach @missingModuleDescriptions;
+ my $cmdlineOptions = $optsAndSelectors->{options};
+ my $cmdlineGlobalOptions = $cmdlineOptions->{global};
- say "\nkdesrc-build can do this for you on many distros:";
- say "Run 'kdesrc-build --initial-setup'";
+ # Setup module resolver
+ my $moduleResolver
+ = $self->{module_resolver}
+ = ksb::ModuleResolver->new($ctx);
+ $moduleResolver->setCmdlineOptions($cmdlineOptions);
+ $moduleResolver->setIgnoredSelectors($cmdlineGlobalOptions->{'ignore-modules'});
- # TODO: Built-in mapping to popular distro package names??
- exit 1;
+ # rc-file needs special handling.
+ if (my $rcFile = ($cmdlineGlobalOptions->{'rc-file'} // '')) {
+ $ctx->setRcFile($rcFile);
}
- # _readConfigurationOptions will add pending global opts to ctx while
- # ensuring returned modules/sets have any such options stripped out. It
- # will also add module-specific options to any returned modules/sets. This
- # is done by adjusting the moduleResolver.
- _readConfigurationOptions($ctx, $moduleResolver);
-
- $ctx->loadPersistentOptions();
-
- # Convert list to hash for lookup
- my %ignoredSelectors =
- map { $_, 1 } @{$cmdlineGlobalOptions->{'ignore-modules'}};
+ # Set aside debug-related and other short-circuit cmdline options
+ # for kdesrc-build CLI driver to handle
+ my @debugFlags = qw(dependency-tree list-build print-modules);
+ $self->{debugFlags} = {
+ map { ($_, 1) } # turns list of matches into list of key/value pairs for hash
+ grep { defined $cmdlineGlobalOptions->{$_} }
+ (@debugFlags)
+ };
- my @startProgramAndArgs = @{$cmdlineGlobalOptions->{'start-program'}};
+ # These options are only used for cmdline handling (and in fact
+ # ksb::BuildContext will complain if we pass them) so delete them now.
delete @{$cmdlineGlobalOptions}{qw/ignore-modules start-program/};
- # rc-file needs special handling.
- if (exists $cmdlineGlobalOptions->{'rc-file'} && $cmdlineGlobalOptions->{'rc-file'}) {
- $ctx->setRcFile($cmdlineGlobalOptions->{'rc-file'});
- }
+ # Everything else in cmdlineOptions should be OK to apply directly as a
+ # module or context option.
+ $ctx->setOption(%{$cmdlineGlobalOptions});
+
- # disable async if only running a single phase.
- $cmdlineGlobalOptions->{async} = 0 if (scalar $ctx->phases()->phases() == 1);
++ # _readConfigurationOptions will add pending global opts to ctx while
++ # ensuring returned modules/sets have any such options stripped out. It
++ # will also add module-specific options to any returned modules/sets. This
++ # is done by adjusting the moduleResolver.
++ _readConfigurationOptions($ctx, $moduleResolver);
+
- my $fh = $ctx->loadRcFile();
+ $ctx->loadPersistentOptions();
+}
+
+# Returns a list of selectors that should be added to the overall selector
+# list, based on --rebuild-failures and --resume statements on the cmdline.
+# Requires the build context to be setup with persistent options loaded.
+sub getResumeSelectorsFromCmdline
+{
+ my ($self, $ctx, $optsAndSelectors) = @_;
+
+ my @selectors;
+ my $cmdlineGlobalOptions = $optsAndSelectors->{options}->{global};
if (exists $cmdlineGlobalOptions->{'resume'}) {
my $moduleList = $ctx->getPersistentOption('global', 'resume-list');
@@@ -1317,10 -1225,7 +1318,11 @@@ sub _parseModuleSetOption
sub _readConfigurationOptions
{
my $ctx = assert_isa(shift, 'ksb::BuildContext');
- my ($fh, $cmdlineGlobalOptions, $deferredOptionsRef) = @_;
+ my $moduleResolver = assert_isa(shift, 'ksb::ModuleResolver');
+
+ my $fh = $ctx->loadRcFile();
++ my $cmdlineGlobalOptions = $moduleResolver->{cmdlineOptions}->{global};
+ my $deferredOptionsRef = { };
my @module_list;
my $rcfile = $ctx->rcFile();
my ($option, %readModules);
diff --cc modules/ksb/BuildSystem/CMake.pm
index f6cb42c,188fa2d..b5c424f
--- a/modules/ksb/BuildSystem/CMake.pm
+++ b/modules/ksb/BuildSystem/CMake.pm
@@@ -326,11 -359,27 +344,23 @@@ sub installInterna
sub configureInternal
{
- my $self = assert_isa(shift, 'ksb::BuildSystem::KDE4');
+ my $self = assert_isa(shift, 'ksb::BuildSystem::CMake');
+ my $module = $self->module();
# Use cmake to create the build directory (sh script return value
# semantics).
- return ($self->_safe_run_cmake() == 0);
- if ($self->_safe_run_cmake())
- {
- error ("\tUnable to configure r[$module] with CMake!");
- return 0;
- }
++ return 0 if ($self->_safe_run_cmake());
+
+ # handle the linking of compile_commands.json back to source directory if wanted
+ # allows stuff like clangd to function out of the box
+ if ($module->getOption('compile-commands-linking')) {
+ # symlink itself will keep existing files untouched!
+ my $builddir = $module->fullpath('build');
+ my $srcdir = $module->fullpath('source');
+ symlink("$builddir/compile_commands.json", "$srcdir/compile_commands.json") if -e "$builddir/compile_commands.json";
+ }
+
+ return 1;
}
# Return value style: boolean
diff --cc t/smoke/issue-64-cmdline-opt-override.t
index 0000000,35450b6..4dbf193
mode 000000,100644..100644
--- a/t/smoke/issue-64-cmdline-opt-override.t
+++ b/t/smoke/issue-64-cmdline-opt-override.t
@@@ -1,0 -1,77 +1,76 @@@
-use 5.014;
-use strict;
++use v5.22;
+ use warnings;
+
+ # Global options in the rc-file can be overridden on the command line just by
+ # using their option name in a cmdline argument (as long as the argument isn't
+ # already allocated, that is).
+ #
+ # This ensures that global options overridden in this fashion are applied
+ # before the rc-file is read.
+ #
+ # See issue #64
+
+ use Test::More;
+
+ use ksb::Application;
+ use ksb::Module;
+
+ # The issue used num-cores as an example, but should work just as well
+ # with make-options
+ my @args = qw(--pretend --rc-file t/data/sample-rc/kdesrc-buildrc);
+ {
- my $app = ksb::Application->new(@args);
- my @moduleList = @{$app->{modules}};
++ my $app = ksb::Application::newFromCmdline(@args)->setHeadless;
++ my @moduleList = $app->modules();
+
+ is ($app->context()->getOption('num-cores'), 8, 'No cmdline option leaves num-cores value alone');
+
+ is (scalar @moduleList, 4, 'Right number of modules');
+ is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1');
+ is ($moduleList[0]->getOption('make-options'), '-j4', 'make-options base value proper pre-override');
+
+ is ($moduleList[3]->name(), 'module2', 'mod list[3] == module2');
+ is ($moduleList[3]->getOption('make-options'), '-j 8', 'module-override make-options proper pre-override');
+ }
+
+ # We can't seem to assign -j3 as Getopt::Long will try to understand the option
+ # and fail
+ push @args, '--make-options', 'j3';
+
+ {
- my $app = ksb::Application->new(@args);
- my @moduleList = @{$app->{modules}};
++ my $app = ksb::Application::newFromCmdline(@args)->setHeadless;
++ my @moduleList = $app->modules();
+
+ is ($app->context()->getOption('num-cores'), 8, 'No cmdline option leaves num-cores value alone');
+
+ is (scalar @moduleList, 4, 'Right number of modules');
+ is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1');
+ is ($moduleList[0]->getOption('make-options'), 'j3', 'make-options base value proper post-override');
+
+ # Policy discussion: Should command line options override *all* instances
+ # of an option in kdesrc-buildrc? Historically the answer has deliberately
+ # been yes, so that's the behavior we enforce.
+ is ($moduleList[3]->name(), 'module2', 'mod list[3] == module2');
+ is ($moduleList[3]->getOption('make-options'), 'j3', 'module-override make-options proper post-override');
+ }
+
+ # Remove last two args and add another test of indirect option value setting
+
+ pop @args;
+ pop @args;
+ push @args, '--num-cores=5'; # 4 is default, 8 is in rc-file, use something different
+
+ {
- my $app = ksb::Application->new(@args);
- my @moduleList = @{$app->{modules}};
++ my $app = ksb::Application::newFromCmdline(@args)->setHeadless;
++ my @moduleList = $app->modules();
+
+ is ($app->context()->getOption('num-cores'), 5, 'Updated cmdline option changes global value');
+
+ is (scalar @moduleList, 4, 'Right number of modules');
+ is ($moduleList[0]->name(), 'setmod1', 'mod list[0] == setmod1');
+ is ($moduleList[0]->getOption('make-options'), '-j4', 'make-options base value proper post-override (indirect value)');
+
+ is ($moduleList[3]->name(), 'module2', 'mod list[3] == module2');
+ is ($moduleList[3]->getOption('make-options'), '-j 5', 'module-override make-options proper post-override (indirect value)');
+ }
+
+ done_testing();
diff --cc vim/syntax/kdesrc-buildrc.vim
index 3e6ef72,7660ed7..d789047
--- a/vim/syntax/kdesrc-buildrc.vim
+++ b/vim/syntax/kdesrc-buildrc.vim
@@@ -67,10 -68,10 +68,10 @@@ syn keyword ksbrcBoolOption contained s
\ build-system-only build-when-unchanged ignore-kde-structure
\ include-dependencies install-after-build manual-build manual-update
\ no-src reconfigure recreate-configure refresh-build run-tests
- \ use-clean-install
+ \ use-clean-install compile-commands-export compile-commands-linking
syn keyword ksbrcGlobalBoolOption contained skipwhite nextgroup=ksbrcBoolValue
- \ async colorful-output disable-agent-check disable-snapshots pretend
+ \ colorful-output disable-agent-check disable-snapshots pretend
\ purge-old-logs stop-on-failure use-idle-io-priority install-session-driver
\ install-environment-driver
More information about the kde-doc-english
mailing list