tags:

views:

159

answers:

5

Does anyone know of a tool that generates a makefile by scanning a directory for source files?

It may be naive:

  • no need to detect external dependencies
  • use default compiler/linker settings
+1  A: 

There's a very old script called 'makedepend' that used to make very simple makefiles. I've since switched over to cmake for almost everything.

Here's the wiki article http://en.wikipedia.org/wiki/Makedepend, note the list of Alternatives at the bottom including depcomp in automake, and the -M flag in gcc.

EDIT: As someone pointed out to me in another question, gcc -MM *.cpp > Makefile produces a rather nice simple makefile. You only have to prepend your CPPFLAGS and a rule for constructing the entire binary... which will take the form:

CPPFLAGS=-Wall
LDFLAGS=-lm
all: binary_name
binary_name: foo.o bar.o baz.o biff.o
jkerian
How does this do what the OP wants? AFAIK, `makedepend` just generates dependencies, not the rules to build the files.
Job
The version of makedepend I was playing with actually created a functional makefile.
jkerian
99% of the time, the implicit rules will handle everything except the final binary as well.
jkerian
+3  A: 

CMake does it and it even creates makefiles and Visual Studio projects. http://www.cmake.org/

All you need to do is creating a CMakeLists.txt file containing the follwing lines:

file(GLOB sources *.h *.c *.cxx *.cpp *.hxx)
add_executable(Foo ${sources})

Then go into a clean directory and type:

cmake /path/to/project/

That will create makefiles on that clean build directory.

tibur
+2  A: 

You can write a Makefile that does this for you:

SOURCES=$(shell find . -name "*.cpp")
OBJECTS=$(SOURCES:%.cpp=%.o)
TARGET=foo

.PHONY: all
all: $(TARGET)

$(TARGET): $(OBJECTS)
        $(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@

.PHONY: clean
clean:
        rm -f $(TARGET) $(OBJECTS)

Just place this in root directory of your source hierarchy and run make (you'll need GNU Make for this to work).

(Note that I'm not fluent in Makefileish so maybe this can be done easier.)

Job
Also make has wildcard function for finding files.
Martin York
+1 Why not use the standard names for things. And the standard rules will work for target no need to do anything special.
Martin York
@Martin: I tried to use an implicit rule for the target but didn't succeed:) It only seems possible if one of the source files is named `$(TARGET).cpp`. What do you mean with "the standard names for things"?
Job
@Martin: I think the `wildcard` function cannot be used to search for files recursively.
Job
see: http://stackoverflow.com/questions/3576292/create-linux-make-build-file/3576355#3576355
Martin York
@Martin: Just writing `$(TARGET): $(OBJECTS)` does not perform the linking step so your left with a bunch of object files but no binary.
Job
@Job: If the target has extension, such as "foo.a" or "foo.exe" then `make` can use its default rules and `$(TARGET): $(OBJECTS)` will work. In your post, the target has no extension.
Thomas Matthews
@Job: If the target name is the same as one of the object file names (minus the .o extension) then the implicit linking rule is fired automatically. See: http://www.gnu.org/software/make/manual/make.html#Catalogue-of-Rules
Martin York
@Martin: Yes, that's what I said before. I'll leave my answer like it is because I think it's most generally applicable this way.
Job
@Thomas: My target doesn't have an extension because I'm used to working on Linux, where executables generally don't have extensions.
Job
and see: http://stackoverflow.com/questions/2481269/how-to-make-simple-c-makefile/2481326#2481326 for a wordier explanation of what's going on in a short GNU makefile like Martin links to. Plus there are a number of other pretty decent "basic makefile" answers scattered all over the site.
dmckee
+1 for the `find` usage which is more readable than any `make` function.
levif
A: 
  • no need to detect external dependencies
  • use default compiler/linker settings

Why script then? Provided that all your project source files are *.cpp and in current directory:

all: $(notdir $(CURDIR))
$(notdir $(CURDIR)): $(subst .cpp,.o,$(wildcard *.cpp))
        $(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@

The Makefile would build the all the source files with default compiler/linker settings into an executable named after the name of the current directory.

Otherwise, I generally recommend people to try SCons instead of make where it is much simpler and intuitive. Added bonus that there is no need to code manually clean targets, source/header dependency checking is built-in, it is natively recursive and supports properly libraries.

Dummy00001
A: 

This is what I would use for a simple project:

CC               = $(CXX)
CXXFLAGS        += -ansi -pedantic -W -Wall -Werror
CPPFLAGS        += -I<Dir Where Boost Lives>


SOURCES          = $(wildcards *.cpp)
OBJECTS          = $(patsubst %.cpp,%.o,$(SOURCES))

all:             myApp
myApp:           $(OBJECTS)

The only restriction is that if you are building an executable called myApp. Then one of the source files should be named myApp.cpp (which is where I put main).

Martin York
+1 Starting from a simple template makefile isn't a bad idea IMO. I don't know why you somebody decided to downvote this.
StackedCrooked