hi guys im trying to write a makefile which contains :two cpp files and two header files.
now i've put cppfiles in a folder called source whose path is: /root/workspace/source

and header files in a folder called header whose path is:
/root/workspace/makedemo/header

my makefile is in the path:/root/workspace/makedemo

my makefile was like this:

HEADERS = $(shell /root/workspace/makedemo/header ls *.h)
SOURCES = $(shell /root/workspace/source ls *.cpp)

COMPILERFLAGS = -W -Wall
DEBUGFLAGS = -g
CPPCOMPILER = g++

INCLUDES = -I.


OBJS = $(SOURCES:.cpp=.o)

BINARY = output

all: $(BINARY)

$(BINARY): $(OBJS)
        $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) -o $(BINARY) $(OBJS)
depend:
        makedepend -f- -- $(SOURCES) > .depend_file
clean:
        rm -rf *.o .depend_file $(BINARY) *~

#DO NOT DELETE

im sure that i've given the correct path but it is showing errors like this:

[root@localhost makedemo]# make
/bin/sh: /root/workspace/source: is a directory
/bin/sh: /root/workspace/source: is a directory
g++ -W -Wall -I. -o output
g++: no input files
make: *** [output] Error 1

any help appreciated...

Recommended Answers

All 8 Replies

Your shell commands are off. Try this:

HEADERS = $(shell ls /root/workspace/makedemo/header/*.h)
SOURCES = $(shell ls /root/workspace/source/*.cpp)

hi mcriscolo ,im still having problem after changing it to the way u have told..
error was like this:
[root@localhost makedemo]# make
/bin/sh: /root/workspace/source/: is a directory
/bin/sh: /root/workspace/source/: is a directory
g++ -W -Wall -I. -o output
g++: no input files
make: *** [output] Error 1

Please post your updated makefile and I'll take a look.

hi mcriscolo ,im sorry i actually misplaced 'ls' in the SOURCES and HEADERS path but later when i gave make command it showed some errors like this:

[root@localhost makedemo]# make
g++ -c -o /root/workspace/source/Main.o /root/workspace/source/Main.cpp
/root/workspace/source/Main.cpp:1:24: SourceData.H: No such file or directory
/root/workspace/source/Main.cpp:2:22: TestFile.H: No such file or directory
/root/workspace/source/Main.cpp: In function `int main()':
/root/workspace/source/Main.cpp:5: error: `TestFile' was not declared in this scope
/root/workspace/source/Main.cpp:5: error: expected `;' before "obj"
/root/workspace/source/Main.cpp:6: error: `SourceData' was not declared in this scope
/root/workspace/source/Main.cpp:6: error: expected `;' before "sd"
/root/workspace/source/Main.cpp:7: error: `sd' was not declared in this scope
/root/workspace/source/Main.cpp:9: error: `obj' was not declared in this scope
make: *** [/root/workspace/source/Main.o] Error 1

im sure i've no problem in other header and source files as i compiled and ran successfully when all was in the same folder(including makefile).

i've used makedepend tool for dependency and i think above problem is arising because of dependency issue.i would also like to know where(in which folder) .o files will be created when im compiling ?

any way i've also included source and header file coding here...
source:
Main.cpp:

#include "SourceData.H"
#include "TestFile.H"
int main()
{
TestFile obj;
SourceData sd;
sd.rollNum = 101;
sd.name = "Shiva";
obj.Display(sd);
return 0;
}

TestFile.cpp:

#include <iostream>
#include "TestFile.H"
void TestFile::Display(SourceData &d)
{
        std::cout<<d.ToString()<<std::endl;
}

Header:
SourceData.H

#ifndef _SORCEDATA_H_
#define _SORCEDATA_H_
#include <iostream>
#include <sstream>
#include <string>
struct SourceData
{
int rollNum;
std::string name;
std::string ToString()
{
std::stringstream sst;
sst<<"RollNum = "<<rollNum<<"\n";
sst<<"Name = "<<name<<"\n";
return sst.str();
}
};
#endif

TestFile.H:

#ifndef _TESTF1_H_
#define _TESTF1_H_

#include "SourceData.H"
class TestFile
{
public:
        void Display(SourceData &d);
};
#endif

and my makefile was like this:

HEADERS = $(shell  ls/root/workspace/makedemo/header/ *.H)
SOURCES = $(shell ls/root/workspace/source/ *.cpp)

COMPILERFLAGS = -W -Wall
DEBUGFLAGS = -g
CPPCOMPILER = g++

INCLUDES = -I.


OBJS = $(SOURCES:.cpp=.o)

BINARY = output

all: $(BINARY)

$(BINARY): $(OBJS)
        $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) -o $(BINARY) $(OBJS)
depend:
        makedepend -f- -- $(SOURCES) > .depend_file
clean:
        rm -rf *.o .depend_file $(BINARY) *~

#DO NOT DELETE

Try this makefile:

TOP_DIR = /root/workspace
S_DIR = $(TOP_DIR)/source
H_DIR = $(TOP_DIR)/makedemo/header

HEADERS = $(shell  ls $(H_DIR)/*.H)
SOURCES = $(shell ls $(S_DIR)/*.cpp)

COMPILERFLAGS = -W -Wall -c
DEBUGFLAGS = -g
CPPCOMPILER = g++

INCLUDES = -I$(H_DIR)

OBJS = $(SOURCES:.cpp=.o)

BINARY = output

all:    $(BINARY)

$(BINARY):      $(OBJS)
        $(CPPCOMPILER) -o $(BINARY) $(OBJS)

.cpp.o: $(SOURCES) $(HEADERS)
        cd $(S_DIR); $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) $<

depend:
        makedepend $(INCLUDES) -f- -- $(SOURCES) > .depend_file
clean:
        rm -rf $(S_DIR)/*.o .depend_file $(BINARY) *~

#DO NOT DELETE

Your original makefile was not pointing to the proper include file, so it was not picking up your headers. That was the source of your errors. Here, I've suggested some changes that make the file somewhat cleaner (at least to me). See if they work for you.

I made the changes to the top, by adding some variables for the directories, since I'd have to go to them (for example, in the "clean" rule).

The other major addition is the ".cpp.o" rule to build the objects prior to linking the executable. I found that the one rule in the original Makefile was not picking up the stuff in COMPILERFLAGS, so I knew it was hitting a default rule for the .cpp items.

The *.o files will, by default, be dropped in the current folder where make is being run (in your example, /root/workspace/makedemo), but then the variables for the object files that have the paths pre-pended would fail during the link step. I fixed that by performing a "cd $(S_DIR)" prior to the compile step to drop the *.o files in the "source" folder. The executable ("output"), however, will still fall into the "makedemo" folder.

I didn't mess with "makedepend" - perhaps someone else knows more about that. There also is one thing I wasn't able to get working - if you "touch" one of the header files, when you make it won't rebuild. I'll look into that.

Hope this helps!

hi mcriscolo, i tried your make file and its working fine without any problem,but still i've some doubts in it to clarify...
>>The other major addition is the ".cpp.o" rule to build the objects prior to linking the executable.

$(BINARY):      $(OBJS)
        $(CPPCOMPILER) -o $(BINARY) $(OBJS)

the above rule is what which links all the object files to produce executable ,but you have included .cpp.o rule for creating object file only after the target rule and makfile is running fine without any problem(even though i tried other way by writting .cpp.o rule before target rule and as expected it didnt show any error there also)so why is that it is not showing any error?

>>I found that the one rule in the original Makefile was not picking up the stuff in COMPILERFLAGS, so I knew it was hitting a default rule for the .cpp items.

>>but then the variables for the object files that have the paths pre-pended would fail during the link step. I fixed that by performing a "cd $(S_DIR)" prior to the compile step to drop the *.o files in the "source" folder.

im sorry if i sound stupid but still cant help asking you,i didnt get what you was saying here and also i'vent used .cpp.o rule till now ...and when i've created .o files already using the suffix replacement like this:

OBJS = $(SOURCES:.cpp=.o)

why should i use .cpp.o rule again for creating object files?so can you explain me why its used here(ofcourse i know its for creating object files but would like to know the meaning of the entire line and each macros used in the below rule...)

.cpp.o: $(SOURCES) $(HEADERS)
        cd $(S_DIR); $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) $<

i've one last question ,in this makefile scenario is such that all the source files are in one folder called source and headers in folder called headers(but both these folders in diff directories),now suppose if i have many sourcefiles and headerfiles residing in other directories other than in the given folder called source and headers ,how do i mention their path in makefile?

should i have to mention the path for each files in diff directories as diff macros or is there any other way for doing that?
thanks in advance...

To answer the question about adding the ".cpp.o" rule: When I ran your makefile as is, I was seeing the compilation of the .cpp files (trying to make the output .o files) working, but it was not picking up the $(COMPILERFLAGS) variable. That is, this rule in your makefile:

$(BINARY): $(OBJS)
        $(CPPCOMPILER) $(COMPILERFLAGS) $(INCLUDES) -o $(BINARY)

when compiling the .cpp sources, was producing this output:

g++    -c -o /root/workspace/source/Main.o /root/workspace/source/Main.cpp

Where is the "-W -Wall"? Where is the "include" directive? It was not in the output of the command make was executing. This is why you were getting the build errors - it didn't know where to find the header files. That's because make was executing a default rule for the .cpp files, and not using the directives in the rule for building the executable. Once I added the ".cpp.o" rule, everything built - almost. The .cpp built and made the correct .o files, but when it was time to make the executable, I got this output:

g++ -W -Wall -c -I/root/workspace/makedemo/header -o output /root/workspace/source/Main.o /root/workspace/source/TestFile.o

That's because I had to put a "-c" into the COMPILERFLAGS variable, and now that it's trying to build the executable, the "-c" is trying to output object code rather than perform the link. This required the removal of the $(COMPILERFLAGS) variable from the rule that was building the executable.

Some of the macros for make: "$<" is the name of the file that caused the rule to be executed, so in the case of the .cpp.o rule, this would be a .cpp file.

As far as having many different source directories and headers, those have to be specified separately (or at least in separate variables). When we do that kind of stuff, we're usually building libraries, so each library would have its own makefile, and then the build for the executable would have its makefile to pull in the required libraries.

Hope this helps.

thanx a lot mcriscolo,your explanation was satisfactory ...but i would also like to know if there is any sequential order by which rules defined in the makefile are evaluated or it doesnt matter here in this file?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.