tags:

views:

394

answers:

7

Hi All,

I have to frequently compile small program and run it. Since, it was tedious to write compile command g++ -W -Wall file.cpp -o out everytime for each cpp file, I wrote one small scripts, which does the compiling.

Here is the script that I wrote

#!/bin/bash
g++ -W -Wall $1 -o $1.out

So, if I have to compile file.cpp, I will do compile file.cpp and it will create file.cpp.out executable for me. And, such file.cpp dont have any header files or any other dependencies.

I know how to write makefile for particular file.cpp like this (very simple case)

file: file.cpp
    g++ -W -Wall file.cpp -o file

but if I have to compile file2.cpp, I have to change above makefile again or write new. So, what I want to do is, when I give make file.cpp command it will produce file as executable. And when I give make file2.cpp it will produce file2 as executable, and similarly for other cpp files.

+6  A: 
export CXXFLAGS="-W -Wall"
rm Makefile
make file1

Make has sane defaults. You don't have to write a makefile to use make.

Make has a set of generic rules, which get apply automatically when there is no specific rule. One of them is to make 'file' out of 'file.cpp' using a C++ compiler with flags from environment variable CXXFLAGS. This works a bit like you want...

liori
Thanks,It worked.
seg.server.fault
The only problem with that is it relies on the environment being the same each time. Sometimes when the environment changes (like between two seassions) unexpected results can be hard to diagnose. I prefer to just create a Makefile with the flags defined inside. Then I know exactly how the objects are built. (Think of it like build documentation and we know documentation is good).
Martin York
+1  A: 

A Makefile doesn't intend to work as a script; taking particular inputs to generate particular outputs. It, instead, describes dependencies between files, and how to build any dependency, in order to reach a particular target.

Although it is possible to do what you are asking for by creating a target called "file1" and a target called "file2", that's not the idea behind Makefiles; you might be better using a shell script if this is your requirement.

Sinan Taifour
-1: `Makefile` is a build system to control generating executables, whether is simple case or complex. It is meant to handle cases as simple as this, and it is superior to shell scripts.
notnoop
Sinan is right, though. Make is not a scripting language--it's a declarative language to specify dependencies between files in order to create products. It is neither superior nor inferior to shell scripts (which is an imperative/procedural language); they are complementary technologies. Trying to use make as a scripting language generally comes out bad.
Chris Cleeland
It's true that using make as a general-purpose scripting language is hard, but the OP didn't propose that, he proposed replacing a trivial script that called g++, with a makefile. It's false that creating a make target called "file1" and another called "file2", when those are the names of the files you want to build, is "not the idea behind makefiles". It's exactly the idea behind makefiles. In this case you'd use the same rule for the two targets, of course.
Steve Jessop
Makefile is superior to shell scripts in doing its job, namely "building and generating executables." Using `make` to do general-purpose scripting is bad style.
notnoop
Actually, make has one key advantage for general-purpose scripting, that it's trivial to write code which can fail (or be interrupted) and then pick up where it left off. If your "script" is actually just a list of commands, not using loops or modifying variables as it goes, then IMO a makefile with a single target can have the edge over bash. But I still don't advocate it as the first place to go for *nix scripting. That's what find is for ;-) http://www.chiark.greenend.org.uk/~pmaydell/find/
Steve Jessop
+5  A: 

You can have the following target

.cpp:
        g++ -W -Wall [email protected] -o $@

This creates an implicit rule which means that to generate file named x where a file x.cpp already exists, perform the following operation.

When you have the rule, you can just do this from command line:

make file
make file2
notnoop
+1  A: 
%: %.cpp
    g++ -W -Wall $*.cpp -o $*
Armin
+1  A: 

Simply create a Makefile with the following line

CXXFLAGS=-W -Wall

You can now call e.g.

make foo

and it'll automatically look for a "foo.cpp" file.

Frerich Raabe
+3  A: 

Relying on make's default rules for C++, the makefile only needs

CPPFLAGS ?= -W -Wall

Then at the command line:

make file1
make file2
rm file2
make file2 CPPFLAGS="-W -Wall -O3"
rm file2
make file2 CXXFLAGS="-O3"   # possibly a bit too cunning, this one
                            # It has the same effect as the one with CPPFLAGS

Personally, I would add to the makefile

EXECUTABLES = file1 file2

all: $(EXECUTABLES)

clean: 
    rm -f $(EXECUTABLES)
Steve Jessop
A: 

You can run make prog# to build the appropriate program.

CXX=/usr/bin/g++
CXXFLAGS=-W -Wall
TARGETS=prog1 prog2 prog3

all: $(TARGETS)

prog1: prog1.cpp
    $(CXX) $(CXXFLAGS) prog1.cpp -o prog1

prog2: prog2.cpp
    $(CXX) $(CXXFLAGS) prog2.cpp -o prog2

prog3: prog3.cpp
    $(CXX) $(CXXFLAGS) prog3.cpp -o prog3
notmg