Gomathi
Gomathi

Reputation: 1003

C Program makefile in linux

I'm a beginner. I'd like to create a makefile for C programs in Linux.

My program flow is, cmd.c calls cdirec(), dspecd(), sfile(), hfile() which are declared in mainl.h (but not defined in it)

cdirec(), dspecd(), sfile() and hfile() are defined in cdirec.c, dspecd.c, sfile.c and hfile.c respectively.

cdirec() in turn calls mimx(), skloc(), fnc() and fcmp() which are declared in subl.h (but not defined in it)

mimx(), skloc(), fnc() and fcmp() are defined in mimx.c, skloc.c, fnc.c and fcmp.c respectively.

I tried to create a makefile as follows,

all: cmd.o cdir.o dspecd.o sfile.o hfile.o
    cc cmd.o cdir.o dspecd.o sfile.o hfile.o -o sourceinfo
cmd.o: cmd.c mainl.h
    cc -c cmd.c
cdir.o: cdirec.o mimx.o skloc.o fnc.o fcmp.o
    cc cdirec.o mimx.o skloc.o fnc.o fcmp.o -o cdir.o
cdirec.o: cdirec.c mainl.h subl.h
    cc -c cdirec.c
dspecd.o: dspecd.c mainl.h
    cc -c dspecd.c
sfile.o: sfile.c mainl.h
    cc -c sfile.c
hfile.o: hfile.c mainl.h
    cc -c hfile.c
mimx.o: mimx.c subl.h
    cc -c mimx.c
skloc.o: skloc.c subl.h
    cc -c skloc.c
fnc.o: fnc.c subl.h
    cc -c fnc.c
fcmp.o: fcmp.c subl.h
    cc -c fcmp.c

I don't understand what the problem is. But I get an undefined reference to main in cdir.o. cdirec.c looks like this,

#include<stdio.h>
#include "subl.h"

void cdirec()
{
printf("\nAll details of current directory is printed.\n");
mimx();
skloc();
fnc();
fcmp();
}

I don't and can't have a main in it, as it is just a function declaration file. Kindly guide me.

ANSWER:

all: cmd.o cdirec.o dspecd.o sfile.o hfile.o mimx.o skloc.o fnc.o fcmp.o 
    cc cmd.o cdirec.o dspecd.o sfile.o hfile.o mimx.o skloc.o fnc.o fcmp.o -o sourceinfo
cmd.o: cmd.c mainl.h
    cc -c cmd.c
cdirec.o: cdirec.c mainl.h subl.h
    cc -c cdirec.c
dspecd.o: dspecd.c mainl.h
    cc -c dspecd.c
sfile.o: sfile.c mainl.h
    cc -c sfile.c
hfile.o: hfile.c mainl.h
    cc -c hfile.c
mimx.o: mimx.c subl.h
    cc -c mimx.c
skloc.o: skloc.c subl.h
    cc -c skloc.c
fnc.o: fnc.c subl.h
    cc -c fnc.c
fcmp.o: fcmp.c subl.h
    cc -c fcmp.c
clean:
    rm -rf *.o sourceinfo

Upvotes: 1

Views: 450

Answers (3)

Brian Campbell
Brian Campbell

Reputation: 333266

The problem occurs here:

cdir.o: cdirec.o mimx.o skloc.o fnc.o fcmp.o
    cc cdirec.o mimx.o skloc.o fnc.o fcmp.o -o cdir.o

This is telling cc to link these given .o files into an executable named cdir.o. An executable needs a main function. But it looks like you're not trying to link an executable; instead, you're trying to collect multiple object files into a single object file.

You don't need to do this; you can just link all of your object files together in the final executable. If you just find it cumbersome to deal with that many files on one line, you can define a Make variable; a common name is OBJS (short for "objects"):

OBJS  = cdirec.o 
OBJS += mimx.o 
OBJS += skloc.o 
OBJS += fnc.o 
OBJS += fcmp.o 
# ... etc

sourceinfo: ${OBJS}
    cc ${OBJS} -o sourceinfo

If you want to collect them into a single file, you can build a library, and then link that into the final executable. A library is built with the ar command; it should have the extension .a:

cdir.a: cdirec.o mimx.o skloc.o fnc.o fcmp.o
    ar rcs cdir.a cdirec.o mimx.o skloc.o fnc.o fcmp.o

You then link that when building your final executable:

cc cmd.o dspecd.o sfile.o hfile.o cdir.a -o sourceinfo

As an aside on your organization, it looks like you might be defining one function per source file. That gets pretty cumbersome pretty quick. You usually group related functions together in the same source file. It's possible that all of cdirec(), mimx() skloc(), fnc() and fcmp() should be defined in the same file, so that they produce a single object file, though I can't say for sure without seeing your actual code.

There are also further features in Make that would make your Makefile much simpler. In particular, there are already implicit rules for compiling .c files into .o, so you don't need all those rules, just the dependencies on the headers (because those aren't generated implicitly):

cmd.o: mainl.h
cdirec.o: mainl.h subl.h
dspecd.o: mainl.h
sfile.o: mainl.h
hfile.o: mainl.h
mimx.o: subl.h
skloc.o: subl.h
fnc.o: subl.h
fcmp.o: subl.h

You can actually generate these dependencies automatically as well, but that's a bit more complicated, so I won't go into it here.

Upvotes: 3

Manoj R
Manoj R

Reputation: 3247

If you are not trying to create a static/dynamic library, you need to have main somewhere. Add some test file with main, and compile with that file.
Also I don't think any need for all those *.o to be mentioned explicitly. The Make is smart enough to figure that out.

Upvotes: 1

KAction
KAction

Reputation: 2017

Do not bother with hand writing of dependencies. Use autotools or light version -- gcc -MM ./*.

Upvotes: -1

Related Questions