HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Makefile -- Platform Dependency

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
platformmakefiledependency

Problem

My application has two parts -- a client and a server. Within this, there are different versions for different platforms. The user specifies this in the args, i.e. "make PLATFORM=x11".

However, I feel like I'm separating the client and server build operations in a very inefficient way, and that I have too many variables. It works, but I'm not sure how to improve it.

Any suggested improvements would be much appreciated!

CC=gcc
CFLAGS=-c -Wall
LDFLAGS=
BUILD_DIR = ../build/
OBJ_DIR = $(BUILD_DIR)obj/
LIBS=

CLIENT_NAME_DIR = client/
CLIENT_SRC_FILES := $(wildcard $(CLIENT_NAME_DIR)*.c)
CLIENT_PLATFORM_DIR = $(PLATFORM)/
CLIENT_SRC_FILES += $(wildcard $(CLIENT_NAME_DIR)$(CLIENT_PLATFORM_DIR)*.c)
CLIENT_OBJ_DIR = $(OBJ_DIR)$(CLIENT_NAME_DIR)
CLIENT_OBJ_FILES := $(addprefix $(CLIENT_OBJ_DIR),$(notdir $(CLIENT_SRC_FILES:.c=.o)))
CLIENT_LIBS = $(LIBS) -lX11
CLIENT_EXECUTABLE_NAME = outcast-client
CLIENT_EXECUTABLE=$(BUILD_DIR)$(CLIENT_EXECUTABLE_NAME)

SERVER_NAME_DIR = server/
SERVER_SRC_FILES := $(wildcard $(SERVER_NAME_DIR)*.c)
SERVER_OBJ_DIR = $(OBJ_DIR)$(SERVER_NAME_DIR)
SERVER_OBJ_FILES := $(addprefix $(SERVER_OBJ_DIR),$(notdir $(SERVER_SRC_FILES:.c=.o)))
SERVER_LIBS = $(LIBS)
SERVER_EXECUTABLE_NAME = outcast-server
SERVER_EXECUTABLE=$(BUILD_DIR)$(SERVER_EXECUTABLE_NAME)

all: clean client server

client: $(CLIENT_SRC_FILES) $(CLIENT_EXECUTABLE)

server: $(SERVER_SRC_FILES) $(SERVER_EXECUTABLE)

$(CLIENT_EXECUTABLE): $(CLIENT_OBJ_FILES)
    $(CC) $(LDFLAGS) $(CLIENT_OBJ_FILES) -o $@ $(CLIENT_LIBS)

$(CLIENT_OBJ_DIR)%.o: $(CLIENT_NAME_DIR)$(CLIENT_PLATFORM_DIR)%.c
    $(CC) $(CFLAGS) -c -o $@ %%CODEBLOCK_0%%lt;

$(CLIENT_OBJ_DIR)%.o: $(CLIENT_NAME_DIR)%.c
    $(CC) $(CFLAGS) -c -o $@ %%CODEBLOCK_0%%lt;

$(SERVER_EXECUTABLE): $(SERVER_OBJ_FILES)
    $(CC) $(LDFLAGS) $(SERVER_OBJ_FILES) -o $@ $(SERVER_LIBS)

$(SERVER_OBJ_DIR)%.o: $(SERVER_NAME_DIR)%.c
    $(CC) $(CFLAGS) -c -o $@ %%CODEBLOCK_0%%lt;

clean:
    rm -rf $(BUILD_DIR)
    mkdir -p $(CLIENT_OBJ_DIR)
    mkdir -p $(SERVER_OBJ_DIR)

Solution

Conner, I have a few minor points.

-
Firstly, you have no includes (ie, no -Idir). Do you really have no headers?

-
You should make the non-targets 'PHONY' so make knows they will never exist:

.PHONY clean
clean: 
        rm -f ...


Same with all, server and client

-
It is not normal to clean everything on each build - usually you let make decide what is out of date and needs to be rebuilt. For that you need to have all the dependencies declared to make (eg headers)

-
client and server depend upon the build directories and the executables, but not directly upon the sources.

-
the clean target remakes the build directories. To me, these directories should be made when you build the targets:

$(CLIENT_OBJ_DIR) $(SERVER_OBJ_DIR):
        mkdir -p $@ 

client: $(CLIENT_OBJ_DIR) $(CLIENT_EXECUTABLE)

server: $(SERVER_OBJ_DIR) $(SERVER_EXECUTABLE)


-
-Wall does not really give you 'all' warnings. There are many more that are worth enabling.

Code Snippets

.PHONY clean
clean: 
        rm -f ...
$(CLIENT_OBJ_DIR) $(SERVER_OBJ_DIR):
        mkdir -p $@ 

client: $(CLIENT_OBJ_DIR) $(CLIENT_EXECUTABLE)

server: $(SERVER_OBJ_DIR) $(SERVER_EXECUTABLE)

Context

StackExchange Code Review Q#18159, answer score: 3

Revisions (0)

No revisions yet.