0

EDITS: Including link to my makefile

I have a main program that calls a bunch of functions defined in other source files. This is not a problem because I am using cc -c functionSource.c functionHeader.h and generating object files before compiling my main program with cc main.c func1.o func2.o .... -o test.o

I am having problems when one of my functions depends on another function. For example: My main program calls an shuffle function which is defined in it's own source file and the shuffle function calls a swap function which in turn is defined in it's own source file.

When i try to generate the shuffle.o file for my main program using cc -c shuffle.o I get an undefined reference to swap error.

When I try to cc shuffle.c swap.o i get an undefined reference to main error.

Here is my makefile

How do I go about fixing this? Found the problem. I had a swap function declared inside insertionSort.h and shuffle.h but no implementations.

Quonux
  • 2,975
  • 1
  • 24
  • 32
  • Why are you including a header file on the compiler line? The header file should be found by `#include "insertionSort.h"` in the `insertionSort.c` file (if the header is in the same directory, or use the right path or path environment). Also, is `swap` declared in `insertionSort.h`? – lurker Sep 04 '13 at 17:52
  • See my answer below, for what I consider a solution. Your "undefined reference" is due to the fact that you forgot to specify '-c', therefor the compiler tries to link (and is missing main). Else you're basically right with your method to generate the executable: Just generate InsertionSort.o and add it to the command line you use for linking. If you use -c to compile insertionSort.c (as you should), it's useless to specify any .o-files at the commandline. – M.E.L. Sep 04 '13 at 18:01
  • No swap is declared in swap.h and implemented in swap.c. swap.h is #included in insertionSort.c. The makefile tutorial I was reading had all the header files listed on the complier line and I did the same. – Yudhishthir Singh Sep 04 '13 at 18:04
  • The makefile probably has the header file on the "dependency" line, not the compiler execution line. – lurker Sep 04 '13 at 18:10
  • "makefile tutorial I was reading had all the header files listed on the complier line". Then the tutorial is wrong (BTW: do you have a link?). Header files on the command line are ignored by the compiler. Header files are pulled in by using *#include* in the source files. I wish I could point you to my own make file tutorial, but unfortunately, it is in German ... – M.E.L. Sep 04 '13 at 18:10
  • BTW: Are you trying to write a makefile, or are you just trying to compile ypur sources at the commandline / shell? – M.E.L. Sep 04 '13 at 18:12
  • Does `insertionSort.c` or `swap.c` contain `main()`? If not, that would explain `undefined reference to main`. If `insertionSort.c` includes `swap.h`, and `swap.h` defines the function `swap`, and `insertionSort.c` is calling `swap` with the correct parameters and spelled correctly, then you shouldn't be seeing `undefined reference to swap` error when doing `cc -c insertionSort.c`. – lurker Sep 04 '13 at 18:12
  • @M.E.L. Here is the makefile tutorial I was following [link](http://www.gnu.org/software/make/manual/make.html#Complex-Makefile). I am trying to write a makefile. mbratch you are right the header files are on the dependencies line. Neither insertionSort.c or swap.c contains a main. – Yudhishthir Singh Sep 04 '13 at 18:16
  • Wow. The makefile you're trying to understand is pretty complicated for the beginning. I usuggest you have a look at this makefile http://www.glitzersachen.de/articles/kleines-make-tutorial/tricky.html#makefile-tricky-2. You should be able to understand it and modify it appropriately. Use the one before that if you don't want automatic dependency generation. – M.E.L. Sep 04 '13 at 18:24
  • Please show what you're actually entering when you get the error and give the complete output of after your comamnd. You really do runr *make* don't you? I'm asking, because I now read *cc -c swap.o* which deon't make much sense. And your Makefile says something different. – M.E.L. Sep 04 '13 at 18:53
  • OK. Thanks :-). I'm sure we could have found this much earlier with a more or less complete description ... – M.E.L. Sep 04 '13 at 18:54
  • Probably. :) Either way I'm glad I posted this, I have a much better understanding of makefiles and cc now. – Yudhishthir Singh Sep 04 '13 at 19:07
  • @YS: That's OK with me. – M.E.L. Sep 04 '13 at 19:17

2 Answers2

2

Have a look to the man page: '-c' makes the compiler generating object files only (not trying to link).

Do the following:

cc -c insertionSort.c     # => gives insertionSort.o
cc -c -c functionSource.c # => gives functionSource.o
cc insertionSort.o functionSource.o ...and-so-on... main.c -o test 

It's not necessary to specify header files - it doesn't help.

BTW: If you have mor than one implementation file, it is rather useful

  • (a) to learn make
  • (b) stick to the convention that object files and programs should be named like th sources.

E.g:

foo.c => foo.o
bar.c => bar

etc - you get the picture.

M.E.L.
  • 613
  • 3
  • 8
1

This has nothing to do with make. You need to get a book on introductory C programming, that will explain how to use the preprocessor, and you need to examine the documentation for your compiler so you understand what the different compiler flags do (such as when you want to use the -c flag and when you don't, and what the difference is).

It's wrong to include header files (.h files) on the compile line. Only source files (.c) should be included on the command line when building object (.o) files. You should be adding the headers you need into your .c files using the #include directive: #include "insertionSort.h". If you're missing a reference to a function, then #include the header file that declares that function: #include "swap.h".

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • I assumed the -c flag just creates object files. I did run man cc unfortunately I didn't understand most of what the man page said. – Yudhishthir Singh Sep 04 '13 at 18:14
  • "I didn't understand most of what the man page said." => Not surprising. Te man page is a veritable kitchen sink of information, but unfortunately doesn't begin with the most common use cases. – M.E.L. Sep 04 '13 at 18:28