Multiarch: libraries/links not found...

Using applications, configuring, problems
Post Reply
Message
Author
User avatar
linuph
Posts: 128
Joined: Mon 04 Jun 2012, 02:29
Location: Philippines

Multiarch: libraries/links not found...

#1 Post by linuph »

Using Dpup Exprimo 5.X.3.4.10

The last I could find about the Multiarch thing is an article by Barry: http://bkhome.org/blog/?viewDetailed=02752.
The solution offered there, i.e. a symlink between directories, doesn't work for me: ln: failed to create symbolic link 'i386-linux-gnu/.': file exists. There is a 'i386-linux-gnu' directory in usr/lib so maybe that's the problem.
See the above link for more information about Multiarch.

The problem is that some libraries/links cannot be found during compiling/making and/or execution because these libraries/links are put in /usr/lib/i386-linux-gnu in stead of /usr/lib. Some of the applications that I compiled exhibit this behavior.

"Multiarch awareness' should be the solution for this, but it is not clear to me if that can be implemented, mainly because I do not understand much of it as yet.

So I decided to make my own solution, until something comes up in Puppy, prepared, cooked and ready to eat.

It is a bash script:

#!/bin/sh
# casi386 120922 - <linuph> - copy absolute symlinks i386.
# Ubuntu introduced a method to enable compilation and execution of a
# program for different platforms, e.g. i386, i486, i686.
# To that effect, some libraries are written to e.g. /usr/lib/i386-linux-gnu
# in stead of /usr/lib. As a consequence, required libraries cannot be
# found during compile/make and/or execution.
# Any symbolic links are also put in /usr/lib/i386-linux-gnu. This script
# copies these links from /usr/lib/i386-linux-gnu to /usr/lib with an
# absolute path. The original symlinks are kept as they are.

uldir="/usr/lib"
sddir="/usr/lib/i386-linux-gnu"

# See if sddir exists. If not, exit, otherwise sit down in sddir.
[[ $? -ne 0 ]] && echo "There is no directory $sddir. Nothing to do." && exit

cd $sddir

# Make a file of symbolic links in sddir.
find . -maxdepth 1 -type l > links.lst

# If no links are found (links.lst is empty), remove links.lst and exit.
[[ ! -s "links.lst" ]] && echo "No processable symlinks found. Nothing to do." && rm links.lst && exit

# Create ABSOLUTE symbolic links in /usr/lib.
# Note: we let it run into an error when the symlink in sddir already exists.
while read line
do
thislink=${line/'./'/} # remove leading "./"
thatlink=$uldir"/"$thislink
ln -s $(readlink -f $thislink) $thatlink
done < links.lst
rm links.lst
echo "Done."

# End of script, all done.


This script is one of my first deeper ventures in (Puppy) linux and bash and a good exercise. It is not perfect nor fool-proof. But it works.

I would appreciate any comments.

User avatar
Karl Godt
Posts: 4199
Joined: Sun 20 Jun 2010, 13:52
Location: Kiel,Germany

#2 Post by Karl Godt »

while read line ; do
[ "$line" ] || continue
> because checking for content. ' command "" ' further down can result in unexpected things .

readlink -f : would be better readlink -e ( exists ) . Test for readlink -[f|e] missing ie
ln -s $(readlink -f $thislink) $thatlink
readlink -e "$thislink" || continue
ln -s $(readlink -e "$thislink") "$thatlink"


And use doublequotes at the correct places to support paths with spaces a little better :
thatlink=$uldir"/"$thislink
thatlink="$uldir"/"$thislink"

User avatar
linuph
Posts: 128
Joined: Mon 04 Jun 2012, 02:29
Location: Philippines

#3 Post by linuph »

Thanks Karl, much appreciated!

aragon
Posts: 1698
Joined: Mon 15 Oct 2007, 12:18
Location: Germany

#4 Post by aragon »

You could also try to add your lib-dirs to LD_LIBRARY_PATH in /etc/profile

After the change, reboot and test if this makes any difference.

Good luck
Aragon

npierce
Posts: 858
Joined: Tue 29 Dec 2009, 01:40

#5 Post by npierce »

linuph wrote:I would appreciate any comments.
OK. I took a look at your script, and mostly it looks good.

I did see one thing that didn't look so good:
linuph wrote:sddir="/usr/lib/i386-linux-gnu"

# See if sddir exists. If not, exit, otherwise sit down in sddir.
[[ $? -ne 0 ]] && echo "There is no directory $sddir. Nothing to do." && exit
That test might not be working. "/usr/lib/i386-linux-gnu" is a valid string, even if there is no such directory, so setting sddir equal to it should always result in a return value of zero (success).

The following will test if the directory exists and if it is really a directory:

Code: Select all

[ ! -d "$sddir" ] && echo "There is no directory $sddir. Nothing to do." && exit
(In this particular script, you don't really need the quotation marks in the above test, because $sddir is set to a name with no spaces in it. But I agree with Karl that it is better to add them, because it is a good idea to get into the habit of using quotation marks: In future scripts that you write your code may run into filenames with spaces.)


linuph wrote:thislink=${line/'./'/} # remove leading "./"
I'm wondering what version of bash you are running. Using bash version "3.00.16(1)-release", I was unable to get the './' pattern to work as it did for you when using parameter expansion.

Bash refused to believe that the slash was part of the pattern. Instead it assumed that the slash in the pattern was the slash between the pattern and the replacement string, just as if I had not used the single quotation marks, and so it replaced only the dot. And then when it saw another slash it assumed that it was the replacement string.

To make it work I had to drop the single quotation marks and escape the slash by preceding it with a backslash.

This excerpt copied from my experimental shell session will illustrate:

Code: Select all

# sh
# echo $BASH_VERSION
3.00.16(1)-release
# FOO="./bar"
# echo ${FOO/'./'/}
//bar
# echo ${FOO/.//}
//bar
# echo ${FOO/.\//}
bar
# exit
exit
So to run on my Puppy I would need to change that line to:

Code: Select all

thislink=${line/.\//} # remove leading "./"
linuph wrote:This script is one of my first deeper ventures in (Puppy) linux and bash and a good exercise.
I'd say you are off to a good start. Your script shows that you've learned quite a bit already.

I learned something as well, from looking at your code. Until I read your script, I didn't know that parameter expansion would allow us to replace patterns. So thanks for introducing me to this.

User avatar
linuph
Posts: 128
Joined: Mon 04 Jun 2012, 02:29
Location: Philippines

#6 Post by linuph »

@npierce

Code: Select all

thislink=${line/'./'/} # remove leading "./"
bash-version shows:
GNU bash, version 4.2.10(2)-release (i486-puppy-linux-gnu).
It comes with Dpup Exprimo 5.X.3.4.10.

Code: Select all

[ ! -d "$sddir" ] && echo "There is no directory $sddir. Nothing to do." && exit
That's of course the way to do it. It's a leftover from a rough design that I forgot to change. Thanks.

npierce
Posts: 858
Joined: Tue 29 Dec 2009, 01:40

#7 Post by npierce »

You're welcome.

Thanks for the version info. I found a version 4 bash in the Quirky repository. It fixed the problem I had with the './' pattern. Thanks.

User avatar
linuph
Posts: 128
Joined: Mon 04 Jun 2012, 02:29
Location: Philippines

#8 Post by linuph »

@ aragon

That works too! Not wanting to touch /etc/profile, I added the following to /etc/profile.local:

Code: Select all

if [ -d /usr/lib/i386-linux-gnu ]; then
      LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/i386-linux-gnu
      PATH="$PATH:/usr/lib/i386-linux-gnu"
fi
Again I learned something new. Thanks!

User avatar
pemasu
Posts: 5474
Joined: Wed 08 Jul 2009, 12:26
Location: Finland

#9 Post by pemasu »

Interesting bit to read. For multiarch coverage you need to cover /lib also.
I would do it like this....since I am not much of coder:

Code: Select all

#!/bin/sh
cd /
ln -s ./ /lib/i386-linux-gnu
ln -s ./ /usr/lib/i386-linux-gnu
Of course there should not be those directories previously (with stuff inside), but that is the whole point. Not having anything there so that compilation and usage of those locations does not prevent anything.
So....woof moves stuff away from i386-linux-gnu to the /lib or /usr/lib, removes the previous stuff and creates symlink. It uses 2createpackages script for that.

Code: Select all

    #120316 hack for multiarch, move libs to standard locations...
    if [ "$ARCHDIR" ];then
     if [ -d sandbox2/lib/$ARCHDIR ];then
      cp -a -f --remove-destination sandbox2/lib/${ARCHDIR}/* sandbox2/lib/
      sync
      rm -rf sandbox2/lib/${ARCHDIR}
      ln -s ./ sandbox2/lib/${ARCHDIR}
     fi
     if [ -d sandbox2/usr/lib/$ARCHDIR ];then
      cp -a -f --remove-destination sandbox2/usr/lib/${ARCHDIR}/* sandbox2/usr/lib/
      sync
      rm -rf sandbox2/usr/lib/${ARCHDIR}
      ln -s ./ sandbox2/usr/lib/${ARCHDIR}
     fi
    fi
   ;;
This kind mechanism Barry uses with woof to cover multiarch problem with Precise and I have done so also with Wheezy packages based experimental build. Of course woof script is much more complicated, but the basics is above.

User avatar
linuph
Posts: 128
Joined: Mon 04 Jun 2012, 02:29
Location: Philippines

#10 Post by linuph »

I thought along the same lines as pemasu, but limited to copying symlinks to usr/lib and /lib, because then I can easily recognize which libs are Multiarch by just looking into /usr/lib/i386-linux-gnu. I think that aragon's solution (extend the library path) is an even better solution. For me it's a sort of keep an eye on what's happening while trying out new applications.

This matter came up for me because I have been playing around with the i3 window manager. It places libraries/symlinks in usr/lib/i386-linux-gnu.

In new distributions it wouldn't matter, of course. Many users don't need/want to know the details.

BTW I will post i3 shortly. For the experimenters....

aragon
Posts: 1698
Joined: Mon 15 Oct 2007, 12:18
Location: Germany

#11 Post by aragon »

I don't think that it is a very good idea to post packages for other with such an individual path-structure. This will lead to problems and cofusion... Just my personal opinion.

Aragon

User avatar
linuph
Posts: 128
Joined: Mon 04 Jun 2012, 02:29
Location: Philippines

#12 Post by linuph »

I just posted the i3 package. I tend to agree with aragon but at this moment it can't be avoided if one wants to try the latest applications.

Should we then post such not-for-the-casual-user applications in some dedicated thread or does it already exist? If so, blame my ignorance.

aragon
Posts: 1698
Joined: Mon 15 Oct 2007, 12:18
Location: Germany

#13 Post by aragon »

I think your remarks about the package are clear enough ;-)

Aragon

Post Reply