alexandrenriq
alexandrenriq

Reputation: 23

How to execute C++11 with makefile

I have a problem when I execute commmand "make" in terminal ubuntu. My code of makefile is:

all: temp p1
%: %.cc g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $@

Of course, my files are temp.cc and p1.cc, but my problem is in p1.cc, where the code is:

#include <bits/stdc++.h>
using namespace std;

int main(){
        vector<int> vec = {4,6,8,9,8,7,1,3,4,5,0,1};
        for(auto i : vec)
                cout<<i<<" ";
        cout<<endl;

return 0;}

My error using 'make' is:

eabg97@EABG:~/P$ make
g++     p1.cc   -o p1
p1.cc: In function ‘int main()’:
p1.cc:7:44: error: in C++98 ‘vec’ must be initialized by constructor, not by ‘{...}’
  vector<int> vec = {4,6,8,9,8,7,1,3,4,5,0,1};
                                            ^
p1.cc:7:44: error: could not convert ‘{4, 6, 8, 9, 8, 7, 1, 3, 4, 5, 0, 1}’ from ‘<brace-enclosed initializer list>’ to ‘std::vector<int>’
p1.cc:9:11: error: ‘i’ does not name a type
  for(auto i : vec)
           ^
p1.cc:11:2: error: expected ‘;’ before ‘cout’
  cout<<endl;
  ^
p1.cc:12:2: error: expected primary-expression before ‘return’
  return 0;
  ^
p1.cc:12:2: error: expected ‘)’ before ‘return’
make: *** [p1] Error 1

Using the next command lines, compile:

g++ --std=c++11 p1.cc -o p1

and executing is okay:

eabg97@EABG:~/P$ ./p1
4 6 8 9 8 7 1 3 4 5 0 1

Please help me, I don't understand why there is a problem, thanks for your support :)

Upvotes: 0

Views: 94

Answers (1)

MadScientist
MadScientist

Reputation: 100836

This is wrong:

all: temp p1
%: %.cc g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $@

You should either add a newline and an initial TAB, like this:

all: temp p1
%: %.cc
        g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $@

(the first char on the third line must be a TAB character) or you need to insert a semicolon like this:

all: temp p1
%: %.cc ; g++ -lm -lcrypt -O2 -std=c++11 -pipe $< -o $@

What is your makefile doing? First, that statement all in one line without any newline/TAB or semicolon is considered by make to be a single pattern rule with a target % and prerequisites %.cc, g++, -lm, -lcrypt, etc. And, since there's no recipe, you're basically deleting that pattern rule (which doesn't exist anyway) since a pattern rule with no recipe deletes the pattern rule. So that line is essentially a no-op and does nothing.

So what happens? Make has a bunch of built-in rules that it uses to create things if you don't tell it how to do so, and there's a built-in rule that knows how to create a program from a .cc file, so make uses that. But of course, that built-in rule doesn't have any of your customizations.

It's simpler to use make's built-in rule and use the standard make variables to control it:

CXX := g++
CXXFLAGS := -std=c++11 -pipe
LDLIBS := -lm -lcrypt

all: temp p1

That's all you need, if you don't want to write your own rule.

Upvotes: 1

Related Questions