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