user1299979
user1299979

Reputation:

How to use ld to link obj files produced by gcc

These days I'm reading APUE and setting up the Makefile myself instead of using the existing .mk Makefile provided by the book's website. My Makefile goes like this:

CC=gcc
LD=ld
CC_FLAGS= -c -I ./include/ -Wall -Wextra
LD_FLAGS= -e main -lc
LIB_OBJS= ./lib/*.o #There'are about 30 .c files in lib, \
most of which are wrap of error handling routines or simplified APIs. \
So I don't copy them all in the code block

all: 

ls: ls.c $(LIB_OBJS)
        $(CC) $(CC_FLAGS) -o ls.o ls.c
        $(LD) $(LD_FLAGS) -o ls ls.o ./lib/error.o

$(LIB_OBJS):
        cd ./lib; \
        make

clean:
        cd ./lib; \
        make clean
        rm ./ls

The Makefile in ./lib is pretty much similar to this one as it just gcc -c all .c files in that directory and doesn't do any linking works. And the ls.c is the first piece of code in Chapter One which just list every element of the given dirent. My problem is, my Makefile CAN PRODUCE a executable without any error printed but this file is not executable at all. Whenever I ./ls with the x privilege, bash returns:

bash: ./ls: No such file or directory

But if I use gcc to link ls.o and ./lib/error.o together it works smoothly. So I wondered what's special in gcc's ld invoking. How do I do if I only use ld to link gcc produced stuffs? Thanks beforehand!

Upvotes: 1

Views: 2245

Answers (1)

M.S.
M.S.

Reputation: 146

I am not sure what toolchain you are using, but there are few default libraries that gcc pass to linker other than the ones you specify, for e.g. libc

Here is a part output of gcc with -v option which tells about linker step:

GNU assembler version 2.17.50.0.6-12.el5 (i386-redhat-linux) using BFD version 2.17.50.0.6-12.el5 20061020 /usr/libexec/gcc/i386-redhat-linux/4.1.2/collect2 --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 -o y.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crt1.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crti.o /usr/lib/gcc/i386-redhat-linux/4.1.2/crtbegin.o -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2 -L/usr/lib/gcc/i386-redhat-linux/4.1.2/../../.. /tmp/ccS39C4x.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i386-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../crtn.o

Upvotes: 3

Related Questions