Most portable g++ executable

87 views
Skip to first unread message

Rafal 'Raf256' Maj

unread,
Jan 10, 2004, 11:07:08 AM1/10/04
to
Hi,
what comamnd-lines options to add to
g++ file.cpp -o executable
so that resulting execuatable would be as portal as possible - i.e. it wil
run on all PC CPU architectures >= 386, and it will be independed of os
version (I think it has something to do with "static libc linking" ?)

TIA

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~l-.~~~~~~~~~~~~~~~~~~~
GG-1175498 ____| ]____,
Rafal 'Raf256' Maj X-( * )
Rafal(at)Raf256(dot)com ,"----------"

Paul Pluzhnikov

unread,
Jan 10, 2004, 2:44:01 PM1/10/04
to
"Rafal 'Raf256' Maj" <sp...@raf256.com> writes:

> what comamnd-lines options to add to
> g++ file.cpp -o executable
> so that resulting execuatable would be as portal as possible - i.e. it wil
> run on all PC CPU architectures >= 386,

Add '-m386'

> and it will be independed of os
> version (I think it has something to do with "static libc linking" ?)

On Linux, you almost certainly *do not* want static libc linking:
that will make your app break/cash going both backward and forward
in glibc versions. Here is one thread that discussed this issue:

http://groups.google.com/groups?threadm=0wB4a.1485%24nz3.300378258%40newssvr13.news.prodigy.com

What you probably *do* want, is static linking against libstdc++,
and not linking against libgcc_s (if building with g++-3.x).

It is surprizingly difficult to get rid of dynmaic libstdc++
dependency (you'd think that '-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic'
would do it, but it doesn't). You could build your gcc with
--disable-shared, or you could do this:

ln -s `g++ --print-file-name=libstdc++.a` .
g++ -m386 -L. file.cpp
rm libstdc++.a

Finally, to get rid of libgcc_s dependency, add '-static-libgcc'.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

Nils O. Selåsdal

unread,
Jan 11, 2004, 10:09:20 AM1/11/04
to
In article <m3isjja...@salmon.parasoft.com>, Paul Pluzhnikov wrote:
> "Rafal 'Raf256' Maj" <sp...@raf256.com> writes:
>
>> what comamnd-lines options to add to
>> g++ file.cpp -o executable
>> so that resulting execuatable would be as portal as possible - i.e. it wil
>> run on all PC CPU architectures >= 386,
>
> Add '-m386'
Usually the default.

>
>> and it will be independed of os
>> version (I think it has something to do with "static libc linking" ?)
>
> On Linux, you almost certainly *do not* want static libc linking:
> that will make your app break/cash going both backward and forward
> in glibc versions. Here is one thread that discussed this issue:
It this entierly true ? I've built many static apps, that works on RH 6.2
to RH9. Also a a pile of commercial applications I've downloaded
are statically linked, and seems to work wherever I run them.
Sure some things will break it, but what about linking
dynamically ? An app built on my Fedora box usually doesn't
run on glibc 2.2.x systems. Seems it links to specific
glibc 2.3.x symbols. Setting up an LSB build environment might solve alot
though.

Paul Pluzhnikov

unread,
Jan 11, 2004, 4:03:40 PM1/11/04
to
Nils O. Selåsdal <nose...@frisurf.no> writes:

> > On Linux, you almost certainly *do not* want static libc linking:

> It this entierly true ?

It is, if your app uses host name resolution, NIS, locales, etc.
Try compiling the test case below with '-static', then run
it on "backwards" system.

[Linking this test case statically on Fedora Core1 produces:
gethostbyname.c:14: warning: Using 'gethostbyname' in statically
linked applications requires at runtime the shared libraries from
the glibc version used for linking]

> Also a a pile of commercial applications I've downloaded
> are statically linked, and seems to work wherever I run them.

I am not aware of any commercial apps that are statically linked.
Care to name a few?

> Sure some things will break it, but what about linking
> dynamically ? An app built on my Fedora box usually doesn't
> run on glibc 2.2.x systems.

The thread I referenced tells you what you must do to prevent dynamic
linking breakage on "backwards" systems. Why don't you read it?

Cheers,

--- cut --- gethostbyname.c ---
#include <stdio.h>
#include <netdb.h>

main(int argc, char *argv[])
{
struct hostent *he;
char *host;

if (argc > 1)
host = argv[1];
else
host = "www.google.com";

if (0 == (he = gethostbyname(host))) {
perror("gethostbyname");
exit(1);
}

printf("%s: %s 0x%08X\n", host, he->h_name, he->h_addr_list[0]);
return 0;
}
--- cut ---

Bob R

unread,
Jan 12, 2004, 5:29:07 PM1/12/04
to

Paul Pluzhnikov wrote in message ...

>Nils O. Selåsdal <nose...@frisurf.no> writes:
>
<snip>

>
>It is, if your app uses host name resolution, NIS, locales, etc.
>Try compiling the test case below with '-static', then run
>it on "backwards" system.
>
>[Linking this test case statically on Fedora Core1 produces:
>gethostbyname.c:14: warning: Using 'gethostbyname' in statically
> linked applications requires at runtime the shared libraries from
> the glibc version used for linking]
>
>
>--- cut --- gethostbyname.c ---
>#include <stdio.h>
>#include <netdb.h>
>
>main(int argc, char *argv[]){
> struct hostent *he;
> char *host;
> if (argc > 1) host = argv[1];
> else host = "www.google.com";
> if (0 == (he = gethostbyname(host))) {
> perror("gethostbyname");
> exit(1);
> }
> printf("%s: %s 0x%08X\n", host, he->h_name, he->h_addr_list[0]);
> return 0;
>}
>--- cut ---

You are using a broken compiler! 'main' **always** returns an 'int';
int main(){}
The compiler should abort with an error on the code you supplied.

--
Bob R
POVrookie
--
MinGW (GNU compiler): http://www.mingw.com/
Dev-C++ IDE: http://www.bloodshed.net/
V IDE & V GUI: http://www.objectcentral.com/
POVray: http://www.povray.org/
Good C++ book: http://www.mindview.net/Books
alt.comp.lang.learn.c-c++: ftp://snurse-l.org/pub/acllc-c++/faq


Socks

unread,
Jan 12, 2004, 5:34:05 PM1/12/04
to
Bob R wrote:
> Paul Pluzhnikov wrote in message ...

>> #include <stdio.h>


>> #include <netdb.h>
>>
>> main(int argc, char *argv[]){
>> }

> You are using a broken compiler! 'main' **always** returns an 'int';
> int main(){}

in old-time C, not saying anything implied 'int', no longer true?

(you would have had to type 'void' to get a void main.)


Bob R

unread,
Jan 13, 2004, 7:11:55 PM1/13/04
to

Socks wrote in message ...

My old 2.95.3-7 GCC silently supplies the 'int' return in 'main'. But
newer GCCs are supposed to quit with an error. When you see '
main(...){}', it's an indicator that the code is 1998 or older. There
are still some teachers using this ancient syntax! (you'd think a
teacher should be educated on the standards.)
For your code to be 'standard compliant', you should always write;

int main(int argc, char** argv){
/* do stuff ... */
return 0; /* || EXIT_SUCCESS || EXIT_FAILURE */
}

Failure to supply the int return for main will result in you being
shot, drawn_and_quartered, stabbed, beaten, slapped, stoned(rocks, not
weed), hung, electrocuted, and/or flamed in NGs! <G>

It's a good idea to follow the standards so your code will compile on
any compliant compiler, not just the one you happen to have at the
time.

Socks

unread,
Jan 14, 2004, 12:03:30 PM1/14/04
to
On Wed, 14 Jan 2004 00:11:55 +0000, Bob R wrote:
> Socks wrote in message ...

>>in old-time C, not saying anything implied 'int', no longer true?


>>
>>(you would have had to type 'void' to get a void main.)
>
> My old 2.95.3-7 GCC silently supplies the 'int' return in 'main'. But
> newer GCCs are supposed to quit with an error. When you see '
> main(...){}', it's an indicator that the code is 1998 or older. There
> are still some teachers using this ancient syntax! (you'd think a
> teacher should be educated on the standards.)

it's a plot, i tell ya ;-). they just want me to replace my old (not that
old really, 1984) copy of "C: A Reference Manual".

> For your code to be 'standard compliant', you should always write;
>
> int main(int argc, char** argv){
> /* do stuff ... */
> return 0; /* || EXIT_SUCCESS || EXIT_FAILURE */ }
>
> Failure to supply the int return for main will result in you being shot,
> drawn_and_quartered, stabbed, beaten, slapped, stoned(rocks, not weed),
> hung, electrocuted, and/or flamed in NGs! <G>
>
> It's a good idea to follow the standards so your code will compile on
> any compliant compiler, not just the one you happen to have at the time.

i've used "int main(int argc, char* argv[])" myself but i went looking
based on what you said. i found references to it being a warning in the
new ISO, and that seems to be what gcc 3.2.2 does. from the man:

"-Wmain Warn if the type of main is suspicious. main should be a
function with external linkage, returning int, taking either zero
arguments, two, or three arguments of appropriate types."

and

"-Wreturn-type Warn whenever a function is defined with a return-type
that defaults to "int". Also warn about any "return" statement with no
return-value in a function whose return-type is not "void".

For C++, a function without return type always produces a diagnostic
message, even when -Wno-return-type is specified. The only exceptions are
main and functions defined in system headers."

this program produces no errors/warnings by default:

#include <stdio.h>

main (int argc, char *argv[])
{
printf("argc is %d\n",argc);
}

... but by now i'm sure we're all bored anyway :-)

Reply all
Reply to author
Forward
0 new messages