Reputation:
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
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