PseudoPsyche
PseudoPsyche

Reputation: 4592

How to use makefile to compile all sources (some only to object files)?

I'm getting an "undefined reference to main" error on one of my files when trying to compile. I know this is because this file doesn't have a main method. This is just an implementation file for some helper methods, so I only want it compiled to an object file not an executable. I know how to do this if I explicitly tell the makefile what to do for each file, but I'm trying to write a makefile that will compile all of my sources at once. I tried using the -c flag, but then it compiled all of my files to only object files rather than executables. How in the world do I do this? Here it is:

CC = gcc
CFLAGS = -g -Wall
SRCS = ./src/server.c ./src/client_slave.c ./src/sockaddrAL.c
EXECS = ./bin/server ./bin/client_slave
OBJS = $(SRCS:.c=.o)

all: clean $(SRCS) server client

server: $(OBJS)
        $(CC) $(CFLAGS) ./src/server.o -o ./bin/server

client: $(OBJS)
        $(CC) $(CFLAGS) ./src/client_slave.o -o ./bin/client_slave

.c.o:
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        @rm -f $(EXECS) $(OBJS)

Upvotes: 2

Views: 4755

Answers (2)

MadScientist
MadScientist

Reputation: 100946

You should add the -c flag to the rule that builds .o files (your .c.o suffix rule) and not add it to the rule that builds the executables (the $(EXECS) rule).

CC = gcc
CFLAGS = -g -Wall
EXECS = ./bin/server ./bin/client_slave

all: $(EXECS)

./bin/%: ./src/%.o ./src/sockaddrAL.o
        $(CC) $(CFLAGS) -o $@ $^

.c.o:
        $(CC) $(CFLAGS) -c $< -o $@

clean:
        @rm -f $(EXECS) $(OBJS)

You didn't show sockAddrAL at all in your question so I assumed it belonged in both executables. Also note that the above syntax assumes GNU make. If you want to use only features available in POSIX standard make you pretty much have to write it all out.

Upvotes: 3

William Pursell
William Pursell

Reputation: 212454

Let implicit rules be your friend. Your entire Makfefile should just be:

CC = clang
CFLAGS = -O0 -g -Wall
SRCS = server.c client_slave.c sockaddrAL.c
OBJS = $(SRCS:.c=.o)
EXECS = server

server: $(OBJS)

clean:
    @rm -f $(EXECS) $(OBJS)

Invoke it from the src directory.

Upvotes: 1

Related Questions