#!/usr/bin/env perl

use strict;
use Config;

# Create/update symbolic links to libraries.

# This script may be useful to compile and link programs that
#   * do not provide a "configure" script, only a Makefile,
#   * need to link with static libraries (for efficiency reasons).
# e.g. BaCSeL <http://www.loria.fr/~stehle/>.

# The reason is that for compilation and conventional linking, one can
# use environment variables, such as C_INCLUDE_PATH, LIBRARY_PATH and
# LD_LIBRARY_PATH, but when one wants to link with a static library,
# one needs to either provide the full path to the library file or use
# non-standard compiler flags in the Makefile, i.e. which may not work
# on some platforms. This script makes the (recommended) former method
# a bit easier.

# Example (with BaCSeL):
#   $ ./liblinks lib libgmp.a libmpfr.a
#   $ make GMP=. DEFS="-DUSE_DPE -DZUSE_MPZ -DVBSE -DAUTOMATIC"

# Copyright 2006 Vincent Lefevre.
# LORIA / INRIA Lorraine, France.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along
# with this program; if not, see <https://www.gnu.org/licenses/>.

my ($proc) = '$Id: liblinks 171413 2024-09-01 12:25:23Z vinc17/qaa $'
  =~ /^.Id: (\S+) / or die;

@ARGV > 1 or $! = 1, die "Usage: $proc <directory> <library> ...\n";
my $dest = shift;
-d $dest or mkdir $dest
  or die "$proc: can't create directory $dest ($!)\n";

my (@paths,%paths);
foreach (split(':', $ENV{'LIBRARY_PATH'}),
         split(':', $ENV{'LD_LIBRARY_PATH'}),
         map { $Config{'osname'} =~ /linux/i &&
               $Config{'archname'} =~ /x86_64/i ? $_.'64' : $_ }
           qw(/usr/local/lib /lib /usr/lib))
  { push @paths, $_ unless $paths{$_}++ }

print "Searching directories:\n", map "  $_\n", @paths;

FILES: foreach my $lib (@ARGV)
  {
    my $dst = $dest eq '.' ? $lib : "$dest/$lib";

    my $link;
    if (lstat $dst)
      {
        if (-l _)
          {
            $link = readlink $dst;
          }
        else
          {
            warn "$proc: file $dst exists and is not a symbolic link\n";
            next;
          }
      }

    foreach my $dir (@paths)
      {
        -e "$dir/$lib" or next;  # test the existence first!
        $link eq "$dir/$lib" and next FILES;  # nothing to do.
        print "Symlinking $dst -> $dir/$lib\n";
        unlink $dst;  # in case there was already a symlink.
        symlink "$dir/$lib", $dst
          or warn "$proc: can't create symlink $dst ($!)\n";
        next FILES;
      }
    warn "$proc: can't find library $lib\n";
  }