Warning, /sdk/kdesrc-build/kdesrc-build-setup is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/env perl 0002 0003 # Script to create a configuration file for kdesrc-build. 0004 # 0005 # Copyright © 2011, 2020-2022 Michael Pyne. <mpyne@kde.org> 0006 # Home page: https://apps.kde.org/kdesrc_build/ 0007 # 0008 # This program is free software; you can redistribute it and/or modify it under 0009 # the terms of the GNU General Public License as published by the Free Software 0010 # Foundation; either version 2 of the License, or (at your option) any later 0011 # version. 0012 # 0013 # This program is distributed in the hope that it will be useful, but WITHOUT 0014 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 0015 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 0016 # details. 0017 # 0018 # You should have received a copy of the GNU General Public License along with 0019 # this program; if not, write to the Free Software Foundation, Inc., 51 0020 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0021 0022 use v5.28; 0023 use strict; 0024 use warnings; 0025 0026 # On many container-based distros, even FindBin is missing to conserve space. 0027 # But we can use File::Spec to do nearly the same. 0028 my $RealBin; 0029 my $modPath; 0030 0031 # The File::Spec calls have to run when parsing (i.e. in BEGIN) to make the 0032 # 'use lib' below work (which itself implicitly uses BEGIN { }) 0033 BEGIN { 0034 use File::Spec; 0035 0036 # resolve symlinks 0037 my $scriptPath = $0; 0038 for (1..16) { 0039 last unless -l $scriptPath; 0040 $scriptPath = readlink $scriptPath; 0041 } 0042 die "Too many symlinks followed looking for script" if -l $scriptPath; 0043 0044 my ($volume, $directories, $script) = File::Spec->splitpath($scriptPath); 0045 0046 $RealBin = File::Spec->catpath($volume, $directories, ''); 0047 die "Couldn't find base directory!" unless $RealBin; 0048 0049 # Use modules in git repo if running from git dir, otherwise assume 0050 # system install 0051 $modPath = File::Spec->rel2abs('modules', $RealBin); 0052 $modPath = ($RealBin =~ s,/bin/?$,/share/kdesrc-build/modules,r) 0053 unless -d $modPath; 0054 0055 die "Couldn't find modules for kdesrc-build-setup!" unless $modPath; 0056 } 0057 0058 use lib "$modPath"; # Make ksb:: modules available 0059 0060 use ksb; 0061 use ksb::FirstRun; 0062 0063 use Cwd qw(abs_path); 0064 use File::Basename; 0065 use File::Copy; 0066 use File::Path qw(make_path); 0067 use File::Temp qw(tempfile); 0068 use IO::Pipe; 0069 use List::Util qw(max min first); 0070 0071 our $VERSION = 0.10; # Not user-visible yet. 0072 0073 my $OS = `uname`; # Check whether we're using Linux or FreeBSD 0074 0075 sub clearScreen 0076 { 0077 require POSIX; 0078 my $termios = POSIX::Termios->new(); 0079 $termios->getattr(1); # Get STDOUT attributes 0080 0081 require Term::Cap; 0082 my $terminal = Term::Cap->Tgetent({OSPEED => $termios->getospeed}); 0083 0084 # Force the clear characters to be output immediately. 0085 # Otherwise it might overlap with other output, like error messages. 0086 local $| = 1; 0087 0088 print $terminal->Tputs('cl', 0); 0089 0090 return 0; 0091 } 0092 0093 sub runDialogExecutable (@args) 0094 { 0095 # Allow for 3 more file descriptors (on top of the normally allowed 0, 1, 0096 # 2) to survive the upcoming exec 0097 # See "SYSTEM_FD_MAX" in perldoc:perlvar 0098 $^F = 5; 0099 0100 my $pipe = new IO::Pipe; 0101 my $pid; 0102 0103 if ($pid = fork()) { 0104 # Parent 0105 $pipe->reader(); 0106 0107 my $output = <$pipe>; 0108 0109 waitpid $pid, 0; 0110 my $result = ($? >> 8); 0111 $pipe->close(); 0112 0113 # dialog uses -1 as an exit code, Perl gets just the standard 8 bits 0114 # the rest of UNIX uses... 0115 if ($? == -1) { 0116 clearScreen(); 0117 die "Failed to run dialog(1): $@"; 0118 } 0119 elsif ($result == 255) { 0120 clearScreen(); 0121 die "Canceled the dialog"; 0122 } 0123 return $output || $result; 0124 } 0125 elsif (defined $pid) { 0126 # Child 0127 $pipe->writer(); 0128 my $outputFd = $pipe->fileno(); 0129 0130 print "Using fd $outputFd"; 0131 exec ('dialog', '--output-fd', $outputFd, 0132 '--backtitle', 'kdesrc-build setup', 0133 @args); 0134 } 0135 else { 0136 die "Unable to fork? $!"; 0137 } 0138 } 0139 0140 sub getUserInput 0141 { 0142 my $prompt = shift; 0143 my $default = shift; 0144 0145 my @args = qw/--inputbox 8 50/; 0146 splice @args, 1, 0, $prompt; 0147 push @args, $default if $default; 0148 0149 return runDialogExecutable(@args); 0150 } 0151 0152 sub getMenuOption 0153 { 0154 my ($prompt, @opts) = @_; 0155 @opts = @{$opts[0]} if ref $opts[0] eq 'ARRAY'; 0156 0157 my @args = qw/--menu 20 70 18/; 0158 splice @args, 1, 0, $prompt; 0159 0160 return runDialogExecutable(@args, @opts); 0161 } 0162 0163 sub showInfo 0164 { 0165 my $message = shift; 0166 my @args = qw/--msgbox 22 64/; 0167 splice @args, 1, 0, $message; 0168 0169 return runDialogExecutable(@args); 0170 } 0171 0172 sub getYesNoAnswer 0173 { 0174 my $prompt = shift; 0175 my @args = qw/--yesno 8 55/; 0176 splice @args, 1, 0, $prompt; 0177 0178 return runDialogExecutable(@args) == 0; 0179 } 0180 0181 sub getDirectory 0182 { 0183 my $dir = shift; 0184 my @args = qw/--dselect 10 70/; 0185 splice @args, 1, 0, $dir; 0186 0187 return runDialogExecutable(@args); 0188 } 0189 0190 sub getListOptions 0191 { 0192 my ($prompt, $opts, $enabled) = @_; 0193 die "\$opts not a hash ref" unless (ref $opts eq 'ARRAY'); 0194 die "\$enabled not a hash ref" unless (ref $enabled eq 'HASH'); 0195 0196 my @args = qw/--checklist 20 70 18/; 0197 splice @args, 1, 0, $prompt; 0198 splice @args, 0, 0, '--output-separator', ','; 0199 0200 while (my ($k, $v) = splice(@{$opts}, 0, 2)) { 0201 push (@args, $k, $v, (exists ${$enabled}{$k} ? 'on' : 'off')); 0202 } 0203 0204 my $output = runDialogExecutable(@args); 0205 0206 # Filter out empty results, remove quotes. 0207 my @items = split (/,/, $output); 0208 s/^"(.*)"$/$1/ foreach @items; 0209 @items = grep { length $_ } @items; 0210 return @items; 0211 } 0212 0213 # The 'dialog(1)' program is required, verify it exists before going 0214 # further. 0215 # We use the --help option since it doesn't send weird terminal characters to the screen 0216 # and it's supported on dialog and Debian's dialog replacement called whiptail. 0217 system('dialog', '--help') == 0 or do { 0218 my $osError = "$!"; 0219 0220 say "Unable to run the dialog(1) program, it is required for this setup script."; 0221 if ($? == -1) { 0222 say "\tThe program wouldn't even run, due to error: $osError"; 0223 } 0224 else { 0225 say "\tProgram ran, but exited with error: ", $? >> 8; 0226 } 0227 0228 exit 1; 0229 }; 0230 0231 showInfo(<<EOF); 0232 This program sets up a base kdesrc-build configuration to 0233 use. 0234 0235 It can be modified as you wish later. Before the form is 0236 presented, you will be asked if you would like an 0237 explanation of the kdesrc-build file layout. It is 0238 recommended to read this if you are not already familiar 0239 with building software. 0240 EOF 0241 0242 if (getYesNoAnswer('See the tutorial?')) { 0243 showInfo(<<EOF); 0244 kdesrc-build must download source code from the KDE 0245 repositories. This source code is then compiled, in the 0246 "build directory". Once complete, this compiled code is 0247 installed to its final location, the "install directory". 0248 0249 This program will only configure the install location, but 0250 all directories are configurable. 0251 0252 The space requirements vary with the amount of software you 0253 choose to build, and whether you keep the build directories 0254 to speed up later builds. You will probably need at least 0255 20 GiB in total free space unless you take steps to 0256 customize your install to use fewer modules. 0257 EOF 0258 } 0259 0260 # If the user appears to be using a proxy, ask for it directly, otherwise 0261 # prompt for one. 0262 my $proxy = $ENV{http_proxy} // ''; 0263 0264 my $installDir = getMenuOption('Where do you want to install the software?', 0265 [ 0266 home => "$ENV{HOME}/kde/usr (default)", 0267 custom => "Custom location, chosen next screen", 0268 ]); 0269 0270 if ($installDir eq 'custom') { 0271 $installDir = getDirectory('/usr/local/kde'); 0272 } 0273 else { 0274 $installDir = "~/kde/usr"; 0275 } 0276 0277 my $sourceDir = getMenuOption('Where do you want the source code to be saved?', 0278 [ 0279 home => "$ENV{HOME}/kde/src (default)", 0280 custom => "Custom location, chosen next screen", 0281 ]); 0282 0283 if ($sourceDir eq 'custom') { 0284 $sourceDir = getDirectory('/usr/local/kde/src'); 0285 } 0286 else { 0287 $sourceDir = "~/kde/src"; 0288 } 0289 0290 my $buildDir = getMenuOption('Where do you want temporary build files to be saved? (They might need lots of space)', 0291 [ 0292 home => "$ENV{HOME}/kde/build (default)", 0293 custom => "Custom location, chosen next screen", 0294 ]); 0295 0296 if ($buildDir eq 'custom') { 0297 $buildDir = getDirectory('/usr/local/kde/build'); 0298 } 0299 else { 0300 $buildDir = "~/kde/build"; 0301 } 0302 0303 showInfo(<<EOF); 0304 Should kdesrc-build automatically try to include needed KDE 0305 dependencies in each build? 0306 0307 Doing this makes it easier to just get a single application 0308 built without worrying about the details. Most KDE software 0309 under active development needs these dependencies. 0310 IF IN ANY DOUBT, SELECT YES on the next screen. 0311 0312 If you know exactly what you want to build or want to ensure 0313 that only modules you have allowed in your configuration 0314 file are built, then you should disable this option. 0315 0316 You can always use the --include-dependencies or 0317 --no-include-dependencies command line option to 0318 kdesrc-build, and you can change this default at any time by 0319 editing the file that this script will generate. 0320 EOF 0321 0322 my $includeDependencies = 0323 getYesNoAnswer('Should kdesrc-build include KDE dependencies by default with each build?'); 0324 0325 my @chosenModules = getListOptions( 0326 "Which major module groups do you want to build?", 0327 [ 0328 qt5 => 'Qt 5 - Base support libraries (required if distro version is old)', 0329 frameworks => 'KDE Frameworks 5 - Essential libraries/runtime (required)', 0330 workspace => 'KDE Plasma 5 Desktop and workspace', 0331 base => 'Assorted useful KF5-based applications', 0332 pim => 'Personal Information Management software', 0333 ], 0334 { 0335 frameworks => 1, 0336 workspace => 1, 0337 base => 1, 0338 }, 0339 ); 0340 0341 # According to XDG spec, if $XDG_CONFIG_HOME is not set, then we should default 0342 # to ~/.config 0343 my $xdgConfigHome = $ENV{XDG_CONFIG_HOME} // "$ENV{HOME}/.config"; 0344 my $xdgConfigHomeShort = $xdgConfigHome =~ s/^$ENV{HOME}/~/r; # Replace $HOME with ~ 0345 my $outputFile = "$xdgConfigHome/kdesrc-buildrc"; 0346 my $outputFileShort = $outputFile =~ s/^$ENV{HOME}/~/r; # Replace $HOME with ~ 0347 my $output; # Will be output filehandle. 0348 0349 while (-e $outputFile) { 0350 my $outputChoice = getMenuOption( 0351 "$outputFileShort already exists, what do you want to do?", 0352 [ 0353 backup => 'Make a backup, then overwrite with the new configuration', 0354 custom => 'Write the new configuration to a different file', 0355 cancel => 'Cancel setup', 0356 ], 0357 ); 0358 0359 if ($outputChoice eq 'cancel') { 0360 showInfo('Setup canceled'); 0361 exit 0; 0362 } 0363 0364 if ($outputChoice eq 'custom') { 0365 $outputFile = getUserInput('Enter desired configuration file name.'); 0366 $outputFile =~ s/^~/$ENV{HOME}/; 0367 $outputFileShort = $outputFile =~ s/^$ENV{HOME}/~/r; 0368 } 0369 0370 if ($outputChoice eq 'backup') { 0371 copy($outputFile, "$outputFile~") or do { 0372 my $error = "$!"; 0373 showInfo(<<EOF); 0374 Failed to make backup of $outputFileShort, due to error $error. 0375 Configuration will be written to a temporary file instead. 0376 EOF 0377 0378 ($output, $outputFile) = tempfile("kdesrc-buildrc-XXXX"); 0379 $outputFileShort = $outputFile =~ s/^$ENV{HOME}/~/r; 0380 }; 0381 0382 last; 0383 } 0384 } 0385 0386 # Filehandle could already be opened as a tempfile. 0387 if (!$output) { 0388 # Ensure the directory we need exists 0389 my ($vol, $dir, $file) = File::Spec->splitpath($outputFile); 0390 make_path($dir) unless -d $dir; 0391 0392 open ($output, '>', $outputFile) or do { 0393 my $error = "$!"; 0394 showInfo (<<EOF); 0395 Unable to open output file $outputFileShort for writing due to error $error. 0396 EOF 0397 die "$!"; 0398 } 0399 } 0400 0401 print $output <<EOF; 0402 # Autogenerated by kdesrc-build-setup. You may modify this file if desired. 0403 global 0404 EOF 0405 0406 # Only set qtdir if we're building it ourselves. If user uses their own custom 0407 # Qt they should already be setting PATH and in that case we need do nothing 0408 # anyways. 0409 if (grep /^qt5$/, @chosenModules) { 0410 print $output <<EOF; 0411 0412 # The path to your Qt installation (default is empty, assumes Qt provided 0413 # by system) 0414 qtdir ~/kde/qt5 0415 EOF 0416 } 0417 0418 my $num_cores; 0419 0420 if ($OS == 'Linux') { 0421 chomp($num_cores = `nproc`); 0422 } elsif ($OS == 'FreeBSD') { 0423 chomp($num_cores = `sysctl -n hw.ncpu`); 0424 } 0425 $num_cores ||= 4; 0426 0427 my $num_cores_low = min(ksb::FirstRun::suggestedNumCoresForLowMemory(), $num_cores); 0428 0429 $includeDependencies = $includeDependencies ? 'true' : 'false'; 0430 0431 # 0432 ### Start generating the kdesrc-buildrc 0433 # 0434 print $output <<EOF; 0435 0436 # Finds and includes *KDE*-based dependencies into the build. This makes 0437 # it easier to ensure that you have all the modules needed, but the 0438 # dependencies are not very fine-grained so this can result in quite a few 0439 # modules being installed that you didn't need. 0440 include-dependencies $includeDependencies 0441 0442 # Install directory for KDE software 0443 kdedir $installDir 0444 0445 # Directory for downloaded source code 0446 source-dir $sourceDir 0447 0448 # Directory to build KDE into before installing 0449 # relative to source-dir by default 0450 build-dir $buildDir 0451 0452 ## kdesrc-build sets 2 options which is used in options like make-options or set-env 0453 # to help manage the number of compile jobs that happen during a build: 0454 # 0455 # 1. num-cores, which is just the number of detected CPU cores, and can be passed 0456 # to tools like make (needed for parallel build) or ninja (completely optional). 0457 # 0458 # 2. num-cores-low-mem, which is set to largest value that appears safe for 0459 # particularly heavyweight modules based on total memory, intended for 0460 # modules like qtwebengine 0461 num-cores $num_cores 0462 num-cores-low-mem $num_cores_low 0463 0464 # kdesrc-build can install a sample .xsession file for "Custom" 0465 # (or "XSession") logins, 0466 install-session-driver false 0467 0468 # or add a environment variable-setting script to 0469 # ~/.config/kde-env-master.sh 0470 install-environment-driver true 0471 0472 # Stop the build process on the first failure 0473 stop-on-failure true 0474 0475 # Use a flat folder layout under $sourceDir and $buildDir 0476 # rather than nested directories 0477 directory-layout flat 0478 0479 # Build with LSP support for everything that supports it 0480 compile-commands-linking true 0481 compile-commands-export true 0482 EOF 0483 0484 if ($proxy) { 0485 print $output <<EOF; 0486 0487 # Proxy to use for HTTP downloads. 0488 http-proxy $proxy 0489 0490 # Prefer HTTPS instead of Git-native protocol for git modules that come 0491 # from 'kde-projects' repositories. 0492 # 0493 # Note that any git:// repositories you use will need to be 0494 # manually converted to https:// URLs if your network does not allow 0495 # git:// protcol. 0496 git-desired-protocol https 0497 EOF 0498 } 0499 0500 # Assume we can refer to files present alongside kdesrc-build in the source 0501 # directory 0502 my $basedir = dirname(abs_path($0)); 0503 my $baseDirShort = $basedir =~ s/^$ENV{HOME}/~/r; # Replace $HOME with ~ 0504 0505 if (! -e "$basedir/kf5-frameworks-build-include") { 0506 # Check if it's installed to a share/ prefix 0507 $basedir = abs_path(dirname($0) . "/../share/kdesrc-build/"); 0508 $baseDirShort = $basedir =~ s/^$ENV{HOME}/~/r; 0509 0510 if (! -e "$basedir/kf5-frameworks-build-include") { 0511 close $output; 0512 showInfo("Unable to find kdesrc-build installation to build a configuration!"); 0513 exit 1; 0514 } 0515 } 0516 0517 print $output <<EOF; 0518 end global 0519 0520 # Common options that should be set for some KDE modules no matter how 0521 # kdesrc-build finds them. Do not comment these out unless you know 0522 # what you are doing. 0523 include $basedir/kf5-common-options-build-include 0524 0525 EOF 0526 0527 my $do_incl = '#'; 0528 $do_incl = '' if grep { $_ eq 'qt5' } @chosenModules; 0529 0530 print $output <<EOF; 0531 # Refers to the qt5 file included as part of kdesrc-build. The file 0532 # is simply read-in at this point as if you'd typed it in yourself. 0533 ${do_incl}include $basedir/qt5-build-include 0534 0535 # Support libraries that use Qt5 0536 ${do_incl}include $basedir/custom-qt5-libs-build-include 0537 0538 EOF 0539 0540 $do_incl = '#'; 0541 $do_incl = '' if grep { $_ eq 'frameworks' } @chosenModules; 0542 0543 print $output <<EOF; 0544 # Refers to the kf5-frameworks file included as part of kdesrc-build. The file 0545 # is simply read-in at this point as if you'd typed it in yourself. 0546 ${do_incl}include $basedir/kf5-frameworks-build-include 0547 0548 EOF 0549 0550 $do_incl = '#'; 0551 $do_incl = '' if grep { $_ eq 'workspace' } @chosenModules; 0552 0553 print $output <<EOF; 0554 # Refers to the kf5-workspace file included as part of kdesrc-build. The file 0555 # is simply read-in at this point as if you'd typed it in yourself. 0556 ${do_incl}include $basedir/kf5-workspace-build-include 0557 0558 EOF 0559 0560 $do_incl = '#'; 0561 $do_incl = '' if grep { $_ eq 'base' } @chosenModules; 0562 0563 print $output <<EOF; 0564 # Refers to the kf5-applications file included as part of kdesrc-build. The file 0565 # is simply read-in at this point as if you'd typed it in yourself. 0566 ${do_incl}include $basedir/kf5-applications-build-include 0567 0568 EOF 0569 0570 $do_incl = '#'; 0571 $do_incl = '' if grep { $_ eq 'pim' } @chosenModules; 0572 0573 print $output <<EOF; 0574 # Refers to the kf5-kdepim file included as part of kdesrc-build. The file 0575 # is simply read-in at this point as if you'd typed it in yourself. 0576 ${do_incl}include $basedir/kf5-kdepim-build-include 0577 0578 EOF 0579 0580 close($output); 0581 0582 showInfo("Generated configuration has been written to $outputFileShort"); 0583 0584 if (!@chosenModules) { 0585 showInfo(<<EOF); 0586 You have not chosen any major module groups. You will have to 0587 add modules and module-sets to your configuration after this. 0588 0589 To help you with this, please consult the sample files in 0590 $basedir 0591 EOF 0592 } 0593 0594 # Say same thing in text mode just in case. 0595 system('clear'); 0596 say "Generated configuration has been written to $outputFileShort"; 0597 say "Sample configuration files are available in $baseDirShort"; 0598 0599 if ($outputFile ne "$xdgConfigHome/kdesrc-buildrc") { 0600 say <<EOF; 0601 0602 Do note, that your configuration file $outputFileShort will NOT BE USED, 0603 unless you will do one of the following: 0604 - Overwrite $xdgConfigHomeShort/kdesrc-buildrc with $outputFileShort 0605 - Copy $outputFileShort to some directory and rename it to "kdesrc-buildrc", 0606 then ALWAYS run kdesrc-build from that directory 0607 - ALWAYS pass the "--rc-file $outputFileShort" option to kdesrc-build when 0608 you run it 0609 EOF 0610 } 0611 0612 exit 0;