0

consider c.c a code that includes a.h and b.h, and main.c a code that includes c.h i tried to compile it like so

gcc --std=c99 -o a.o -c a.c
gcc --std=c99 -o b.o -c b.c
gcc --std=c99 -o c.o -c c.c a.o b.o

but when I run the last one, gcc yells at me

gcc --std=c99 -o c.o -c c.c a.o b.o
gcc: warning: a.o: linker input file unused because linking not done
gcc: warning: b.o: linker input file unused because linking not done

and then when I try to compile the main.c file using gcc -o main main.c c.o it says that there are a lot of undefined references, which is predictable once the c file was not correctly compiled.

I've seen some similar questions here at stackoverflow, but I couldn't get it to work neither way.

I'm on Arch Linux running gcc v4.9.2-3

Kasama
  • 83
  • 2
  • 10
  • Have you tried just `gcc --std=c99 -o c.o b.o a.o c.c`? – ForceBru Mar 11 '15 at 20:36
  • On which operating system, with which version of GCC? Why do you ask? Don't you simply want to link some executable? Please edit your question to improve it! – Basile Starynkevitch Mar 11 '15 at 20:46
  • @ForceBru if I do, it tells me `undefined reference to main`, because c.o is not the final program, it will later be used together with main.c to create the final executable – Kasama Mar 11 '15 at 20:56

1 Answers1

2

First, it is -std=c99 with a single dash.

I guess you are on Linux.

Then, you always should pass -Wall -Wextra -g (especially since you are a newbie) to gcc : -Wall ask for nearly all warnings, -Wextra for even more warnings, -g ask for debug information.

At last, you want to produce an executable myprog (don't name executables as c.o, this is supposed to be an object file) with

gcc -std=c99 -Wall -Wextra -g -o myprog c.c a.o b.o

You need to remove any -c since you want the linking to happen.

If you really mean -but that is very unusual today, better make shared libraries!- to agglomerate several object files into one all.o (to be linked later with other objects) you might try the -r linker option

gcc -std=c99 -Wall -Wextra -g -r c.c a.o b.o -o all.o

But last time I tried it was in the previous century, so details could be wrong.

There are very few reasons to agglomerate objects using the -r linker option. Unless you really know what you are doing, you are very probably wrong (in trying -r).

Perhaps you want to make a software library. These days it is much better to make a shared library. A shared library (technically an ELF shared object) should contain position independent code. So, assuming you have three translation units t1.c, t2.c, t3.c you first compile them as PIC :

 gcc -std=c99 -Wall -Wextra -g -fPIC t1.c -c -o t1.pic.o
 gcc -std=c99 -Wall -Wextra -g -fPIC t2.c -c -o t2.pic.o
 gcc -std=c99 -Wall -Wextra -g -fPIC t3.c -c -o t3.pic.o

then you link all these PIC object files into a shared library libmyt.so

 gcc -std=c99 -Wall -Wextra -g -shared \
    t1.pic.o t2.pic.o t3.pic.o \
    -o libmyt.so

Later you'll use this shared library e.g. as

 gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . libmyt.so

or as

 gcc -std=c99 -Wall -Wextra -g main.o -o myprog -Wl,-rpath . -L. -lmyt

You might consider static linking with ar to make a static library libmyt.a but I don't recommend that.


Of course, you'll debug your program using gdb ./myprog and you could try running it with ./myprog. To use valgrind, try valgrind ./myprog

If you have several translation units, better learn how to use GNU make. Read the Program Library HowTo and this and these hints.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • What I really meant was to agglomerate the objects to use later, like you said, but now ld (the linker) is telling me that `ld: cannot find -lgcc_s` I couldn't find any references to -r on gcc man page, what is it really supposed to mean? – Kasama Mar 11 '15 at 20:54
  • `-r` is a linker option. But if you want to agglomerate objects, make a static library (use `ar`) or better yet a shared object. – Basile Starynkevitch Mar 11 '15 at 20:55