1#!/usr/bin/perl
2###########################################################################
3# Makefile for ABI Dumper
4# Install/remove the tool for GNU/Linux
5#
6# Copyright (C) 2013-2015 Andrey Ponomarenko's ABI Laboratory
7#
8# Written by Andrey Ponomarenko
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License or the GNU Lesser
12# General Public License as published by the Free Software Foundation.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# and the GNU Lesser General Public License along with this program.
21# If not, see <http://www.gnu.org/licenses/>.
22###########################################################################
23use Getopt::Long;
24Getopt::Long::Configure ("posix_default", "no_ignore_case");
25use File::Path qw(mkpath rmtree);
26use File::Copy qw(copy);
27use File::Basename qw(dirname);
28use Cwd qw(abs_path);
29use File::Find;
30use strict;
31
32my $TOOL_SNAME = "abi-dumper";
33my $ARCHIVE_DIR = abs_path(dirname($0));
34
35my $HELP_MSG = "
36NAME:
37  Makefile for ABI Dumper
38
39DESCRIPTION:
40  Install $TOOL_SNAME command and private modules.
41
42USAGE:
43  sudo perl $0 -install -prefix /usr
44  sudo perl $0 -remove -prefix /usr
45
46OPTIONS:
47  -h|-help
48      Print this help.
49
50  --prefix=PREFIX
51      Install files in PREFIX [/usr].
52
53  -install
54      Command to install the tool.
55
56  -remove
57      Command to remove the tool.
58
59EXTRA OPTIONS:
60  --destdir=DESTDIR
61      This option is for maintainers to build
62      RPM or DEB packages inside the build root.
63      The environment variable DESTDIR is also
64      supported.
65\n";
66
67if(not @ARGV)
68{
69    print $HELP_MSG;
70    exit(0);
71}
72
73my ($PREFIX, $DESTDIR, $Help, $Install, $Remove);
74
75GetOptions(
76    "h|help!" => \$Help,
77    "prefix=s" => \$PREFIX,
78    "destdir=s" => \$DESTDIR,
79    "install!" => \$Install,
80    "remove!" => \$Remove
81) or exit(1);
82
83sub scenario()
84{
85    if($Help)
86    {
87        print $HELP_MSG;
88        exit(0);
89    }
90    if(not $Install and not $Remove)
91    {
92        print STDERR "ERROR: command is not selected (-install or -remove)\n";
93        exit(1);
94    }
95
96    if($Install)
97    { # remove old version first
98        $Remove = 1;
99    }
100
101    if($PREFIX ne "/") {
102        $PREFIX=~s/[\/]+\Z//g;
103    }
104    if(not $PREFIX)
105    { # default prefix
106        $PREFIX = "/usr";
107    }
108    if(my $Var = $ENV{"DESTDIR"})
109    {
110        print "Using DESTDIR environment variable\n";
111        $DESTDIR = $Var;
112    }
113    if($DESTDIR)
114    {
115        if($DESTDIR ne "/") {
116            $DESTDIR=~s/[\/]+\Z//g;
117        }
118        if($DESTDIR!~/\A\//)
119        {
120            print STDERR "ERROR: destdir is not absolute path\n";
121            exit(1);
122        }
123        if(not -d $DESTDIR)
124        {
125            print STDERR "ERROR: you should create destdir directory first\n";
126            exit(1);
127        }
128        $PREFIX = $DESTDIR.$PREFIX;
129        if(not -d $PREFIX)
130        {
131            print STDERR "ERROR: you should create installation directory first (destdir + prefix):\n  mkdir -p $PREFIX\n";
132            exit(1);
133        }
134    }
135    else
136    {
137        if($PREFIX!~/\A\//)
138        {
139            print STDERR "ERROR: prefix is not absolute path\n";
140            exit(1);
141        }
142        if(not -d $PREFIX)
143        {
144            print STDERR "ERROR: you should create prefix directory first\n";
145            exit(1);
146        }
147    }
148
149    print "INSTALL PREFIX: $PREFIX\n";
150
151    # paths
152    my $EXE_PATH = "$PREFIX/bin";
153    my $MODULES_PATH = "$PREFIX/share/$TOOL_SNAME";
154    my $REL_PATH = "../share/$TOOL_SNAME";
155    my $TOOL_PATH = "$EXE_PATH/$TOOL_SNAME";
156
157    if(not -w $PREFIX)
158    {
159        print STDERR "ERROR: you should be root\n";
160        exit(1);
161    }
162    if($Remove)
163    {
164        if(-e $EXE_PATH."/".$TOOL_SNAME)
165        { # remove executable
166            print "-- Removing $TOOL_PATH\n";
167            unlink($EXE_PATH."/".$TOOL_SNAME);
168        }
169        elsif(not $Install) {
170            print "The tool is not installed\n";
171        }
172
173        if(-d $ARCHIVE_DIR."/modules")
174        {
175            if(-d $MODULES_PATH)
176            { # remove modules
177                print "-- Removing $MODULES_PATH\n";
178                rmtree($MODULES_PATH);
179            }
180            elsif(not $Install) {
181                print "The modules of the tool are not installed\n";
182            }
183        }
184    }
185    if($Install)
186    {
187        # configure
188        my $Content = readFile($ARCHIVE_DIR."/".$TOOL_SNAME.".pl");
189        if($DESTDIR) { # relative path
190            $Content=~s/MODULES_INSTALL_PATH/$REL_PATH/;
191        }
192        else { # absolute path
193            $Content=~s/MODULES_INSTALL_PATH/$MODULES_PATH/;
194        }
195
196        # copy executable
197        print "-- Installing $TOOL_PATH\n";
198        mkpath($EXE_PATH);
199        writeFile($EXE_PATH."/".$TOOL_SNAME, $Content);
200        chmod(0755, $EXE_PATH."/".$TOOL_SNAME);
201
202        # copy modules
203        if(-d $ARCHIVE_DIR."/modules")
204        {
205            print "-- Installing $MODULES_PATH\n";
206            mkpath($MODULES_PATH);
207            copyDir($ARCHIVE_DIR."/modules", $MODULES_PATH);
208        }
209
210        # check PATH
211        if($ENV{"PATH"}!~/(\A|:)\Q$EXE_PATH\E[\/]?(\Z|:)/) {
212            print "WARNING: your PATH variable doesn't include \'$EXE_PATH\'\n";
213        }
214    }
215    exit(0);
216}
217
218sub copyDir($$)
219{
220    my ($From, $To) = @_;
221    my %Files;
222    find(\&wanted, $From);
223    sub wanted {
224        $Files{$File::Find::dir."/$_"} = 1 if($_ ne ".");
225    }
226    foreach my $Path (sort keys(%Files))
227    {
228        my $Inst = $Path;
229        $Inst=~s/\A\Q$ARCHIVE_DIR\E/$To/;
230        if(-d $Path)
231        { # directories
232            mkpath($Inst);
233        }
234        else
235        { # files
236            mkpath(dirname($Inst));
237            copy($Path, $Inst);
238        }
239    }
240}
241
242sub readFile($)
243{
244    my $Path = $_[0];
245    return "" if(not $Path or not -f $Path);
246    open(FILE, $Path) || die ("can't open file \'$Path\': $!\n");
247    local $/ = undef;
248    my $Content = <FILE>;
249    close(FILE);
250    return $Content;
251}
252
253sub writeFile($$)
254{
255    my ($Path, $Content) = @_;
256    return if(not $Path);
257    open(FILE, ">".$Path) || die ("can't open file \'$Path\': $!\n");
258    print FILE $Content;
259    close(FILE);
260}
261
262scenario();
263