views:

150

answers:

5

My projects almst always consist of:

1- Pairs of Foo.h and Foo.cpp

2- Some extra headers util.h etc.

What is the simplest way to write a makefile that

a-runs

$CC -c foo.cpp

for each .cpp file, keeping a dependency to its coresponding .h file

b- provides some way that I can manually add extra dependencies

c-includes a linking step with my manuall set $LIBS variable.

I work with Linux(Ubuntu) and gcc/g++.

A: 

start here simple makefile for gcc

Martin Beckett
A: 

Here is an example from one of my projects -- you can simply drop new pairs foo1.cc and foo1.h in there and they will automagically be built for you:

# determine all sources and from that all targets
sources :=              $(wildcard *.cpp)
programs :=             $(sources:.cpp=)

## compiler etc settings used in default make rules 
CXX :=                  g++
CPPFLAGS :=             -Wall 
CXXFLAGS :=             -O3 -pipe 
LDLIBS :=  

# build all and strip programs afterwards 
all:                    $(programs) 
                        @test -x /usr/bin/strip && strip $^ 
Dirk Eddelbuettel
With no dependency on the header files there are cases where this will not rebuild after changes have been made. The usual `.depend` recipe will fix it. Multiple SO question address that issue including http://stackoverflow.com/questions/297514/how-can-i-have-a-makefile-automatically-rebuild-source-files-that-include-a-modif.
dmckee
Building `strip` into your compilation step seems like a really bad idea, especially for development. The GNU makefile conventions put stripping into its own target, `install-strip`: http://www.gnu.org/prep/standards/standards.html#Makefile-Conventions
Jack Kelly
As I said, it came from a local project -- where I considered strip to be appropriate.
Dirk Eddelbuettel
+2  A: 

Pardon the meta-answer, but perhaps you can check out CMake [1]?

If you're unfamiliar with CMake, it's basically a Makefile generator (or XCode, or Visual Studio Projects, etc, depending on platform), so it lets you specify just the variables you need, and takes care of header dependency issues for you, makefile generation, etc.

[1] http://www.cmake.org/cmake/help/examples.html

Eddie Parker
+1  A: 

How about this:

%.o: %.cpp %.h
    $(CC) -c $< -o $@

# Some things have extra dependencies. (Headers like util.h are unlikely
# to change, but you can handle them this way if you really want to.)
#
# foo.o and bar.o both depend on baz.h
foo.o bar.o: baz.h

# foo.o also depends on gab.h and jig.h
foo.o: gab.h jig.h

# You will need a list of object files. You can build it by hand:
OBJ_FILES = foo.o bar.o snaz.o # and so on

# ...or just grab all the files in the source directory:
SOURCE_FILES = $(wildcard *.cpp)
OBJ_FILES = $(SOURCE_FILES:.cpp=.o)

# It is possible to get this from the environment, but not advisable.
LIBS = -lred -lblue

final-thing: $(OBJ_FILES)
    $(CC) $(LIBS) $^ -o $@
Beta
Have fun manually maintaining those dependencies.
Jack Kelly
@Jack Kelly: Yes, I am familiar with more advanced methods like mad-scientist.net/make/autodep.html, but look at the question.
Beta
@Beta: Ah yes, it does ask for manually managing the deps. My bad.
Jack Kelly
+3  A: 

Please, just use automake. You'll get proper dependency tracking, makefiles that comply with the GNU Makefile Standards (e.g., make install does the correct thing and respects DESTDIR and prefix), the ability to check for system quirks as needed and support for building proper distribution tarballs.

This is a minimal configure.ac:

                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.61])
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AM_INIT_AUTOMAKE([foreign])

# Checks for programs.
AC_PROG_CXX

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

and a minimal Makefile.am:

## Process this file with automake to generate Makefile.in
bin_PROGRAMS = foo
foo_SOURCES = foo.cpp bar.h baz.h quux.cpp

Run autoreconf -i to generate the configure script, followed by ./configure and make.

Here is an excellent autotools tutorial.

Jack Kelly