0

I have a small problem, and I have tried everything to test this function, could you please help me? I need to write a C file that is called "mutual_info.c", and it needs a mathematical function. I have included the library and linked it in the makefile, but it still gives me "undefined reference to log"... my includes look like this: (I'm using Eclipse on Ubuntu)

#include <stdio.h>
#include <stdlib.h>
#include "sample.h"
#include "graph_or.h"
#include <math.h>

and my makefile looks like this:

all:

    gcc -g amostra.c sample.h -o amostra.o

    gcc -g graph_or.c graph_or.h -o graph_or.o

    gcc -g graph_w.c graph_W.h -o graph_W.o

    gcc -g mutual_info.c -o mutual_info.o -lm

clean:
    rm *.o

I have absolutely no idea what is going on, I have even tried to define the LDFLAGS before the command "all" and putting it like this:

LDFLAGS= -lm
all:

    gcc -g amostra.c sample.h -o amostra.o

    gcc -g graph_or.c graph_or.h -o graph_or.o

    gcc -g graph_w.c graph_W.h -o graph_W.o

    gcc -g mutual_info.c -o mutual_info.o -lm

clean:
    rm *.o

But it still won't work!! Please anyone, I need help with this! Thanks!

PL-RL
  • 427
  • 2
  • 7
  • 13
  • This makefile doesn't make any sense. If you want to generate .o files, then you need the `-c` flag, and you don't need to specify any linker options (i.e. you don't need `-lm`). You then need a separate GCC invocation to link all the .o files together. Also, you don't need to specify .h files. – Oliver Charlesworth May 01 '12 at 10:27
  • I'm sorry @OliCharlesworth couldn't understand what you are saying, could you be more specific, or maybe show me some code for the makefile? I thought you had to link the math library every time you wanted to use it! Thanks – PL-RL May 01 '12 at 10:36
  • The typical pattern for compiling is something like: `gcc -c -o foo.o foo.c, gcc -c -o bar.o bar.o, gcc -o myApp foo.o bar.o -lm`. – Oliver Charlesworth May 01 '12 at 10:45
  • thank you, but what you're saying is 3 different ways to compile? And what do you intend to say when you write "myApp"? Sorry for all the dumb questions, but I'm kind of a newbie in C – PL-RL May 01 '12 at 10:47
  • I'm saying that this is an example of how you would create an executable called `myApp` from two input source files `foo.c` and `bar.c`. – Oliver Charlesworth May 01 '12 at 11:08
  • Please edit the title of the question. You do not link headers. "math.h linkage with file" is absurd, and there is too much confusion in the world about the difference between libraries and headers. A header is not a library. You cannot link a header. – William Pursell May 01 '12 at 14:10

4 Answers4

1

Let's take this in steps.

The usual way to write a makefile is to have a rule for each target, and to use prerequisites:

thing: amostra.o graph_or.o graph_w.o mutual_info.o
    gcc -g amostra.o graph_or.o graph_w.o mutual_info.o -o thing -lm

mutual_info.o: mutual_info.c
    gcc -g -c mutual_info.c -o mutual_info.o -lm

amostra.o: amostra.c sample.h
    gcc -g -c amostra.c -o amostra.o

graph_or.o: graph_or.c graph_or.h 
    gcc -g -c graph_or.c -o graph_or.o

graph_w.o: graph_w.c graph_w.h
    gcc -g -c graph_w.c -o graph_w.o

mutual_info.o: mutual_info.c
    gcc -g -c mutual_info.c -o mutual_info.o -lm

(I have guessed that you want the executable to be called thing, and that you meant graph_w, not graph_W.)

That should work, but we can make it tidier. First we introduce automatic variables:

thing: amostra.o graph_or.o graph_w.o mutual_info.o
    gcc -g $^ -o $@ -lm

mutual_info.o: mutual_info.c
    gcc -g -c $< -o $@

amostra.o: amostra.c sample.h
    gcc -g -c $< -o $@

graph_or.o: graph_or.c graph_or.h 
    gcc -g -c $< -o $@

graph_w.o: graph_w.c graph_w.h
    gcc -g -c $< -o $@

mutual_info.o: mutual_info.c
    gcc -g -c $< -o $@

Then we see that these recipes use the same command, so we create a pattern rule:

thing: amostra.o graph_or.o graph_w.o mutual_info.o
    gcc -g $^ -o $@ -lm

amostra.o: sample.h

graph_or.o: graph_or.h 

graph_w.o: graph_w.h

%.o: %.c
    gcc -g -c $< -o $@

Give this a try and tell us if it works.

Beta
  • 96,650
  • 16
  • 149
  • 150
  • Thank you very much for your explanation! I tried it, but it still gives me the same error, I really cannot understand what am doing wrong :( is there anything else I can try? – PL-RL May 01 '12 at 17:56
  • @PL-RL, yes, you can reduce your code. Simplify it as much as you can, remove as much as possible, and test at every stage to verify that you still get the same error. Get it down to one source file of only a few lines, if you can. When you cannot make it any simpler (and still get the error), edit your question and show us the code. – Beta May 01 '12 at 18:21
0

Is that a snippet from your Makefile? Hav you tried exporting LDFLAGs? I have seen this error before, but it was always fixed with the -lm flag.

gcc -lm -o blah blah.c

Sirch
  • 407
  • 3
  • 17
  • What you are saying is to change the -lm next to gcc? I tried that and it didn't work either... – PL-RL May 01 '12 at 10:37
  • -c compiles the source but doesnt link. So you need to: gcc -c -o amostra.o amostra.c gcc -c -o graph_or.o graph_or.c gcc -c -o graph_w.o graph_w.c gcc -o YourExecutableName amostra.o graph_or.o graph_w.o -lm – Sirch May 01 '12 at 10:51
0

you need to:
gcc -c -o amostra.o amostra.c
gcc -c -o graph_or.o graph_or.c
gcc -c -o graph_w.o graph_w.c
gcc -c -o mutual_info.o mutual_info.c
gcc -o YourExecutableName amostra.o graph_or.o graph_w.o mutual_info.o -lm

Sirch
  • 407
  • 3
  • 17
  • Thank you, but what about the mutual_info file (the one I need to link with the math library?) – PL-RL May 01 '12 at 11:00
0

Here's a generic makefile using my best guess of what you want to achieve: It compiles all *.c files in the current directory and creates a binary mutual_info.

RM := rm -f
CC := gcc
CFLAGS := -g
LDLIBS := -lm

SOURCES := $(wildcard *.c)
OBJECTS := $(SOURCES:%.c=%.o)
DEPS := $(SOURCES:%.c=%.d)
BINARY := mutual_info
FILES_TO_CLEAN := $(OBJECTS) $(DEPS)

.PHONY : all clean realclean

all : $(BINARY)

clean :
    $(RM) $(FILES_TO_CLEAN)

realclean : FILES_TO_CLEAN += $(BINARY)
realclean : clean

-include $(DEPS)

$(OBJECTS) : %.o : %.c
    $(CC) $(CFLAGS) -c -MMD -o $@ $<

$(BINARY) : $(OBJECTS)
    $(CC) -o $@ $^ $(LDLIBS)

Please clarify if that's not what you want.

Christoph
  • 164,997
  • 36
  • 182
  • 240