views:

385

answers:

1

Hello everyone! So i have this issue : i am declaring some extern global variables in my C program. If I don't use the -c option for gcc, i get undefined references errors. But with that -c option, the linking is not done, which means that i don't have an executable generated.

So how do I solve this?

Here is my makefile (written thanks to Alex)

CC = gcc                      # compiler/linker frontend
INCL = -I$(INCL_DIR)          # includes
DEFS = -D_DEBUG_              # defines
CFLAGS = -g $(INCL) $(DEFS)   # compiler flags
LFLAGS = -lpthread -lm -g     # linker flags

OBJ = approx.o producteur.o sequentialApproximation.o main.o
BIN = calculPi.exe
LINKOBJ  = approx.o producteur.o sequentialApproximation.o main.o
RM = rm -fv

all: $(BIN)

clean:
 ${RM} *\~ \#*\# $(OBJ)

clean_all: clean
 ${RM} $(BIN)

cleanall: clean
 ${RM} $(BIN)

$(BIN): $(OBJ)
 $(CC) $(LFLAGS) -o $@ $^

main.o: main.c
approx.o: approx.c approx.h
producteur.o: producteur.c producteur.h
sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h

.c.o:
 $(CC) $(CFLAGS) -c $<

And here is the output of make : http://pastebin.com/NzsFetrn

I did declare extern variables in approx.h (extern and global) and i try to call them in approx.c, and there it doesn't work.

+2  A: 

Solution 1

You can't pass -c in your linking phase, as that will tell the compiler to skip linking.

Your problem is

$(BIN): $(OBJ)
    $(CXX) $(LINKOBJ) -o "calculPi.exe"

with

CXX_FLAGS =-g -c -lpthread -lm

where $(CXX) expands to gcc -g -c -lpthread -lm ...

get rid of the -c there.

Only pass -c when compiling from source to object modules.

Solution 2

Re the second problem, you aren't actually defining the variables anywhere. In your .c file you need the lines:

Coord* production;
int indice_prod;
int indice_cons;

(Assuming you really want global variables). This will fix the unresolved external error. You can't write to them until they've been allocated!

Notes

Also note that you can specify how to build object files from source in one rule:

.c.o:
    $(CC) $(CFLAGS) -c $<

and specify the dependencies without rules:

main.o: main.c
approx.o: approx.c approx.h
producteur.o: producteur.c producteur.h
sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h

etc.

Other notes.

Also, as general rule of thumb, CXX should only contain the compiler name, no flags. Those should go in CXX_FLAGS. And why are you calling it CXX not CC? Use g++ if you want a C++ compiler, or use CC. Since you have .c files, I'll assume C. So in your case, you should change:

CXX_FLAGS =-g -c -lpthread -lm
CXX = gcc $(CXX_FLAGS) $(INCL) $(DEFS)

to

CC = gcc
CFLAGS = -g -lpthread -lm $(INCL) $(DEFS)  # also removed -c

And you don't need a separate LINK_CXX.

Sample Makefile

So a minimal Makefile should look like:

# Makefile
CC = gcc                      # compiler/linker frontend
INCL = -I$(INCL_DIR)          # includes
DEFS = -D_DEBUG_              # defines
CFLAGS = -g $(INCL) $(DEFS)   # compiler flags
LFLAGS = -lpthread -lm -g     # linker flags

OBJ = approx.o producteur.o sequentialApproximation.o main.o
BIN = calculPi.exe

all: $(BIN)

$(BIN): $(OBJ)
    $(CC) $(LFLAGS) -o$@ $^

main.o: main.c
approx.o: approx.c approx.h
producteur.o: producteur.c producteur.h
sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h

.c.o:
    $(CC) $(CFLAGS) -c $<

# clean and other stuff.
Alex
Hey Alex, thanks for helping me.About the how to build object ine one rule thing :.c.o: $(CC) $(CFLAGS) -cis this correct? It says a separator is missing (again, excuse me as i ma very bad at writing makefiles and i am not good at compiling c code)Also, when i get rid of the -c in the $(BIN) rule I still have my undefined references back!
Moons
I did not call it CXX, as i told you, i took an existing makefile that i edited, i will try this and let you knowThanks again
Moons
Actually im gonna be busy this afternoon, so i'll try this tomorrow :)Thanks again for your kind help!
Moons
Post your undefined references and your updated makefile.
Alex
So here is the new makefile http://pastebin.com/u4pJKJKtHere is the make output : http://pastebin.com/NzsFetrnThe undefined references are gblobal extern variables i declare in approx.h, and that i set in approx.c (and that i'll have to use in producteur.c)
Moons
@Moons, where is `indice_prod` defined? And edit your original question ideally. (And remove the LINKOBJ variable, you don't need it)
Alex
@Moons, show how indice_prod et al. are defined. They're clearly not in `approx.o`
Alex
Here is approx.c : http://pastebin.com/TZw5jHWjHere is approx.h : http://pastebin.com/qjbRvH03(i can't post them into the main post, my reputation isn't high enough :) )
Moons
When i set a value for indice_prod in approx.h, then i get the following error : multiple definition of indice_prod !That's weird!
Moons
@Moon, the problem is you haven't reserved any space for those variables. You must define the variable somewhere (*not* in a header though!). E.g. in approx.c, write `int indice_prod;` and the same for others. (Assuming you really want those variables to be global).Never define variables in a header. Extern is OK (since it doesn't define them). I'll edit my answer.
Alex
Thank you for you answer, it is compiling.So now that i have added the lines in the .c, I can use them in every other .c ??I didn't knew i had towrite these 3 lines, thaught when I included the .h, it'd do the job!Well i'm happy i'm able to work again on that school work, thank you.
Moons
@Moon, Yes, you can use them in other C files.
Alex