You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
494 lines
13 KiB
494 lines
13 KiB
#!/usr/bin/env perl |
|
|
|
# Script to create a configuration file for kdesrc-build. |
|
# |
|
# Copyright © 2011 Michael Pyne. <mpyne@kde.org> |
|
# Home page: http://kdesrc-build.kde.org/ |
|
# |
|
# This program is free software; you can redistribute it and/or modify it under |
|
# the terms of the GNU General Public License as published by the Free Software |
|
# Foundation; either version 2 of the License, or (at your option) any later |
|
# version. |
|
# |
|
# This program is distributed in the hope that it will be useful, but WITHOUT |
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
|
# details. |
|
# |
|
# You should have received a copy of the GNU General Public License along with |
|
# this program; if not, write to the Free Software Foundation, Inc., 51 |
|
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
|
|
use strict; |
|
use 5.010; |
|
use IO::Pipe; |
|
use File::Copy; |
|
use File::Temp qw/tempfile/; |
|
|
|
our $VERSION = 0.02; # Not user-visible yet. |
|
|
|
sub clearScreen |
|
{ |
|
require POSIX; |
|
my $termios = POSIX::Termios->new(); |
|
$termios->getattr(1); # Get STDOUT attributes |
|
|
|
require Term::Cap; |
|
my $terminal = Term::Cap->Tgetent({OSPEED => $termios->getospeed}); |
|
|
|
# Force the clear characters to be output immediately. |
|
# Otherwise it might overlap with other output, like error messages. |
|
local $| = 1; |
|
|
|
print $terminal->Tputs('cl', 0); |
|
|
|
return 0; |
|
} |
|
|
|
sub runDialogExecutable |
|
{ |
|
my (@args) = @_; |
|
|
|
# Allow for 2 more file descriptors (on top of the normally allowed 0, 1, |
|
# 2) to survive the upcoming exec |
|
# See "SYSTEM_FD_MAX" in perldoc:perlvar |
|
$^F = 4; |
|
|
|
my $pipe = new IO::Pipe; |
|
my $pid; |
|
|
|
if ($pid = fork()) { |
|
# Parent |
|
$pipe->reader(); |
|
|
|
my $output = <$pipe>; |
|
|
|
waitpid $pid, 0; |
|
my $result = ($? >> 8); |
|
$pipe->close(); |
|
|
|
# dialog uses -1 as an exit code, Perl gets just the standard 8 bits |
|
# the rest of UNIX uses... |
|
if ($? == -1) { |
|
clearScreen(); |
|
die "Failed to run dialog(1): $@"; |
|
} |
|
elsif ($result == 255) { |
|
clearScreen(); |
|
die "Canceled the dialog"; |
|
} |
|
return $output || $result; |
|
} |
|
elsif (defined $pid) { |
|
# Child |
|
$pipe->writer(); |
|
my $outputFd = $pipe->fileno(); |
|
|
|
print "Using fd $outputFd"; |
|
exec ('dialog', '--output-fd', $outputFd, |
|
'--backtitle', 'kdesrc-build setup', |
|
@args); |
|
} |
|
else { |
|
die "Unable to fork? $!"; |
|
} |
|
} |
|
|
|
sub getUserInput |
|
{ |
|
my $prompt = shift; |
|
my $default = shift; |
|
|
|
my @args = qw/--inputbox 8 50/; |
|
splice @args, 1, 0, $prompt; |
|
push @args, $default if $default; |
|
|
|
return runDialogExecutable(@args); |
|
} |
|
|
|
sub getMenuOption |
|
{ |
|
my ($prompt, @opts) = @_; |
|
@opts = @{$opts[0]} if ref $opts[0] eq 'ARRAY'; |
|
|
|
my @args = qw/--menu 20 70 18/; |
|
splice @args, 1, 0, $prompt; |
|
|
|
while(my ($k, $v) = splice (@opts, 0, 2)) { |
|
push @args, $k, $v; |
|
} |
|
|
|
return runDialogExecutable(@args); |
|
} |
|
|
|
sub showInfo |
|
{ |
|
my $message = shift; |
|
my @args = qw/--msgbox 20 62/; |
|
splice @args, 1, 0, $message; |
|
|
|
return runDialogExecutable(@args); |
|
} |
|
|
|
sub getYesNoAnswer |
|
{ |
|
my $prompt = shift; |
|
my @args = qw/--yesno 8 55/; |
|
splice @args, 1, 0, $prompt; |
|
|
|
return runDialogExecutable(@args) == 0; |
|
} |
|
|
|
sub getDirectory |
|
{ |
|
my $dir = shift; |
|
my @args = qw/--dselect 20 70/; |
|
splice @args, 1, 0, $dir; |
|
|
|
return runDialogExecutable(@args); |
|
} |
|
|
|
sub getListOptions |
|
{ |
|
my ($prompt, $opts, $enabled) = @_; |
|
die "\$opts not a hash ref" unless (ref $opts eq 'ARRAY'); |
|
die "\$enabled not a hash ref" unless (ref $enabled eq 'HASH'); |
|
|
|
my @args = qw/--checklist 20 70 18/; |
|
splice @args, 1, 0, $prompt; |
|
splice @args, 0, 0, '--output-separator', ','; |
|
|
|
while (my ($k, $v) = splice(@{$opts}, 0, 2)) { |
|
push (@args, $k, $v, (exists ${$enabled}{$k} ? 'on' : 'off')); |
|
} |
|
|
|
my $output = runDialogExecutable(@args); |
|
|
|
# Filter out empty results, remove quotes. |
|
return map { m/^"(.*)"$/ } (grep { length $_ } (split(/,/, $output))); |
|
} |
|
|
|
# The 'dialog(1)' program is required, verify it exists before going |
|
# further. |
|
# We use the --help option since it doesn't send weird terminal characters to the screen |
|
# and it's supported on dialog and Debian's dialog replacement called whiptail. |
|
system('dialog', '--help') == 0 or do { |
|
my $osError = "$!"; |
|
|
|
say "Unable to run the dialog(1) program, it is required for this setup script."; |
|
if ($? == -1) { |
|
say "\tThe program wouldn't even run, due to error: $osError"; |
|
} |
|
else { |
|
say "\tProgram ran, but exited with error: ", $? >> 8; |
|
} |
|
|
|
exit 1; |
|
}; |
|
|
|
showInfo(<<EOF); |
|
This program sets up a base kdesrc-build configuration to |
|
use. |
|
|
|
It can be modified as you wish later. Before the form is |
|
presented, you will be asked if you would like an |
|
explanation of the kdesrc-build file layout. It is |
|
recommended to read this if you are not already familiar |
|
with building software. |
|
EOF |
|
|
|
if (getYesNoAnswer('See the tutorial?')) { |
|
showInfo(<<EOF); |
|
kdesrc-build must download source code from the KDE |
|
repositories. This source code is then compiled, in the |
|
"build directory". Once complete, this compiled code is |
|
installed to its final location, the "install directory". |
|
|
|
This program will only configure the install location, but |
|
all directories are configurable. |
|
|
|
The space requirements vary, but typically the build |
|
directory will require 3-5 times as much space as the |
|
corresponding source directory. The space required of |
|
installed software will be less than the build directory. |
|
EOF |
|
} |
|
|
|
my $dev = getYesNoAnswer('Do you already have commit ' . |
|
'access to the KDE repositories?'); |
|
|
|
if ($dev) { |
|
$dev = getUserInput("What is your KDE identity username (for SVN access)?"); |
|
} |
|
|
|
my $installDir = getMenuOption('Where do you want to install the software?', |
|
[ |
|
home => "$ENV{HOME}/kde4 (default)", |
|
custom => "Custom location, chosen next screen", |
|
]); |
|
|
|
if ($installDir eq 'custom') { |
|
$installDir = getDirectory('/usr/local/kde4'); |
|
} |
|
else { |
|
$installDir = "~/kde4"; |
|
} |
|
|
|
my @chosenModules = getListOptions( |
|
"Which major module groups do you want to build?", |
|
[ |
|
qt => 'The Qt library', |
|
baselibs => 'KDE essential libraries/runtime (required)', |
|
workspace => 'KDE Plasma Desktop and workspace', |
|
base => 'Essential KDE applications', |
|
pim => 'Personal Information Management software', |
|
], |
|
{ |
|
baselibs => 1, |
|
workspace => 1, |
|
base => 1, |
|
}, |
|
); |
|
|
|
my $numCpus = getUserInput( |
|
'How many CPU cores do you wish to use for building?', '2'); |
|
|
|
my $outputFileName = "$ENV{HOME}/.kdesrc-buildrc"; |
|
my $output; # Will be output filehandle. |
|
|
|
while (-e $outputFileName) { |
|
(my $printableName = $outputFileName) =~ s/^$ENV{HOME}/~/; |
|
my $outputChoice = getMenuOption( |
|
"$printableName already exists, what do you want to do?", |
|
[ |
|
backup => 'Make a backup, then overwrite with the new configuration', |
|
custom => 'Write the new configuration to a different file', |
|
cancel => 'Cancel setup', |
|
], |
|
); |
|
|
|
if ($outputChoice eq 'cancel') { |
|
showInfo('Setup canceled'); |
|
exit 0; |
|
} |
|
|
|
if ($outputChoice eq 'custom') { |
|
$outputFileName = getUserInput('Enter desired configuration file name.'); |
|
$outputFileName =~ s/^~/$ENV{HOME}/; |
|
} |
|
|
|
if ($outputChoice eq 'backup') { |
|
|
|
copy($outputFileName, "$outputFileName~") or do { |
|
my $error = "$!"; |
|
showInfo(<<EOF); |
|
Failed to make backup of $outputFileName, due to error $error. |
|
Configuration will be written to a temporary file instead. |
|
EOF |
|
|
|
($output, $outputFileName) = tempfile("kdesrc-buildrc-XXXX"); |
|
}; |
|
|
|
last; |
|
} |
|
} |
|
|
|
# Filehandle could already be opened as a tempfile. |
|
if (!$output) { |
|
open ($output, '>', $outputFileName) or do { |
|
my $error = "$!"; |
|
showInfo (<<EOF); |
|
Unable to open output file $outputFileName for writing due to error $error. |
|
EOF |
|
die "$!"; |
|
} |
|
} |
|
|
|
print $output <<EOF; |
|
# Autogenerated by kdesrc-build-setup. You may modify this file if desired. |
|
global |
|
|
|
EOF |
|
|
|
if (grep { /^qt$/ } @chosenModules) { |
|
print $output <<EOF; |
|
# The path to your Qt installation. |
|
qtdir ~/qt4 |
|
|
|
EOF |
|
} |
|
|
|
print $output <<EOF; |
|
# KDE install directory |
|
kdedir $installDir |
|
|
|
# Directory for downloaded source code |
|
source-dir ~/kdesrc |
|
|
|
# Directory to build KDE into before installing |
|
build-dir build |
|
|
|
# Use multiple cores for building. Other options to GNU make may also be |
|
# set. |
|
make-options -j$numCpus |
|
|
|
EOF |
|
|
|
if ($dev) { |
|
print $output <<EOF; |
|
# Login to use for SVN. Anonymous SVN can be used by just deleting this |
|
# line. |
|
svn-server svn+ssh://$dev\@svn.kde.org/home/kde |
|
|
|
EOF |
|
} |
|
|
|
print $output <<EOF; |
|
end global |
|
|
|
EOF |
|
|
|
if (grep /^qt$/, @chosenModules) { |
|
print $output <<EOF; |
|
module qt |
|
configure-flags -fast -debug -system-zlib -system-libpng -system-libjpeg \\ |
|
-plugin-sql-mysql -no-phonon \\ |
|
-dbus -webkit -nomake examples -nomake demos |
|
|
|
# KDE's unmodified copy of Qt is used by default since git.kde.org supports |
|
# cloning the module more reliably than gitorious. To use standard Qt as |
|
# provided by Nokia, comment the following line and uncomment the next |
|
# repository line. |
|
repository kde:qt |
|
|
|
# Nokia's Qt. Note that gitorious has had known issues checking out large |
|
# git modules such as Qt. If there are failures try using KDE's qt (see |
|
# above). |
|
# repository git://gitorious.org/qt/qt.git |
|
|
|
branch 4.8 |
|
end module |
|
|
|
EOF |
|
} |
|
|
|
if (grep /^baselibs$/, @chosenModules) { |
|
print $output <<EOF; |
|
# These encompass modules that are not directly a part of KDE proper but are |
|
# required or highly recommended for the KDE framework and are developed in |
|
# the KDE source repository. |
|
module-set baselibs-support |
|
repository kde-projects |
|
|
|
use-modules automoc cagibi attica soprano polkit-qt-1 |
|
end module-set |
|
|
|
# Phonon provides the KDE multimedia layer. It requires an appropriate backend |
|
# to be installed to actually implement multimedia. |
|
module-set framework-phonon |
|
repository kde-projects |
|
|
|
use-modules phonon/phonon phonon-gstreamer phonon-vlc |
|
end module-set |
|
|
|
# Strigi provides file analysis tools for extracting information from files |
|
# (e.g. music length, picture size, etc.) It is split into several submodules |
|
# so do not alter the order in the use-modules below. |
|
module-set strigi |
|
repository kde-projects |
|
|
|
use-modules strigi/libstreams strigi/libstreamanalyzer strigi/strigiutils \\ |
|
strigi/strigidaemon strigi/strigiclient |
|
end module-set |
|
|
|
# libdbusmenu is needed to support new-style Plasma system tray icons and |
|
# support in the Unity shell. Installing a recent development package from your |
|
# distribution should be sufficient, but if you want to have the latest then |
|
# make sure you have the "Bazaar" program installed and uncomment the |
|
# following: |
|
#module libdbusmenu-qt |
|
# The lp: prefix refers to Canonical's Launchpad repository |
|
# repository bzr://lp:libdbusmenu-qt |
|
#end module |
|
|
|
# Base/essential KDE libraries and the required runtime programs. |
|
# Split into two module-sets to setup the right branch for kdelibs. |
|
module-set baselibs-kdelibs |
|
repository kde-projects |
|
|
|
use-modules kdelibs |
|
branch KDE/4.8 # kdelibs for KDE 4 is limited to bugfixes. |
|
end module-set |
|
|
|
module-set baselibs-other |
|
repository kde-projects |
|
|
|
use-modules kactivities kde-runtime |
|
end module-set |
|
|
|
module-set baselibs-pimlibs |
|
repository kde-projects |
|
|
|
use-modules akonadi kdepimlibs |
|
end module-set |
|
|
|
EOF |
|
} |
|
|
|
if (grep /^workspace$/, @chosenModules) { |
|
print $output <<EOF; |
|
module-set workspace |
|
repository kde-projects |
|
|
|
use-modules kde-workspace kdeplasma-addons |
|
end module-set |
|
|
|
EOF |
|
} |
|
|
|
if (grep /^base$/, @chosenModules) { |
|
print $output <<EOF; |
|
module-set base |
|
repository kde-projects |
|
|
|
# kde-baseapps must precede kate and konsole, due to |
|
# on-disk layout. |
|
use-modules kde-baseapps kate konsole |
|
end module-set |
|
|
|
EOF |
|
} |
|
|
|
if (grep /^pim$/, @chosenModules) { |
|
print $output <<EOF; |
|
module-set pim |
|
repository kde-projects |
|
|
|
use-modules kdepim-runtime kdepim |
|
end module-set |
|
|
|
EOF |
|
} |
|
|
|
close($output); |
|
$outputFileName =~ s/^$ENV{HOME}/~/; |
|
showInfo("Generated configuration has been written to $outputFileName"); |
|
|
|
# Say same thing in text mode just in case. |
|
system('clear'); |
|
say "Generated configuration has been written to $outputFileName"; |
|
|
|
if ($outputFileName ne '~/.kdesrc-buildrc') { |
|
say <<EOF; |
|
|
|
Note that your configuration file in $outputFileName will |
|
NOT BE USED unless you either: |
|
1. Overwrite your ~/.kdesrc-buildrc with $outputFileName, or |
|
2. Copy $outputFileName to be called 'kdesrc-buildrc' in some directory |
|
and ALWAYS run kdesrc-build from the directory, or |
|
3. ALWAYS pass the "--rc-file $outputFileName" option to kdesrc-build when you |
|
run it. |
|
EOF |
|
} |
|
|
|
exit 0;
|
|
|