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