0

I'm writing C++ project made of few files on Linux. The project have no subdirectories.

I wanted like to have some as simple as possible, generic build script.

By generic, I mean that I don't want to hardcode file names, so that when I put new .cpp file into project, I don't have to modify build script. It should find and compile all modyfied source files in current directory, and link object files into executable. Nothing more.

I don't care about tool you'll use, since I don't know any yet.

I don't want to learn a tool from basics to write something as simple as that. For now, I just need a code, I'll learn when I'll need something more fancy.

What I tryed

make:

a.out: %.o
    $(CXX) %.o

%.o: %.cpp
    $(CXX) -Wall -c %.cpp

with no success:

make: *** Brak reguł do zrobienia obiektu `%.o', wymaganego przez `a.out'. Stop.

my translation of this message:

make: *** No rules to make object `%.o', required by `a.out'. Stop.

Before someone will ask, I'll answer: yes, my makefile is indented with 1 tab, not with spaces.

make -d prints out 664 lines, so I won't paste it here.

scons:

Program("main.cpp")

It's copyed from some StackOverflow answer, but it is definietly intended to build a executable from one source file, because I get linker errors when I want use it.

I ended us using bash:

g++ -Wall *.cpp

Simple. Does the job well... for now. I don't think it's elegant and I know it's probably inefficent, because it recompiles everything, even unmodyfied files.

2
  • 1
    about scons: Program(Glob("*.cpp")) will build executable from all *.cpp files in a directory. In general, SCons is just a Python extension, so you are able to use Python power into your build system. Commented Sep 26, 2015 at 15:59
  • @Nevermore: thank you, it answers my question. Commented Sep 26, 2015 at 16:05

2 Answers 2

2

I guess that you have a directory full of single-source C++ programs (e.g. each program has one single C++ source file) named .cpp (e.g. foo.cpp & bar.cpp), each independently compiled to an executable (e.g. foo & bar). You might try the following (untested) Makefile for GNU make.

CXX= g++
CXXFLAGS= -Wall -Wextra -g -O
RM= rm -vf

SOURCES= $(wildcard *.cpp)
BINARIES= $(patsubst %.cpp, %, $(SOURCES))

.PHONY: all clean

all: $(BINARIES)

clean:
     $(RM) *~ *.o $(BINARIES)

Read the documentation of GNU make and try make -p to find the builtin rules. See also these two examples of Makefile-s: this & that

If on the contrary you want one single executable myprogram from all the *.cpp files (like foo.cpp & bar.cpp etc....), you still can use $(wildcard *.cpp) in your Makefile (and you'll better not name a.out your executable, but something more meaningful), something like (in addition of common stuff like CXXFLAGS= above):

SOURCES= $(wildcard *.cpp)
OBJECTS= $(patsubst %.cpp, %.o, $(SOURCES))
all: myprogram
myprogram: $(OBJECTS)
    $(LINK.cc) $^ -o $@ $(LIBES)

In all cases, using $(wildcard *.cpp) is enough to have a Makefile generic enough on the list of sources. You may want to generate autodependencies (using gcc -M things, to some of your header files), see this.

Notice that you might have some C++ source or header files generated by some other means (e.g. your own awk or python script, or a _timestamp.c file generated with date, or some C++ files produced by a code generator like GNU bison or gperf, etc, etc...). Then you need to add specific rules into your Makefile.

So in practice, I don't believe in fully generic build files, but I am trying to show you that a Makefile can be almost generic and short. At some time you'll adapt it to your particular needs.

Sign up to request clarification or add additional context in comments.

Comments

0
SRC := $(wildcard src/*.c)
DEP := $(SRC:src/%.c=lib/%.d)
OBJ := $(SRC:src/%.c=lib/%.o)
CFLAGS := -Wall -Wextra -O2 -MMD

# Executable
lib/mines: lib/assets.o $(OBJ)
    ${CC} $^ -o $@

# Object files
lib/%.o:: src/%.c
    ${CC} -c $< -o $@ ${CFLAGS}

# Dependencies
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
-include $(DEP)

.PHONY: clean
clean:
    rm lib/*

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.