0
votes

I'm following this tutorial on how to make a makefile. I've made one below for my project. However, there is a problem with the linking stage and the order of the files.

The tutorial says that LINK.cc makes use of cxx, cxxflags, ldflags and is defined as

$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

The command line gives this output which indicates that main.o is being placed after linking when it should be before hand.

gcc  -I./include -I/usr/local/include/upm  -c -o utils.o utils.c
g++  -I./include -I/usr/local/include/upm -L/usr/local/lib/x86_64-linux-gnu -L/usr/local/lib/ -lrabbitmq -lupmc-rn2483 -lupmc-utilities -lupmc-rn2903  main.o utils.o  -o myprogram

Correct command:

gcc main.o -I./include -I/usr/local/include/upm -L/usr/local/lib/x86_64-linux-gnu -L/usr/local/lib/ -lrabbitmq -lupmc-rn2483 -lupmc-utilities -lupmc-rn2903  utils.o  -o myprogram

My question is how do I fix the makefile?

Makefile

program_NAME := myprogram
program_C_SRCS := $(wildcard *.c)

program_CXX_SRCS := $(wildcard *.cpp)

program_C_OBJS := ${program_C_SRCS:.c=.o}

program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o}

program_OBJS := $(program_C_OBJS) $(program_CXX_OBJS)

program_INCLUDE_DIRS := ./include /usr/local/include/upm

program_LIBRARY_DIRS := /usr/local/lib/x86_64-linux-gnu /usr/local/lib/

program_LIBRARIES := rabbitmq upmc-rn2483 upmc-utilities upmc-rn2903 

CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir))
LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir))
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))

CC = gcc
CXX = g++

LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)

LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

.PHONY: all clean distclean

all: $(program_NAME)

$(program_NAME): $(program_OBJS)
    $(LINK.cc) $(program_OBJS) -o $(program_NAME)


clean:
    @- $(RM) $(program_NAME)
    @- $(RM) $(program_OBJS)

distclean: clean

This is the dir structure:

.
├── include
│   └── utils.h
├── main.c
├── Makefile
└── utils.c
2
The variable program_C_OBJS contains "utils.o", and program_CXX_OBJS contains "main.o", is that right?Beta
@Beta thanks for your reply. No I don't thinks so main.c and utils.c are both c files so there should be no C++ object files. I included the directory tree in my original question. thanksarcoxia tom
Then what is the pattern? You want 'main.o` before the flags, and all other objects after the flags?Beta
Its producing this pattern, main.o is after the flags. How do i change the make file to fix this? g++ -I./include -I/usr/local/include/upm -L/usr/local/lib/x86_64-linux-gnu -L/usr/local/lib/ -lrabbitmq -lupmc-rn2483 -lupmc-utilities -lupmc-rn2903 main.o utils.o -o myprogram arcoxia tom

2 Answers

1
votes

Don't put libraries (-l) in LDFLAGS, put them in LDLIBS instead. The linking rule used by make is:

$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@

The change for your makefile is

LDLIBS += $(foreach library,$(program_LIBRARIES),-l$(library))
[...]
$(LINK.cc) $(program_OBJS) -o $(program_NAME) $(LDLIBS)
0
votes

It's not entirely clear what you want in the general case, but this should give you what you're asking for.

Add this:

LINKFLAGS :=$(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

and change the $(program_NAME) rule to this:

$(program_NAME): $(program_OBJS)
    $(CC) main.o $(LINKFLAGS) $(filter-out main.o, $(program_OBJS)) -o $(program_NAME)

Other refinements are possible once you have this working.