April 27, 2011
On 04/27/2011 11:51 AM, Nick Sabalausky wrote:
> "Kai Meyer"<kai@unixlords.com>  wrote in message
> news:ip9bro$1lak$1@digitalmars.com...
>> On 04/26/2011 02:28 PM, Nick Sabalausky wrote:
>>> Ok, so I guess statically linking against the stuff isn't the way to go,
>>> and
>>> apparently DLL hell is worse on linux. Sooo...What do I do?
>>>
>>> In the other thread, Spacen said: "The way to do this is to link against
>>> the
>>> oldest libc you need to
>>> support, thus making the binaries forward compatible"
>>>
>>> I know my way around Linux as a user, but with deeper system stuff like
>>> that
>>> I'm pretty much lost. I don't have a clue how to do what Spacen suggests
>>> or
>>> how to determine what version of libc I need. Can anyone help me out with
>>> that?
>>>
>>>
>>
>> Can you backup, and help me understand what the first problem was? The one
>> you thought was solvable by statically linking against glibc?
>>
>
> It was the thread "D CGI test: linux.so.2: bad ELF interpreter: No such file
> or directory".
>
> Reposted here:
>
> -------------------------
>
> I've made a little test CGI app:
>
> import std.conv;
> import std.stdio;
>
> void main()
> {
>   auto content = "<b><i>Hello world</i></b>";
>   auto headers =
> `HTTP/1.1 200 OK
> Content-Type: text/html; charset=UTF-8
> Content-Length: `~to!string(content.length);
>
>   while(readln().length>  1) {}
>
>   writeln(headers);
>   writeln();
>   writeln(content);
> }
>
> Works on Windows command line and through IIS. And it works on my Kubuntu
> 10.6 (CORRECTION: It's v10.04) command line. But if I copy the executable
> from my Kubuntu box to my
> web host's Debian server (CORRECTION: It's Red Hat, but there is another
> server I'd like to also run on that is Debian): Running it through Apache
> gives me a 500, and running it directly with ssh gives me:
>
> linux.so.2: bad ELF interpreter: No such file or directory
>
> I assume that error message is the cause of the 500 (can't tell for sure
> because the 500 isn't even showing up in my Apache error logs). But I'm not
> enough of a linux expert to have the slightest clue what that error message
> is all about. I don't need to actually compile it *on* the server do I? I
> would have thought that all (or at least most) Linux distros used the same
> executable format - especially (K)Ubuntu and Debian.
>
>
>

Ya, glibc tries very hard to be forward compatible, but it is quite often not very backwards compatible. Meaning, if you build on an older system, it should run on newer systems (forward compatible.) But if you build on newer systems, it's not always going to run on older systems (backwards compatible.)

The best solution is to either use LSB (which is a big hoary mess to get into, and isn't fully supported everywhere, and I don't think there's anything you can do to D to make it LSB compatible), build on the oldest distro, or build on each distro.

Ideally, for performance, you should build a binary for each distro. You should build one for Ubuntu separately from Debian, but if you don't ahve the time, building on Debian will likely run on Ubuntu, but not visa versa. Statically linking or dynamic linking isn't the answer, it's forward and backwards compatibility.

Personally, I build rpms for both RHEL/CentOS and Fedora on a semi-regular basis, and I usually build one to distribute on RHEL/CentOS separate from a build to distribute on Fedora.
April 27, 2011
"Spacen Jasset" <spacenjasset@yahoo.co.uk> wrote in message news:ip9n5d$27je$1@digitalmars.com...
> On 27/04/2011 18:51, Nick Sabalausky wrote:
>> "Kai Meyer"<kai@unixlords.com>  wrote in message news:ip9bro$1lak$1@digitalmars.com...
>>>
>>> Can you backup, and help me understand what the first problem was? The
>>> one
>>> you thought was solvable by statically linking against glibc?
>>>
>>
>> It was the thread "D CGI test: linux.so.2: bad ELF interpreter: No such
>> file
>> or directory".
>>
>> Reposted here:
>>
>> -------------------------
>>
>> I've made a little test CGI app:
>>
>> import std.conv;
>> import std.stdio;
>>
>> void main()
>> {
>>   auto content = "<b><i>Hello world</i></b>";
>>   auto headers =
>> `HTTP/1.1 200 OK
>> Content-Type: text/html; charset=UTF-8
>> Content-Length: `~to!string(content.length);
>>
>>   while(readln().length>  1) {}
>>
>>   writeln(headers);
>>   writeln();
>>   writeln(content);
>> }
>>
>> Works on Windows command line and through IIS. And it works on my Kubuntu
>> 10.6 (CORRECTION: It's v10.04) command line. But if I copy the executable
>> from my Kubuntu box to my
>> web host's Debian server (CORRECTION: It's Red Hat, but there is another
>> server I'd like to also run on that is Debian): Running it through Apache
>> gives me a 500, and running it directly with ssh gives me:
>>
>> linux.so.2: bad ELF interpreter: No such file or directory
>>
>> I assume that error message is the cause of the 500 (can't tell for sure
>> because the 500 isn't even showing up in my Apache error logs). But I'm
>> not
>> enough of a linux expert to have the slightest clue what that error
>> message
>> is all about. I don't need to actually compile it *on* the server do I? I
>> would have thought that all (or at least most) Linux distros used the
>> same
>> executable format - especially (K)Ubuntu and Debian.
>>
>>
>
> Yes well hmm. I've done this type of thing before, that is want to make something run on newer systems. And lo and behold our makefile used static linking with libc, so I can say authoritatively that in certain circumstances it does not work. (it it only going to work without doubt if you run it on the exact same system)
>
> I've just been to court today (small claims) and it's been a hard day, so before I rant on, can you tell us what version you want to run said binary on (distro and version) and what version you are compiling on.
>

I'm compiling on Kubuntu v10.04 (32-bit). There's two servers I want to run on, although info on them seems to be difficult to get:

1. Main server: I googled for ways to find the distro and version, and most didn't work (I think my SSH access is sandboxed.) But I was able to get this:

$ cat /proc/version
Linux version 2.6.18-164.15.1.el5.028stab068.9 (root@rhel5-build-x64) (gcc
version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Tue Mar 30 18:07:38 MSD
2010

So I guess it's Red Hat 4.1.2?

2. Another server: This one is some shitty host ( ipower.com ) that my client insists on using. There's no SSH access and they're extremely tight-lipped about server details. I couldn't even get them to confirm whether or not it was x86 - and that was after a half hour of trying to get those jokers to comprehend what "x86" and "CPU architecture" even *meant*. All I know is that their control panel reports the system as being "debian", and that despite all of that they still *claim* to support CGI.


>
> As an example, to solve this problem I have compiled on redhat 2ES and all binaries now work on redhat 2-3-4 ubuntu 10.10 and so on, i.e. those that are later in generation than redhat 2. And it all works fine.
>
> This is what I suggest, if it is possible. i.e. compile on redhat 2, or perhaps 3.
>
> Perhaps if you post your build system version and flavour and target system I'll be able to give you a better answer.
>
> try lsb_release for this, if you aren't sure (and it's available as a command)
>
> jason@ionrift:~$ lsb_release -a
> No LSB modules are available.
> Distributor ID: Ubuntu
> Description:    Ubuntu 10.04.2 LTS
> Release:        10.04
> Codename:       lucid
>
> otherwise cat /etc/*release*
>

On my system, the one I'm compiling on, I get:

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 10.04.1 LTS
Release:        10.04
Codename:       lucid

On the main server I just get:

$ lsb_release -a
-jailshell: lsb_release: command not found



April 27, 2011
"Nick Sabalausky" <a@a.a> wrote in message news:ip9va1$2lbe$1@digitalmars.com...
> "Spacen Jasset" <spacenjasset@yahoo.co.uk> wrote in message news:ip9n5d$27je$1@digitalmars.com...
>>
>> try lsb_release for this, if you aren't sure (and it's available as a command)
>>
>> jason@ionrift:~$ lsb_release -a
>> No LSB modules are available.
>> Distributor ID: Ubuntu
>> Description:    Ubuntu 10.04.2 LTS
>> Release:        10.04
>> Codename:       lucid
>>
>> otherwise cat /etc/*release*
>>
>
> On my system, the one I'm compiling on, I get:
>
> $ lsb_release -a
> No LSB modules are available.
> Distributor ID: Ubuntu
> Description:    Ubuntu 10.04.1 LTS
> Release:        10.04
> Codename:       lucid
>
> On the main server I just get:
>
> $ lsb_release -a
> -jailshell: lsb_release: command not found
>

On the main server, cat /etc/*release* doesn't work either:

$ cat /etc/*release*
cat: cat /etc/*release*: No such file or directory



April 28, 2011
On 27/04/2011 21:56, Nick Sabalausky wrote:
> "Nick Sabalausky"<a@a.a>  wrote in message
> news:ip9va1$2lbe$1@digitalmars.com...
>> "Spacen Jasset"<spacenjasset@yahoo.co.uk>  wrote in message
>> news:ip9n5d$27je$1@digitalmars.com...
>>>
>>> try lsb_release for this, if you aren't sure (and it's available as a
>>> command)
>>>
>>> jason@ionrift:~$ lsb_release -a
>>> No LSB modules are available.
>>> Distributor ID: Ubuntu
>>> Description:    Ubuntu 10.04.2 LTS
>>> Release:        10.04
>>> Codename:       lucid
>>>
>>> otherwise cat /etc/*release*
>>>
>>
>> On my system, the one I'm compiling on, I get:
>>
>> $ lsb_release -a
>> No LSB modules are available.
>> Distributor ID: Ubuntu
>> Description:    Ubuntu 10.04.1 LTS
>> Release:        10.04
>> Codename:       lucid
>>
>> On the main server I just get:
>>
>> $ lsb_release -a
>> -jailshell: lsb_release: command not found
>>
>
> On the main server, cat /etc/*release* doesn't work either:
>
> $ cat /etc/*release*
> cat: cat /etc/*release*: No such file or directory
>
>
>

I see. It looks like you are trying to run at least on debian 4 yes.


What I would suggest you do is get the oddest debian or centos distribution you can, use a virtual box, and build on that. e.g. centos 3

It is possible to get "compat libraries" for some distributions, but that may just be more hassle.


You *can* by the way statically link any libraries (if you need to), except libc.so. As other libraries don't call the kernel directly.

something like this:

gcc obects.o -Wl,-Bstatic -lc++ -lfoo -lfish -Wl,-Bdynamic



The way to then check if the binary will run on an older (or newer system) is

ldd <executable> or library. It will then tell you what it will bind to, or if it cannot find any particular library.
April 28, 2011
On 04/27/2011 10:40 PM, Nick Sabalausky wrote:
> 1. Main server: I googled for ways to find the distro and version, and most
> didn't work (I think my SSH access is sandboxed.) But I was able to get
> this:
>
> $ cat /proc/version
> Linux version 2.6.18-164.15.1.el5.028stab068.9 (root@rhel5-build-x64) (gcc
> version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Tue Mar 30 18:07:38 MSD
> 2010
>
> So I guess it's Red Hat 4.1.2?

It looks like the 4.1.2 is the gcc version, and you are using Red Hat 5 (rhel5).
Also it looks like the sever is 64 bits, and you're compiling on a 32 bits machine, so does the server support multilib?

-- 
Mike Wey
April 28, 2011
"Mike Wey" <mike-wey@example.com> wrote in message news:ipca9t$tml$1@digitalmars.com...
> On 04/27/2011 10:40 PM, Nick Sabalausky wrote:
>> 1. Main server: I googled for ways to find the distro and version, and
>> most
>> didn't work (I think my SSH access is sandboxed.) But I was able to get
>> this:
>>
>> $ cat /proc/version
>> Linux version 2.6.18-164.15.1.el5.028stab068.9 (root@rhel5-build-x64)
>> (gcc
>> version 4.1.2 20080704 (Red Hat 4.1.2-46)) #1 SMP Tue Mar 30 18:07:38 MSD
>> 2010
>>
>> So I guess it's Red Hat 4.1.2?
>
> It looks like the 4.1.2 is the gcc version, and you are using Red Hat 5
> (rhel5).
> Also it looks like the sever is 64 bits, and you're compiling on a 32 bits
> machine, so does the server support multilib?
>

I'm sure I'll end up finding out... ;)


April 29, 2011
On 26.04.2011 21:44, Spacen Jasset wrote:

> On 26/04/2011 20:10, Steven Schveighoffer wrote:
> ...
>> I don't think static linking is officially supported any more.
> It is but only for OS binaries. Some systems infact, like AIX and Windows, do no support it at all.

  Windows does - there are static versions of C runtime and some others. Linux libc is not really very special, it only provides nice interface to syscalls.

  Actually, static linking is useful sometimes, and it is not always possible to link dynamically.

  Example: Fedora 14 and CentOS 5.5 shared libs are incompatible, though static binaries run on both - flawlessly. The main problem is that some dependencies are not satisfied through compatibility layer, as not all libs provide that (like libxml2 or
some other), thus, building on CentOS wouldn't really help (unless everything but libc will be linked statically anyway). Linux is now in "DLL hell" more than any Windows ever...

  And, by the way, D can be used for OS binaries as well ;) Though, I would look into direction of uClibc - smaller footprint and almost the same functionality, and it can be safely linked statically.

/Alexander
April 29, 2011
On 26.04.2011 21:10, Steven Schveighoffer wrote:

> It's a bad idea to statically link libc.  This is from the glibc maintainer:

  Well, I would say - bad idea to statically link glibc, but there are alternatives (mentioned previously uClibc).

  Good point from the link: "...more efficient use of physical memory. All processes share the same physical pages for the code in the DSOs." makes me wonder, when druntime/phobos will be in DSO? ;)

/Alexander
April 29, 2011
On 29/04/2011 01:46, Alexander wrote:
> On 26.04.2011 21:44, Spacen Jasset wrote:
>
>> On 26/04/2011 20:10, Steven Schveighoffer wrote:
>> ...
>>> I don't think static linking is officially supported any more.
>> It is but only for OS binaries. Some systems infact, like AIX and Windows, do no support it at all.
>
>    Windows does - there are static versions of C runtime and some others. Linux libc is not really very special, it only provides nice interface to syscalls.
That's because in windows the syscalls and the c libraries are in different libraries.

You still *cannot* link statically to kernel32.dll. That's the difference. Linux glibc contains the C library functions *and* the syscalls, which is the bit that causes the problems.

msvcrt.dll and msvcrt.lib don't have any syscalls in them. they call though kernel32.dll dynamically.

The answer therefore on linux as it is on windows: do not to statically link anything that calls the kernel, which in this case is glibc

Arguably the ability to link statically to libc should be removed from the compiler as it seems to confuse everyone as to what is actually happening and what the outcome will be.


>
>    Actually, static linking is useful sometimes, and it is not always possible to link dynamically.
>
>    Example: Fedora 14 and CentOS 5.5 shared libs are incompatible, though static binaries run on both - flawlessly. The main problem is that some dependencies are not satisfied through compatibility layer, as not all libs provide that (like libxml2 or
> some other), thus, building on CentOS wouldn't really help (unless everything but libc will be linked statically anyway). Linux is now in "DLL hell" more than any Windows ever...
>
>    And, by the way, D can be used for OS binaries as well ;) Though, I would look into direction of uClibc - smaller footprint and almost the same functionality, and it can be safely linked statically.
>
> /Alexander

I don't know about any of that. All I say is software was built on Centos 3 and it runs on the then company I was working for supported platforms.

Which is redhat 3,4,5 + and Suse 9.something + That is 32bit and 64 bit by the way too.

It also runs on ubuntu (since about version 6ish +, upto 10, and I dare say beyond) and fedora, but rekon it hasn't been tried recently on Fedora 14 as it's not a supported platform. This all happens from one binary compiled on Centos 3


There was a bug, that I had to fix, and that was a crash on something like Redhat 4, because at the time libc was being statically linked. I can't remember the syscall that caused problem now, I have a feeling it was BSD sockets related.

libc is designed to be forward compatible only, if you dynamically link it. The symbols within are versioned and the correct ones bound at runtime.

I pipe up about all this because I've been though it all, and did not understand at the time what was wrong with static linking, but then you see the difference between Posix type platforms and windows, and what libc *actually is*, then it all makes sense.
April 29, 2011
On 29.04.2011 11:41, Spacen Jasset wrote:

> You still *cannot* link statically to kernel32.dll. That's the difference. Linux glibc contains the C library functions *and* the syscalls, which is the bit that causes the problems.

  But at least I know, that no matter where I am, as long as I am using kernel32 only (no more dependencies), it will work on *any* Windows system (obviously, keeping backward compatibility in mind - something compiled on WinXP will work on all later
versions) - which is not he case of Linux/glibc, unfortunately.

> msvcrt.dll and msvcrt.lib don't have any syscalls in them. they call though kernel32.dll dynamically.

  Actually, they do. Calling kernel32 is like making a syscall, that's the base of Win32 API, which is equivalent of Linux syscall.

> The answer therefore on linux as it is on windows: do not to statically link anything that calls the kernel, which in this case is glibc

  As there alternatives exists (like mentioned uClibc), which can be linked statically - this is more policy than technical limitation. glibc still can be linked statically, and will work - but it becomes *very* dependent on other stuff, which is
dynamic only (sometimes) - that's why developers do not want to support static versions.

> I don't know about any of that. All I say is software was built on Centos 3 and it runs on the then company I was working for supported platforms.

  That's the keyword - "supported platform". In Windows world, any version is "supported" - in Linux world, OTOH - there are dozens of platforms, sharing same kernel but hardly compatible.

> libc is designed to be forward compatible only, if you dynamically link it. The symbols within are versioned and the correct ones bound at runtime.

  Probably you mean "backward compatible"? Forward compatibility means that all previous versions will accept applications compiled with newer versions, which is obviously not the case of glibc.

  So I'd say that unless and until *any* binary compiled on *any* Linux distribution (same or newer kernel version) will be accepted by all other Linux systems (I bet it will never happen though), it is a bit too early to rule out static linking.

/Alexander