PDA

View Full Version : Makefile



NecroDOME
11-09-2009, 02:36 PM
System: Ubuntu (linux)
Compiler\IDE: g++ (yeah I know, I'm turning to the dark-side)
API: std-lib

So no Pascal related question this time, but I'm stuck with a makefile at work. And as this is such nice community I thought to give it a shot here.

First of all I have a file called Main.cpp that just prints "Hello world". So now I want to create a make file so when I type make it compiles Main.cpp to something executable ./Main or ./Test or something. How do I do that?

I tried some stuff like this (ripped form the Internets):


COMPILER = g++
CCFLAGS = -g

myprogram: Main.cpp Main.o
${COMPILER} ${CCFLAGS} Main.cpp Main.o

subfile1.o: Main.cpp Main.o
${COMPILER} ${CCFLAGS} -c Main.cpp Main.o

myclass.o: Main.cpp
${COMPILER} ${CCFLAGS} -c Main.cpp

clean:
rm -rf *.o a.out

But it doesn't seem to do the job...

g++ -g Main.cpp Main.o
Main.o: In function `main':
Main.cpp:(.text+0x0): multiple definition of `main'
/tmp/ccUA5sxi.o:/home/michiel/Cpp/Codeblocks/TestProject/TestProject/Main.cpp:3: first defined here
collect2: ld returned 1 exit status
make: *** [myprogram] Error 1

Is this a makefile error or a compilation error? I know there are some Linux-guys here that maybe can help me.

JSoftware
11-09-2009, 03:19 PM
The reason yours fail to compile is that you link the result of compiling Main.cpp together with Main.o. So you link the same file twice.
That's an error on your part where you call the compiler

You probably want something like this


COMPILER = g++
CCFLAGS = -g

all: myprogram

myprogram: Main.o
${COMPILER} ${CCFLAGS} Main.o -o Main

Main.o:
${COMPILER} ${CCFLAGS} Main.cpp -o Main.o

clean:
rm -rf *.o a.out


I usually just fit any makefiles to the following template:


SOURCES=Main.cpp file1.cpp file2.cpp file3.cpp
OBJECTS=$(SOURCES:.cpp=.o)

EXECUTABLE=Main

COMPILER = g++
CCFLAGS = -g

all: $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
$(COMPILER) $(CCFLAGS) $(OBJECTS) -o $@

.o:
$(COMPILER) $(CCFLAGS) $< -o $@

clean:
rm -f *.o

NecroDOME
11-09-2009, 06:37 PM
Ok thnx, will try that one Monday at work!

NecroDOME
14-09-2009, 09:09 AM
Thnx :)

I tried the first, that worked well!! I also take a closer look at the second one.
Anyway, thanks for helping out :)

cragwolf
15-09-2009, 04:08 AM
Another approach, from a small project of mine:


SHELL = /bin/sh
CC = gcc
CFLAGS = -Wall
GTKFLAGS = `pkg-config --cflags gtk+-2.0`
LDFLAGS = `pkg-config --libs gtk+-2.0`
SRCS = gtkss.c
OBJS = gtkss.o
FILES = $(SRCS) README INSTALL COPYING AUTHORS NEWS ChangeLog Makefile
PROG = gtkss
VERSION = 0.1
prefix = /usr/local
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin

%.o: %.c
$(CC) -c $(CFLAGS) $(GTKFLAGS) $<

$(PROG): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@

all: $(PROG)

$(PROG).tar.gz:
@mkdir $(PROG)-$(VERSION)
@cp $(FILES) $(PROG)-$(VERSION)
@tar --numeric-owner -czf $(PROG)-$(VERSION).tar.gz $(PROG)-$(VERSION)
@rm -rf $(PROG)-$(VERSION)
@echo Distribution complete!

dist: $(PROG).tar.gz

install:
@cp -f $(PROG) $(bindir)
@echo Installation complete!

.PHONY : clean

clean:
@-rm -f $(OBJS) $(PROG)
@echo Clean complete!

I think I went a little overboard. But if your project gets too large, then it's time to switch to Autotools, where angels fear to tread. ;D