0

I'm scanning the web and all my project files for solution but still can't find the answer why my linker won't finish the job. Everything smoothly compiles into .o files, but the last make command fails. And here is the Makefile content:

CXX = g++
CXXFLAGS = -Wall -pedantic -c
OBJS = main.o operacje.o porownaj.o 
dzialania: $(OBJS)
    $(CXX) $^ -o $@

main.o: main.cpp operacje.h porownaj.h
    $(CXX) $(CXXFLAGS) $^ -o $@

operacje.o: operacje.cpp operacje.h porownaj.h
    $(CXX) $(CXXFLAGS) $^ -o $@

porownaj.o: porownaj.cpp operacje.h porownaj.h
    $(CXX) $(CXXFLAGS) $^ -o $@

clean:
    rm -f *o

and again, here is the mistake that pops out:

g++ main.o operacje.o porownaj.o -o dzialania
ld: fatal: file main.o: unknown file type
ld: fatal: file processing errors. No output written to dzialania
*** Error code 1
make: Fatal error: Command failed for target `dzialania'

I'm sure it's some kind of a basic mistake but after staring at the file for a few hours I won't notice it anyway. Maybe some of you folks with notice the bug with a fresh eye.

btw. it's my first post after long-term passive lurking, I hope I did everything right. Thanks in advance!

@edit1 OK, I did all the suggested corrections

@edit2 Seems like the problem is caused by improper module division of my program. I'll rearrange it's structure and let you know if it works then. Thanks for all the support!

@edit3 OK, I changed the structure of my program and everything runs smooth, Thanks again!

2 Answers2

1

Try using $< instead of $^ in your rules to compile main.o, operacje.o, and porownaj.o:

main.o: main.cpp operacje.h porownaj.h
    $(CXX) $(CXXFLAGS) $< -o $@

operacje.o: operacje.cpp operacje.h porownaj.h
    $(CXX) $(CXXFLAGS) $< -o $@

porownaj.o: porownaj.cpp operacje.h porownaj.h
    $(CXX) $(CXXFLAGS) $< -o $@

That will cause make to compile only the corresponding .cpp file. When you use $^ the header files are passed to the g++ command which tells the compiler to create precompiled headers for them - that's what's ending up in main.o instead of the object file for main.cpp.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • OK, tried it. This time I'm getting such thing: g++ -Wall -pedantic -c -o main.o g++: fatal error: no input files compilation terminated. *** Error code 1 make: Fatal error: Command failed for target `main.o' If I try replace $< with corresponding source file names, the linker pops out a message that certain objects are multiply-defined. Each of my header files has a header guardian. – user3408010 Mar 12 '14 at 00:45
  • Post the output of `make --version`. I've tried this with both GNU make 4.00 and 3.82.90. I can reproduce your original problem when `$^` is used and I get a successful build when `$<` is used instead for the compile steps (note: the first instance of `$^` in the makefile is left alone because in that case we want all the object files to be passed to the link). Of course, my `.cpp` files are simple single-function modules with `main.cpp` just calling the single function in the other files. – Michael Burr Mar 12 '14 at 05:08
  • Multiple definition errors probably mean a bug in your program, not your makefile – Jonathan Wakely Mar 12 '14 at 10:01
  • I'll try to rearrange it then. – user3408010 Mar 12 '14 at 13:32
0

GNU make variable definitions like CC = g++, or CFLAGS = -Wall -pedantic etc.. should each be on its own line:

CC = g++ 
CFLAGS = -Wall -pedantic 
OBJS = main.o operacje.o porownaj.o

BTW, you probably mean

CXX = g++
CXXFLAGS = -Wall -pedantic

You certainly don't want -c explicitly in your CFLAGS or CXXFLAGS; you really should remove it.

Also, recipes should be after its rule, so you want

dzialania: $(OBJS)  
    $(LINK.cc) $^ -o $@
operacje.o: operacje.cpp operacje.h porownaj.h  
    $(CXX) $(CXXFLAGS) -c $< -o $@

The several spaces are actually a single tab character.

Run make -p to understand the rules known by make; see also this answer and that one.

Take time to read GNU make documentation.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547