summaryrefslogtreecommitdiff
path: root/tools/apbuild/Apbuild/Utils.pm
diff options
context:
space:
mode:
Diffstat (limited to 'tools/apbuild/Apbuild/Utils.pm')
-rw-r--r--tools/apbuild/Apbuild/Utils.pm195
1 files changed, 195 insertions, 0 deletions
diff --git a/tools/apbuild/Apbuild/Utils.pm b/tools/apbuild/Apbuild/Utils.pm
new file mode 100644
index 00000000..a5089299
--- /dev/null
+++ b/tools/apbuild/Apbuild/Utils.pm
@@ -0,0 +1,195 @@
+package Apbuild::Utils;
+
+use strict;
+use warnings;
+use Exporter;
+use base qw(Exporter);
+use IO::Handle;
+use IPC::Open2;
+use POSIX;
+use Cwd qw(abs_path);
+
+
+our @EXPORT = qw(debug error checkCommand empty homeDir searchLib searchStaticLib soname run parseDataFile writeDataFile);
+our $debugOpened = 0;
+
+
+##
+# debug(message)
+#
+# If the environment variable $APBUILD_DEBUG is set to 1,
+# then print a debugging message to /dev/tty (not stdout or stderr).
+sub debug {
+ return if (empty($ENV{APBUILD_DEBUG}) || !$ENV{APBUILD_DEBUG});
+
+ if (!$debugOpened) {
+ if (open DEBUG, '>/dev/tty') {
+ $debugOpened = 1;
+ } else {
+ return;
+ }
+ }
+
+ my @args = split /\n/, "@_";
+ foreach (@args) {
+ $_ = '# ' . $_;
+ $_ .= "\n";
+ }
+
+ print DEBUG "\033[1;33m";
+ print DEBUG join '', @args;
+ print DEBUG "\033[0m";
+ DEBUG->flush;
+}
+
+
+##
+# error(message)
+#
+# Print an error message to stderr. It will be displayed in red.
+sub error {
+ print STDERR "\033[1;31m";
+ print STDERR $_[0];
+ print STDERR "\033[0m";
+ STDERR->flush;
+}
+
+
+##
+# checkCommand(file)
+# file: an command's filename.
+# Returns: the full path to $file, or undef if $file is not a valid command.
+#
+# Checks whether $file is an executable which is in $PATH or the working directory.
+#
+# Example:
+# checkCommand('gcc'); # Returns "/usr/bin/gcc"
+sub checkCommand {
+ my ($file, $file2) = split / /, $_[0];
+ $file = $file2 if ($file =~ /ccache/);
+
+ return abs_path($file) if (-x $file);
+ foreach my $dir (split /:+/, $ENV{PATH}) {
+ if (-x "$dir/$file") {
+ return "$dir/$file";
+ }
+ }
+ return undef;
+}
+
+##
+# empty(str)
+#
+# Checks whether $str is undefined or empty.
+sub empty {
+ return !defined($_[0]) || $_[0] eq '';
+}
+
+##
+# homeDir()
+#
+# Returns the user's home folder.
+sub homeDir {
+ if (!$ENV{HOME}) {
+ my $user = getpwuid(POSIX::getuid());
+ $ENV{HOME} = (getpwnam($user))[7];
+ }
+ return $ENV{HOME};
+}
+
+##
+# searchLib(basename, [extra_paths])
+# basename: the base name of the library.
+# extra_paths: a reference to an array, which contains extra folders in which to look for the library.
+# Returns: the absolute path to the library, or undef if not found.
+#
+# Get the absolute path of a (static or shared) library.
+#
+# Example:
+# searchLib("libfoo.so.1"); # Returns "/usr/lib/libfoo.so.1"
+sub searchLib {
+ my ($basename, $extra_paths) = @_;
+
+ if ($extra_paths) {
+ foreach my $path (reverse(@{$extra_paths})) {
+ return "$path/$basename" if (-f "$path/$basename");
+ }
+ }
+ foreach my $path ('/usr/local/lib', '/lib', '/usr/lib') {
+ return "$path/$basename" if (-f "$path/$basename");
+ }
+ return undef;
+}
+
+##
+# soname(lib)
+# lib: a filename to a shared library.
+# Returns: the soname.
+#
+# Get the soname of the specified shared library by reading
+# the SONAME section of the shared library file.
+sub soname {
+ my ($lib) = @_;
+ my ($r, $w);
+
+ if (open2($r, $w, 'objdump', '-p', $lib)) {
+ close $w;
+ my @lines = <$r>;
+ close $r;
+
+ my ($soname) = grep {/SONAME/} @lines;
+ $soname =~ s/.*?SONAME[ \t]+//;
+ $soname =~ s/\n//gs;
+ return $soname;
+
+ } else {
+ my ($soname) = $lib =~ /.*\/lib(.+)\.so/;
+ return $soname;
+ }
+}
+
+##
+# run(args...)
+# Returns: the command's exit code.
+#
+# Run a command with system().
+sub run {
+ # split the first item in @_ into "words". The `printf ...`
+ # takes care of respecting ' and " quotes so we don't split a
+ # quoted string that contains whitespace. If $cmd itself
+ # contains \n, this will still go wrong.
+ my $cmd = shift @_;
+ my @words = `printf '%s\n' $cmd`;
+ chomp @words;
+ my $status = system(@words, @_);
+ return 127 if ($status == -1);
+ return $status / 256 if ($status != 0);
+ return 0;
+}
+
+sub parseDataFile {
+ my ($file, $r_hash) = @_;
+
+ %{$r_hash} = ();
+ return if (!open FILE, "< $file");
+ foreach (<FILE>) {
+ next if (/^#/);
+ s/[\r\n]//g;
+ next if (length($_) == 0);
+
+ my ($key, $value) = split / /, $_, 2;
+ $r_hash->{$key} = $value;
+ }
+ close FILE;
+}
+
+sub writeDataFile {
+ my ($file, $r_hash) = @_;
+ return if (!open FILE, "> $file");
+ foreach my $key (sort(keys %{$r_hash})) {
+ print FILE "$key $r_hash->{$key}\n";
+ }
+ close FILE;
+}
+
+1;