Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A Concise Makefile

I am doing some Makefile refactoring and trying to figure out the most concise way to implement a Makefile that does the following:

  1. Has one variable that has all the source files listed (can be both C and C++ files)
  2. All object files are generated in OBJ_DIR
  3. The object directory is created if it does not exist

Here is what I have so far:

...

OBJ_DIR = obj/
BIN_DIR = bin/
PROGRAM = program

SRCS = test1.cpp test2.c

OBJS  = $(addprefix $(OBJ_DIR), \
        $(patsubst %.cpp, %.o,  \
        $(patsubst %.c, %.o, $(SRCS))))

$(BIN_DIR)$(PROGRAM) : $(OBJS)
    $(CREATE_OUT_DIR)
    $(LINK)

$(OBJ_DIR)%.o : %.c
    $(CREATE_OBJ_DIR)
    $(CCOMPILE)

$(OBJ_DIR)%.o : %.cpp
    $(CREATE_OBJ_DIR)
    $(CPPCOMPILE)

...

I'd like to eliminate the call to $(CREATE_OBJ_DIR) for every .o compile. Anyone know how to do this? I tried adding this, but then it would not build the object files:

$(OBJS): | $(OBJ_DIR)

$(OBJ_DIR):
    $(CREATE_OBJ_DIR)
like image 794
waffleman Avatar asked Oct 11 '22 12:10

waffleman


2 Answers

You already seem to have solved your first point: Have them all in one variable (I shouldn't think you actually need to to separate them into TEMP1 and TEMP2 like you have, just have different build rules)

For the second point, you can tell the compiler where to output the object files (for g++ its like this:

g++ -c MySourceFile.cpp -o obj/MySourceFile.o

The make rule for this would look like:

obj/%.o: %.cpp
    g++ -c $*.cpp -o obj/$*.o

And your third point is also easily solved, as you can have a build rule for it (Just put the directory name in the dependency list for the target, before all of the objects are listed), and the build rule would look like this

obj:
    mkdir obj

Edit: or following your code examples:

$(BIN_DIR)$(PROGRAM) : $(BIN_DIR) $(OBJS) 
$(LINK)

$(BIN_DIR):
    $(CREATE_OUT_DIR) 
like image 66
deek0146 Avatar answered Oct 20 '22 07:10

deek0146


As for your 3rd point: This question has been asked here before. Unfortunately there is no really good answer for this, and you need to find the least ugly hack from the answer. Personally, I vote for the marker file solution.

like image 24
Chen Levy Avatar answered Oct 20 '22 08:10

Chen Levy