Re[2]: Static build of mc
Sorry it took so long, but I've documented the steps to my final solution in my blog here: http://david.leighweb.com/2017/01/07/install-midnight-commander-on-a-shared-hosting-account/ It works great for me now! -- Original Message -- From: "Yury V. Zaytsev" <y...@shurup.com> To: "David Leigh" <da...@leighweb.com> Cc: "Erdmut Pfeifer" <e.pfei...@science-computing.de>; mc@gnome.org Sent: 9/13/2016 8:42:12 PM Subject: RE: Static build of mc On Tue, 13 Sep 2016, David Leigh wrote: Wow! This worked (with just a few minor glitches) RIGHT OUT OF THE BOX! FIRST execution and I had something that worked. I used the version of mc that yum installed with the CentOS 6.8. That was like 4.7.0 or something. Now that I have a baseline that works, I may see if I can get a more recent package to work (upgrade my CentOS box and upgrade mc). For latest (unofficial) binaries, including CentOS 6, see: http://www.midnight-commander.org/wiki/Binaries -- Sincerely yours, Yury V. Zaytsev___ mc mailing list https://mail.gnome.org/mailman/listinfo/mc
RE: Static build of mc
On Tue, 13 Sep 2016, David Leigh wrote: Wow! This worked (with just a few minor glitches) RIGHT OUT OF THE BOX! FIRST execution and I had something that worked. I used the version of mc that yum installed with the CentOS 6.8. That was like 4.7.0 or something. Now that I have a baseline that works, I may see if I can get a more recent package to work (upgrade my CentOS box and upgrade mc). For latest (unofficial) binaries, including CentOS 6, see: http://www.midnight-commander.org/wiki/Binaries -- Sincerely yours, Yury V. Zaytsev ___ mc mailing list https://mail.gnome.org/mailman/listinfo/mc
RE: Static build of mc
Wow! This worked (with just a few minor glitches) RIGHT OUT OF THE BOX! FIRST execution and I had something that worked. I used the version of mc that yum installed with the CentOS 6.8. That was like 4.7.0 or something. Now that I have a baseline that works, I may see if I can get a more recent package to work (upgrade my CentOS box and upgrade mc). I'll get all the minor glitches worked out and then post a follow-up with the details. Amazing! Thanks! -Original Message- From: Erdmut Pfeifer [mailto:e.pfei...@science-computing.de] Sent: Monday, September 12, 2016 06:24 PM To: da...@leighweb.com Cc: mc@gnome.org Subject: Re: Static build of mc You don't necessarily need to create a statically linked version to get it to run on a different box. just pack up all required shared libs (use "ldd" to find out which) plus the dynamic loader itself. The dynamic loader is normally invoked indirectly via the system, but nothing keeps you from calling it directly, passing it the name of the dynamically linked binary to run and the directory where the packed-up libs reside - see "man ld.so" for details ("ld.so" is the generic name of the dynamic loader, the actual name on today's 64-bit boxes is typically ld-linux-x86-64.so.2, which itself is a symlink to ld-.so). The loader is a statically linked binary, and thus doesn't need any libs itself. As I found myself needing something like this rather frequently, I've put together a little Perl script which automates these steps. Please find it included below (I've inlined it, as I'm not sure if the mailing list does allow attachments). Call it without arguments to get a short usage message. If you have installed/built a version of mc which works on your local machine/VirtualBox, you could, for example, say $ cp-deps mc ~/mytools/mc (~/mytools/mc is the directory where everything will be put) The script creates a basic wrapper which you can then tweak as needed. In the case of mc, you probably want to set the env variable MC_DATADIR to point to a directory with mc's helper/config files (which you must copy yourself (e.g. /usr/lib/mc, /usr/share/mc, /etc/mc) - the script doesn't know anything about the specifics of certain programs, it just copies the files mentioned in the ldd output): #!/bin/sh # adjust this path if you move the installation myINSTDIR=/home/username/mytools/mc myEXE=$myINSTDIR/mc.bin myLIBDIR=$myINSTDIR/lib myLDSO=$myLIBDIR/ld.so export MC_DATADIR=$myINSTDIR/mclib # uncomment to enable debug output (like ldd) #$myLDSO --library-path $myLIBDIR --list $myEXE exec $myLDSO --library-path $myLIBDIR $myEXE "$@" If using MC_DATADIR doesn't work, you might try putting the files mc warns about not finding in ~/.local/share/mc, ~/.mc or similar. (Where mc looks for files seems to depend on buildtime configuration - "strace -efile ..." is your friend to find out where it actually looks) Finally, scp or rsync everything to your remote box, make sure myINSTDIR is set correctly, and put the wrapper (or a symlink to it) somewhere on your $PATH. You should then be able to start mc even though the remote box has an incompatible glibc version, etc. Good luck! --- start of the script cp-deps --- #!/usr/bin/perl -w use strict; sub usage { print "\nCopy shared library dependencies of an executable into some directory\n\n"; print "Usage: $0 []\n"; print " e.g. $0 vim [vim_standalone]\n\n"; exit 1; } usage() unless @ARGV >= 1; my ($program, $destdir) = @ARGV; my ($prg_name) = $program =~ m|([^/]+)/*$|; $destdir = "./${prg_name}_standalone" unless $destdir; my $libdir = "$destdir/lib"; sub copy { my $lib = shift; print "$lib\n"; system 'cp', '-fa', $lib, $libdir; } my $exe = qx(which $program) # ldd doesn't look in PATH or die "Failed to determine path of $program"; chomp $exe; for my $dir ($destdir, $libdir) { unless (-d $dir) { mkdir $dir or die "Couldn't create $dir: $!"; } } for my $dep (split /\n/, qx(ldd $exe) ) { my ($lib) = $dep =~ m|=>\s+(\S+)\s+\(0x|; # extract lib path unless (defined $lib) { # we want the dynamic loader, too ($lib) = $dep =~ m|(/lib.*/ld-linux.*\.so\S*)|; if (defined $lib) { my ($ld_so) = $lib =~ m|([^/]+)$|; symlink $ld_so, "$libdir/ld.so"; # additional unified link } } if (defined $lib) { unless (-l $lib) { copy $lib; } else { # symlink print "$lib\n"; my ($name) = $lib =~ m|([^/]+)$|; # orig link name while (-l $lib) { # resolve... my $path = $lib; $lib = readlink $lib; unless ($lib =~ m|^/|) { # relative ? (my $dir = $path) =~ s|[^/]+$||;
RE: Static build of mc
Thank you Erdmut. I'll look at Yury's solution and yours and see what happens. At least you've given me hope to keep trying (and I'll learn even more in the process!) -Original Message- From: Erdmut Pfeifer [mailto:e.pfei...@science-computing.de] Sent: Monday, September 12, 2016 06:24 PM To: da...@leighweb.com Cc: mc@gnome.org Subject: Re: Static build of mc You don't necessarily need to create a statically linked version to get it to run on a different box. just pack up all required shared libs (use "ldd" to find out which) plus the dynamic loader itself. The dynamic loader is normally invoked indirectly via the system, but nothing keeps you from calling it directly, passing it the name of the dynamically linked binary to run and the directory where the packed-up libs reside - see "man ld.so" for details ("ld.so" is the generic name of the dynamic loader, the actual name on today's 64-bit boxes is typically ld-linux-x86-64.so.2, which itself is a symlink to ld-.so). The loader is a statically linked binary, and thus doesn't need any libs itself. As I found myself needing something like this rather frequently, I've put together a little Perl script which automates these steps. Please find it included below (I've inlined it, as I'm not sure if the mailing list does allow attachments). Call it without arguments to get a short usage message. If you have installed/built a version of mc which works on your local machine/VirtualBox, you could, for example, say $ cp-deps mc ~/mytools/mc (~/mytools/mc is the directory where everything will be put) The script creates a basic wrapper which you can then tweak as needed. In the case of mc, you probably want to set the env variable MC_DATADIR to point to a directory with mc's helper/config files (which you must copy yourself (e.g. /usr/lib/mc, /usr/share/mc, /etc/mc) - the script doesn't know anything about the specifics of certain programs, it just copies the files mentioned in the ldd output): #!/bin/sh # adjust this path if you move the installation myINSTDIR=/home/username/mytools/mc myEXE=$myINSTDIR/mc.bin myLIBDIR=$myINSTDIR/lib myLDSO=$myLIBDIR/ld.so export MC_DATADIR=$myINSTDIR/mclib # uncomment to enable debug output (like ldd) #$myLDSO --library-path $myLIBDIR --list $myEXE exec $myLDSO --library-path $myLIBDIR $myEXE "$@" If using MC_DATADIR doesn't work, you might try putting the files mc warns about not finding in ~/.local/share/mc, ~/.mc or similar. (Where mc looks for files seems to depend on buildtime configuration - "strace -efile ..." is your friend to find out where it actually looks) Finally, scp or rsync everything to your remote box, make sure myINSTDIR is set correctly, and put the wrapper (or a symlink to it) somewhere on your $PATH. You should then be able to start mc even though the remote box has an incompatible glibc version, etc. Good luck! --- start of the script cp-deps --- #!/usr/bin/perl -w use strict; sub usage { print "\nCopy shared library dependencies of an executable into some directory\n\n"; print "Usage: $0 []\n"; print " e.g. $0 vim [vim_standalone]\n\n"; exit 1; } usage() unless @ARGV >= 1; my ($program, $destdir) = @ARGV; my ($prg_name) = $program =~ m|([^/]+)/*$|; $destdir = "./${prg_name}_standalone" unless $destdir; my $libdir = "$destdir/lib"; sub copy { my $lib = shift; print "$lib\n"; system 'cp', '-fa', $lib, $libdir; } my $exe = qx(which $program) # ldd doesn't look in PATH or die "Failed to determine path of $program"; chomp $exe; for my $dir ($destdir, $libdir) { unless (-d $dir) { mkdir $dir or die "Couldn't create $dir: $!"; } } for my $dep (split /\n/, qx(ldd $exe) ) { my ($lib) = $dep =~ m|=>\s+(\S+)\s+\(0x|; # extract lib path unless (defined $lib) { # we want the dynamic loader, too ($lib) = $dep =~ m|(/lib.*/ld-linux.*\.so\S*)|; if (defined $lib) { my ($ld_so) = $lib =~ m|([^/]+)$|; symlink $ld_so, "$libdir/ld.so"; # additional unified link } } if (defined $lib) { unless (-l $lib) { copy $lib; } else { # symlink print "$lib\n"; my ($name) = $lib =~ m|([^/]+)$|; # orig link name while (-l $lib) { # resolve... my $path = $lib; $lib = readlink $lib; unless ($lib =~ m|^/|) { # relative ? (my $dir = $path) =~ s|[^/]+$||; $lib = $dir.$lib; } } copy $lib; # resolved path my ($file) = $lib =~ m|([^/]+)$|; # name of resolved/copied file my $lnk = "$libdir/$name"; unlink $lnk; symlink $file, $lnk; # create
Re: Static build of mc
On Mon, 12 Sep 2016, da...@leighweb.com wrote: They told me that the server is a CentOS 6 box. I see traces of CloudLinux and CageFS in my user space as well. This doesn't sound good, just make sure you aren't constrained to jailshell or whatever CloudLinux calls it, because previously I remember that in that case you somehow couldn't even properly allocate a tty... it'd be stupid if you'll manage to compile mc and then figure it doesn't run. You can check it with screen if it's already installed on the target host, if that works, then mc is also likely to work. I would have actually just extracted pre-compiled mc from an rpm and put all of its library dependencies (also extracted from rpms) on LD_LIBRARY_PATH as the other poster suggests, but yeah, you can do it the hard way too. export GLIB_LIBDIR=/root/myglibc/build/lib The following seemed to work for me: $ GLIB_LIBDIR=/usr/lib ../configure export LD_LIBRARY_PATH=/root/myglibc/build/lib You don't need this. -- Sincerely yours, Yury V. Zaytsev ___ mc mailing list https://mail.gnome.org/mailman/listinfo/mc
Re: Static build of mc
On Mon, 12 Sep 2016, Erdmut Pfeifer wrote: You don't necessarily need to create a statically linked version to get it to run on a different box. just pack up all required shared libs (use "ldd" to find out which) plus the dynamic loader itself. The dynamic loader is normally invoked indirectly via the system, but nothing keeps you from calling it directly, passing it the name of the dynamically linked binary to run and the directory where the packed-up libs reside - see "man ld.so" for details ("ld.so" is the generic name of the dynamic loader, the actual name on today's 64-bit boxes is typically ld-linux-x86-64.so.2, which itself is a symlink to ld-.so). The loader is a statically linked binary, and thus doesn't need any libs itself. I'm not quite sure why it needs to be so complicated. Why can't you simply use the loader from the target system and set LD_LIBRARY_PATH accordingly? -- Sincerely yours, Yury V. Zaytsev ___ mc mailing list https://mail.gnome.org/mailman/listinfo/mc
Re: Static build of mc
You don't necessarily need to create a statically linked version to get it to run on a different box. just pack up all required shared libs (use "ldd" to find out which) plus the dynamic loader itself. The dynamic loader is normally invoked indirectly via the system, but nothing keeps you from calling it directly, passing it the name of the dynamically linked binary to run and the directory where the packed-up libs reside - see "man ld.so" for details ("ld.so" is the generic name of the dynamic loader, the actual name on today's 64-bit boxes is typically ld-linux-x86-64.so.2, which itself is a symlink to ld-.so). The loader is a statically linked binary, and thus doesn't need any libs itself. As I found myself needing something like this rather frequently, I've put together a little Perl script which automates these steps. Please find it included below (I've inlined it, as I'm not sure if the mailing list does allow attachments). Call it without arguments to get a short usage message. If you have installed/built a version of mc which works on your local machine/VirtualBox, you could, for example, say $ cp-deps mc ~/mytools/mc (~/mytools/mc is the directory where everything will be put) The script creates a basic wrapper which you can then tweak as needed. In the case of mc, you probably want to set the env variable MC_DATADIR to point to a directory with mc's helper/config files (which you must copy yourself (e.g. /usr/lib/mc, /usr/share/mc, /etc/mc) - the script doesn't know anything about the specifics of certain programs, it just copies the files mentioned in the ldd output): #!/bin/sh # adjust this path if you move the installation myINSTDIR=/home/username/mytools/mc myEXE=$myINSTDIR/mc.bin myLIBDIR=$myINSTDIR/lib myLDSO=$myLIBDIR/ld.so export MC_DATADIR=$myINSTDIR/mclib # uncomment to enable debug output (like ldd) #$myLDSO --library-path $myLIBDIR --list $myEXE exec $myLDSO --library-path $myLIBDIR $myEXE "$@" If using MC_DATADIR doesn't work, you might try putting the files mc warns about not finding in ~/.local/share/mc, ~/.mc or similar. (Where mc looks for files seems to depend on buildtime configuration - "strace -efile ..." is your friend to find out where it actually looks) Finally, scp or rsync everything to your remote box, make sure myINSTDIR is set correctly, and put the wrapper (or a symlink to it) somewhere on your $PATH. You should then be able to start mc even though the remote box has an incompatible glibc version, etc. Good luck! --- start of the script cp-deps --- #!/usr/bin/perl -w use strict; sub usage { print "\nCopy shared library dependencies of an executable into some directory\n\n"; print "Usage: $0 []\n"; print " e.g. $0 vim [vim_standalone]\n\n"; exit 1; } usage() unless @ARGV >= 1; my ($program, $destdir) = @ARGV; my ($prg_name) = $program =~ m|([^/]+)/*$|; $destdir = "./${prg_name}_standalone" unless $destdir; my $libdir = "$destdir/lib"; sub copy { my $lib = shift; print "$lib\n"; system 'cp', '-fa', $lib, $libdir; } my $exe = qx(which $program) # ldd doesn't look in PATH or die "Failed to determine path of $program"; chomp $exe; for my $dir ($destdir, $libdir) { unless (-d $dir) { mkdir $dir or die "Couldn't create $dir: $!"; } } for my $dep (split /\n/, qx(ldd $exe) ) { my ($lib) = $dep =~ m|=>\s+(\S+)\s+\(0x|; # extract lib path unless (defined $lib) { # we want the dynamic loader, too ($lib) = $dep =~ m|(/lib.*/ld-linux.*\.so\S*)|; if (defined $lib) { my ($ld_so) = $lib =~ m|([^/]+)$|; symlink $ld_so, "$libdir/ld.so"; # additional unified link } } if (defined $lib) { unless (-l $lib) { copy $lib; } else { # symlink print "$lib\n"; my ($name) = $lib =~ m|([^/]+)$|; # orig link name while (-l $lib) { # resolve... my $path = $lib; $lib = readlink $lib; unless ($lib =~ m|^/|) { # relative ? (my $dir = $path) =~ s|[^/]+$||; $lib = $dir.$lib; } } copy $lib; # resolved path my ($file) = $lib =~ m|([^/]+)$|; # name of resolved/copied file my $lnk = "$libdir/$name"; unlink $lnk; symlink $file, $lnk; # create directory-local link } print "\n"; } } my ($exe_name) = $exe =~ m|([^/]+)$|; system 'cp', '-faL', $exe, "$destdir/$exe_name.bin"; # use Cwd; my $instdir = Cwd::realpath($destdir); my $wrapper = "$destdir/$exe_name"; open my $fh, ">", $wrapper or die "Couldn't create wrapper $wrapper: $!"; print $fh <<"EOF"; #!/bin/sh # adjust this path if you move the installation myINSTDIR=$instdir myEXE=\$myINSTDIR/$exe_name.bin myLIBDIR=\$myINSTDIR/lib myLDSO=\$myLIBDIR/ld.so # uncomment to enable debug output (like ldd)