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