0

I know this is a very basic question but while I found similar problem I didn't find a solution...

I have the same problem with this simple program:

#include <stdio.h>

void main()
{
    printf("Hi\n");
    fflush(stdout);
}

If I compile with gcc main.c, I have no problem.

If I compile with gcc -c main.c and then link with ld -o main main.o, I obtain the error undefined reference for puts, stdout and fflush. I added the -lc at the end and the binary file is created with just a warnig on the _start point but when I exec the program, it returns a generic "File not found" error. If I'm not wrong the problem is that the linker is using libc.so.1 that does not exists instead of, I think, libc.so.6: with readelf -a main

[Requesting program interpreter: /usr/lib/libc.so.1]

Does anyone know what is wrong? It is some environment/system problem or I have to change the ld options? How?

Thank you and sorry for the "stupid" question... (and for my poor "English")

EDIT: "solved" (see below), just to add the new ld options obtained form gcc -v main.c [COLLECT_GCC_OPTIONS] that I'm trying to reduce at the min:

ld -o main main.o --hash-style=gnu --as-needed -dynamic-linker /lib/ld-linux.so.2 -z relro /usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crt1.o /usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crti.o /usr/lib/gcc/i686-linux-gnu/5/crtbegin.o -L/usr/lib/gcc/i686-linux-gnu/5 -L/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu -L/usr/lib/gcc/i686-linux-gnu/5/../../../../lib -L/lib/i386-linux-gnu -L/lib/../lib -L/usr/lib/i386-linux-gnu -L/usr/lib/../lib -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-linux-gnu/5/crtend.o /usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/crtn.o

EDIT2: to start the program, I think the min is

ld -o main main.o --as-needed -dynamic-linker /lib/ld-linux.so.2 -lc

It returns a segmentation error (I think for the missed link to crt*)

1 Answers1

2

You can't just link an object file with noting to obtain an executable. You need to link with libraries defining the symbols needed by the object file. Since any C program needs some startup code to initialize main's argc and argv, you likely need to at least link with a file usually called crt0.o, probably also with the C standard library.

That's quite involved. If you run a verbose compilation with gcc -v you can see the actual link command.

Jens
  • 69,818
  • 15
  • 125
  • 179
  • Yes, thank you, I solved after lookin at gcc -v as suggested also above – user7707645 May 08 '17 at 09:59
  • *You can't just link an object file with noting to obtain an executable.* - True for C compiler output, but you *can* do that for an object file built from hand-written asm that defines a `_start`. (Or even a hacky C program that defines a `_start`.) You link it into a static executable. – Peter Cordes Dec 26 '21 at 05:20