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