0

I am trying to figure our an error I keep getting with make. I have several source files located in assign1 directory along with a includes directory (contains bb.h). What I am trying to do is include the bb.h header file when I am creating gq.o file. All the other object files compile fine except gq.o due to this error:

z1755294@hopper:~/assign1/assign1$ make
g++ -c fr.cc
g++ -c vw.cc
g++ -c ac.cc
g++ -c pg.cc
g++ -c gq.cc -I./includes
g++ -o output fr.o gq.o vw.o ac.o pg.o
gq.o: In function `main':
gq.cc:(.text+0x0): multiple definition of `main'
fr.o:fr.cc:(.text+0x0): first defined here
vw.o: In function `main':
vw.cc:(.text+0x0): multiple definition of `main'
fr.o:fr.cc:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
Makefile:12: recipe for target 'output' failed
make: *** [output] Error 1

this is my Makefile:

output: fr.o vw.o ac.o pg.o gq.o
        g++ -o fr.o gq.o vw.o ac.o pg.o output

fr.o: fr.cc pg.h
        g++ -c fr.cc

vw.o: vw.cc ac.h
        g++ -c vw.cc

ac.o: ac.cc ac.h pg.h
        g++ -c ac.cc

pg.o: pg.cc pg.h
        g++ -c pg.cc

gq.o: gq.cc ac.h includes/bb.h
        g++ -c gq.cc -I./includes/bb.h

clean:
        -rm *.o

fr.cc, gq.cc and vw.cc all have main functions inside each of them.  
ac.cc and fr.cc both have fl(); function they have in common.
gq.cc and vw.cc both have x2(); function they have in common.

I am not allowed to edit any of the files below. The goal is to create a makefile so if the bb.h file were to be changed by someone then the makefile will still work.

Here is the file structure for each file:

ac.cc

#include "ac.h"
#include "pg.h"
#include <iostream>
using std::cout;
using std::endl;

void  y7(void)
{
  cout << "y7()" << endl;
}

void  x2(void)
{
  cout << "x2()" << endl;
  f1();
}

ac.h

void y7(void);

void x2(void);

fr.cc

#include <iostream>
using std::cout;
using std::endl;

#include "pg.h"

int main()
{
  cout << "program fr" << endl;

  f1();

  return 0;

}

gq.cc

#include <iostream>
using std::cout;
using std::endl;

#include "ac.h"
#include "bb.h"

int main()
{
  cout << "program gq" << endl;

  x2();

  cout << "CONST111: " << CONST111 << endl;
  cout << "CONST222: " << CONST222 << endl;

  return 0;

}

pg.cc

#include "pg.h"
#include <iostream>
using std::cout;
using std::endl;

void  f1(void)
{
  cout << "f1()" << endl;
}

void  g3(void)
{
  cout << "g3()" << endl;
}

pg.h

void f1(void);

void g3(void);

vw.cc

#include <iostream>
using std::cout;
using std::endl;

#include "ac.h"

int main()
{
  cout << "program vw" << endl;

  x2();

  return 0;

}

includes/bb.h

define CONST111   42
#define CONST222   84
3
  • This is wrong: -I./includes/bb.h, it should point only to the directory, not the file: -I./includes. Of course bb.h must exist in that directory. Commented Sep 6, 2015 at 2:50
  • ok I fixed that problem with your suggestion, now I am getting : g++ -o fr.o gq.o vw.o ac.o pg.o output g++: error: output: No such file or directory Makefile:12: recipe for target 'output' failed make: *** [output] Error 1 Commented Sep 6, 2015 at 3:07
  • Change: g++ -o fr.o gq.o vw.o ac.o pg.o output to: g++ -o output fr.o gq.o vw.o ac.o pg.o Commented Sep 6, 2015 at 3:10

2 Answers 2

1

Change

gq.o: gq.cc ac.h bb.h
        g++  -c gq.cc -I./includes/bb.h 

to

gq.o: gq.cc ac.h
         g++ -c gq.cc -I./includes 

or

gq.o: gq.cc ac.h includes/bb.h
         g++ -c gq.cc -I./includes 

The reason your build was failing is due to bb.h not being in the same directory. You list bb.h as a requirement and since it is not there, make attempts to generate it but finds no suitable rule. You need to either not list bb.h as a requirement or specify the file with its path so make sees that it exists. You also need to just use -I./includes to specify the search directory that g++ will look for bb.h in.

You will also need to change this:

output: fr.o vw.o ac.o pg.o gq.o
    g++ -o fr.o gq.o vw.o ac.o pg.o output

which has many problems. First and foremost you are trying to link objects with conflicting symbols and your use of the -o flag is wrong. Based on comments and your edits, what I think you want is:

output: fr.o vw.o ac.o pg.o gq.o
        g++ -o fr fr.o pg.o
        g++ -o gq gq.o ac.o pq.o
        g++ -o vw vw.o ac.o pg.o

This will produce three binaries, fr, gq, and vw, named after the three files with main() symbols. Each only lists the objects necessary for resolving external symbols.

Sign up to request clarification or add additional context in comments.

14 Comments

I did change that and now another error: g++ -c fr.cc g++ -c vw.cc g++ -c ac.cc g++ -c pg.cc g++ -I./includes -c gq.cc g++ fr.o gq.o vw.o ac.o pg.o -o output gq.o: In function main': gq.cc:(.text+0x0): multiple definition of main' fr.o:fr.cc:(.text+0x0): first defined here vw.o: In function main': vw.cc:(.text+0x0): multiple definition of main' fr.o:fr.cc:(.text+0x0): first defined here collect2: error: ld returned 1 exit status Makefile:12: recipe for target 'output' failed make: *** [output] Error 1
I posted the question with updates, can you help me figure this out?
Thank you so much, it compiles perfectly. Just a quick question, if any of the source files changes, will the make work again? Also when it compiles how come when I type make clean the files fr, gq, and vw still say. Shouldn't this be cleared and if not, how do remove those files?
Since those files in the output section you suggested are executables, how do I create a rule to build all of them?
Oh I get it now, the name output or all is just a command to say to produce executables but doesn't acutally create a name called all or output (in our case). Now I understand
|
0

I can see at least two errors in this Makefile but its impossible to tell without knowing the file layout:

Here are my fixes:

output: fr.o vw.o ac.o pg.o gq.o
        g++ -o output fr.o gq.o vw.o ac.o pg.o

fr.o: fr.cc pg.h
            g++ -c fr.cc

vw.o: vw.cc ac.h
            g++ -c vw.cc

ac.o: ac.cc ac.h pg.h
            g++ -c ac.cc

pg.o: pg.cc pg.h
            g++ -c pg.cc

gq.o: gq.cc ac.h includes/bb.h # need to give path to bb.h
            g++ -c gq.cc -I./includes

clean:
            -rm *.o

If you still have problems post your file layout into the question.You can use this:

find .

in your project folder.

6 Comments

I added the find . information above, if you can help me figure this out, I would really appreciate it.
@user3325133 You should add your file structure to the original question. I have revised my answer so that it builds with the file structure you posted. I missed putting the full (relative) path to bb.h.
I have added the file structure for each file, can you help me to get the makefile to compile?
@user3325133 What is the Makefile supposed to do? There are 3 programs in that list of files and your Makefile is only trying to build one.
The goal is to create a makefile such that if a change is made to any of the source code files, the project can be rebuilt by typing make at the command line.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.