9

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
StackedCrooked
  • 34,653
  • 44
  • 154
  • 278

6 Answers6

11

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.)

mtvec
  • 17,846
  • 5
  • 52
  • 83
  • 2
    Also make has wildcard function for finding files. – Martin York Aug 26 '10 at 16:10
  • 1
    +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 Aug 26 '10 at 16:14
  • @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"? – mtvec Aug 26 '10 at 16:22
  • 1
    @Martin: I think the `wildcard` function cannot be used to search for files recursively. – mtvec Aug 26 '10 at 16:27
  • 1
    see: http://stackoverflow.com/questions/3576292/create-linux-make-build-file/3576355#3576355 – Martin York Aug 26 '10 at 16:33
  • @Martin: Just writing `$(TARGET): $(OBJECTS)` does not perform the linking step so your left with a bunch of object files but no binary. – mtvec Aug 26 '10 at 16:44
  • @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 Aug 26 '10 at 17:08
  • @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 Aug 26 '10 at 17:13
  • @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. – mtvec Aug 26 '10 at 17:20
  • @Thomas: My target doesn't have an extension because I'm used to working on Linux, where executables generally don't have extensions. – mtvec Aug 26 '10 at 17:33
  • 2
    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 --- ex-moderator kitten Aug 26 '10 at 22:20
  • +1 for the `find` usage which is more readable than any `make` function. – levif Sep 05 '10 at 21:22
  • This approach may end up in a total overshoot. Way too many files are collected and later compiled! HWUT's approach of searching for include files and references before generating a dedicated Makefile is much more effective. – Frank-Rene Schäfer Sep 15 '15 at 10:50
7

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
  • 11,531
  • 2
  • 37
  • 39
5

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          = $(wildcard *.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
  • 257,169
  • 86
  • 333
  • 562
3

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
  • 16,497
  • 3
  • 46
  • 59
  • How does this do what the OP wants? AFAIK, `makedepend` just generates dependencies, not the rules to build the files. – mtvec Aug 26 '10 at 18:21
  • The version of makedepend I was playing with actually created a functional makefile. – jkerian Aug 26 '10 at 19:18
  • 99% of the time, the implicit rules will handle everything except the final binary as well. – jkerian Sep 04 '10 at 23:06
1
  • 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
  • 16,630
  • 5
  • 41
  • 63
0

As described in the linked discussion, HWUT is a tool that can generate pretty Makefiles, searching for dependencies and include files in directories that you tell it. On windows you need to install MinGW and Ctags. Under Linux gcc and ctags are most likely present. It is OpenSource and free to use.

Especially, when generating Unit Tests for some already existing modules of some larger project with bad cohesion, this feautures easily spares you hours or even days.

Community
  • 1
  • 1
Frank-Rene Schäfer
  • 3,182
  • 27
  • 51