-1
# Compiler
CXX      := g++
CF       := -g

# c files
CFILES   := $(wildcard src/*.cpp)
SOURCES  := $(CFILES) # $(CFILES2) all CFILES

# o files
OBJECTS  := $(SOURCES:.cpp=.o)
OBJECTS_A:= $(SOURCES:.cpp=_a.o)

# Macros
MACRO = -D
INFO = -DINFO // optional
DCDREAD = -DDCDREAD
# More Macros
DEFAULT   = -DDEFAULT
CONTACT = -DDEFAULT -DCONTACT -DCONTACTPERSIST -DTENSION_COSTHETA
MTCONTACT = -DDEFAULT -DMTCON1 -DMTCON2
DCDCON = -DDCDREAD -DCONTACT -DCONTACTPERSIST -DTENSION_COSTHETA
DCDMT = -DDCDREAD -DMTCON1 -DMTCON2
CENMOV = -DDCDREAD -DMTCON1 -DCENTROIDMOVEMENT
ANGLE = -DDCDREAD -DINERTIA -DANGLE
ANG3 = -DDCDREAD -DMTCON1 -DANGLE3CENTROID

ang3o: $(OBJECTS_A)
    $(CXX) $(OBJECTS_A) -o test/$(EXEC)_dcd_angle3centroid
    cd test && ./$(EXEC)_dcd_angle3centroid mtonly_seamup.ref.pdb      mtonly_seamup_d1_indent.dcd 1 209 1
ang3: $(OBJECTS)
    $(CXX) $(SOURCES) $(CF) $(INC) $(LIB) $(ANG3) -o   test/$(EXEC)_dcd_angle3centroid
    cd test && ./$(EXEC)_dcd_angle3centroid mtonly_seamup.ref.pdb mtonly_seamup_d1_indent.dcd 1 209 1

# To obtain object files
$(OBJECTS_A) : $(SOURCES)
    $(CXX) $(CF) $(INC) $(LIB) $(ANG3) -c $< -o $@
%.o: %.cpp
    $(CXX) $(CC_FLAGS) $(INC) $(LIB) -c $< -o $@

I know the objects are unnecessary in the ANG3 rule. The c files are compiled directly, the executable runs correctly! I'd like to switch to objects, an ANG3O rule. HERE is my main question, am I trying to link .o files incorrectly at the end of the ANG3O rule?

ANG3 works. ANG3O fails. Multiple Definitions of Function Error.

make ang3
g++ -g -O3 -Iinclude -pthread -c src/readfile.cpp -o src/readfile.o 

g++ -g -O3 -Iinclude -pthread -c src/main.cpp -o src/main.o         

g++ -g -O3 -Iinclude -pthread -c src/md.cpp -o src/md.o
g++ -g -O3 -Iinclude -pthread -c src/chain.cpp -o src/chain.o
g++ src/readfile.cpp src/main.cpp src/md.cpp src/chain.cpp  -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -o test/run_segment_dcd_angle3centroid


make ang3o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c     src/readfile.cpp -o src/readfile_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/main_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/md_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/chain_a.o
g++ src/readfile_a.o src/main_a.o src/md_a.o src/chain_a.o -o test/run_segment_dcd_angle3centroid

src/main_a.o: In function `ReadLines(Chain*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: multiple     definition of `ReadLines(Chain*)'
                src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:43:     first defined here
src/main_a.o: In function `ReadMolecularContent(char*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: multiple     definition of `ReadMolecularContent(char*)'
        src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:208:    first defined here
src/md_a.o: In function `ReadLines(Chain*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: multiple     definition of `ReadLines(Chain*)'
    src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:43:     first defined here
src/md_a.o: In function `ReadMolecularContent(char*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: multiple     definition of `ReadMolecularContent(char*)'
    src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:208:    first defined here
src/chain_a.o: In function `ReadLines(Chain*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:43: multiple     definition of `ReadLines(Chain*)'
        src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:43:     first defined here
src/chain_a.o: In function `ReadMolecularContent(char*)':
/home/d/sop_dev/contacts/segment/src/readfile.cpp:208: multiple     definition of `ReadMolecularContent(char*)'
    src/readfile_a.o:/home/d/sop_dev/contacts/segment/src/readfile.cpp:208:    first defined here
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../lib/crt1.o: In     function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:172: recipe for target 'ang3o' failed
make: *** [ang3o] Error 1

NOTES:

Related question: Error with multiple definitions of function

Possibly related: One definition rule and different class definitions in two translation units

However, in my situation: the headers are in the include directory. The c files are in a src directory. All functions are declared in the headers. Only headers are included, no c/cpp files. Makefile examples seem to halt just before this level of complexity, the use of different define segments of code, and the need to compile objects with/without certain defined sections.

Community
  • 1
  • 1
dmerz75
  • 23
  • 4
  • Not a _minimal_ testcase, didn't read the output, didn't look up the language facilities used in the documentation before asking for help. -1 – Lightness Races in Orbit Oct 07 '15 at 16:59
  • It is not necessary to spell out the commands for compiling the individual C source files, because make can figure them out: it has an implicit rule for updating a `.o' file from a correspondingly named `.c' file using a `cc -c' command. For example, it will use the command `cc -c main.c -o main.o' to compile `main.c' into `main.o'. We can therefore omit the commands from the rules for the object files. See section Using Implicit Rules. ftp://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_2.html I've seen this before, now how do I get past it.. – dmerz75 Oct 07 '15 at 18:42
  • I dunno... I usually override that. – Lightness Races in Orbit Oct 07 '15 at 23:12

1 Answers1

2

It helps to actually read the output.

g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/readfile_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/main_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/md_a.o
g++ -g -Iinclude -pthread -DDCDREAD -DMTCON1 -DANGLE3CENTROID -c src/readfile.cpp -o src/chain_a.o

You're compiling the same C++ source file over and over again, then linking it to itself.

Your mistake is in the recipe to build objects. I'll leave you to read the documentation and find out why.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Oh! in the ang3 rule, the objects (%.o) get created from the corresponding cpp file. Do you know why it fails in the ($(OBJECTS_A) rule? – dmerz75 Oct 07 '15 at 17:04
  • @dmerz75: There are too many mistakes with it for me to enumerate here. It doesn't really make any logical sense the way you have it laid out at present. Which book are you using? – Lightness Races in Orbit Oct 07 '15 at 17:06
  • @dmerz75: Well there you go then! – Lightness Races in Orbit Oct 07 '15 at 17:12
  • I'm going to lookup how to force the for looping through the $SOURCES provided as targets. But for now, I see analogous construction between the %.o and $(OBJECTS_A) dependencies.... – dmerz75 Oct 07 '15 at 17:19