Makefile Export .O File to a Different Path Than .Cpp

Makefile export .o file to a different path than .cpp

Use make -d or even better remake -x to understand what commands are invoked.

Run also make -p to understand what builtin rules are used.

We cannot help you more, because we have no idea if you redefined CFLAGS.

And C++ compilation should better be done with g++ that is CXX and CXXFLAGS, e.g. with (I am extracting this from my make -p output)

LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
CXX = g++
%.o: %.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $<

I strongly suggest to have CXXFLAGS= -Wall -g at least during the development phase. Learn also to use gdb and valgrind.

You could have the following in your Makefile

 CXXFLAGS= -g -Wall
SOURCES=f1.cc f2.cc
SOURCE_PATH=yoursourcedir/
OBJECT_PATH=yourobjectdir/
SRCFILES=$(patsubst %.cc,$(SOURCE_PATH)/%.cc,$(SOURCES))
OBJFILES=$(patsubst %.cc,$(OBJECT_PATH)/%.o,$(SOURCES))
PROGFILE=$(OBJECT_PATH)
.PHONY: all clean
all: $(PROGFILE)
$(PROGFILE): $(OBJFILES)
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@
$(OBJECT_PATH)/%.o: $(SOURCE_PATH)/%.cc
$(COMPILE.cc) $(OUTPUT_OPTION) $<
clean:
$(RM) $(OBJECT_PATH)/*.o $(PROGFILE)

How to place object files in separate subdirectory

Since you're using GNUmake, use a pattern rule for compiling object files:

$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<

Makefile: How to correctly include header file and its directory?

These lines in your makefile,

INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)
DEPS = split.h

and this line in your .cpp file,

#include "StdCUtil/split.h"

are in conflict.

With your makefile in your source directory and with that -I option you should be using #include "split.h" in your source file, and your dependency should be ../StdCUtil/split.h.

Another option:

INC_DIR = ../StdCUtil
CFLAGS=-c -Wall -I$(INC_DIR)/.. # Ugly!
DEPS = $(INC_DIR)/split.h

With this your #include directive would remain as #include "StdCUtil/split.h".

Yet another option is to place your makefile in the parent directory:

root
|____Makefile
|
|___Core
| |____DBC.cpp
| |____Lock.cpp
| |____Trace.cpp
|
|___StdCUtil
|___split.h

With this layout it is common to put the object files (and possibly the executable) in a subdirectory that is parallel to your Core and StdCUtil directories. Object, for example. With this, your makefile becomes:

INC_DIR = StdCUtil
SRC_DIR = Core
OBJ_DIR = Object
CFLAGS = -c -Wall -I.
SRCS = $(SRC_DIR)/Lock.cpp $(SRC_DIR)/DBC.cpp $(SRC_DIR)/Trace.cpp
OBJS = $(OBJ_DIR)/Lock.o $(OBJ_DIR)/DBC.o $(OBJ_DIR)/Trace.o
# Note: The above will soon get unwieldy.
# The wildcard and patsubt commands will come to your rescue.

DEPS = $(INC_DIR)/split.h
# Note: The above will soon get unwieldy.
# You will soon want to use an automatic dependency generator.


all: $(OBJS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
$(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR)/Trace.o: $(DEPS)

How to export directly in a Makefile?

If you want to handle exporting from Makefile, then try:

$(NAME): $(OBJS)
@export MY_ENV_VAR=my_value; \
$(CXX) -o $(NAME) $(OBJS) $(CXXFLAGS) $(LDFLAGS)

Exporting will only work if called in the same subshell with the command itself.

However, this solution is not going to work for LD_LIBRARY_PATH, because your intention is to update the parent process from make, which is not possible.

The workaround is to create a wrapper script that would:

  • build your application by calling make
  • set the LD_LIBRARY_PATH
  • launch your application

How to define several include path in Makefile

You have to prepend every directory with -I:

INC=-I/usr/informix/incl/c++ -I/opt/informix/incl/public

Make: circular dependency dropped c++


$(BIN_DIR)/main.o:$(SRC_DIR)/main.cpp $(OBJECTS) $(H_FILES)

On this line you say to build main.o , I need main.cpp *.h and *.o

But *.o has main.o so you write main.o depend of main.o. Just remove $(OBJECTS) you don't need object to build a object.

$(BIN_DIR)/main.o:$(SRC_DIR)/main.cpp $(H_FILES)

Don't use wildcard, it's better to explicit your sources files. Don't use CC for c++ compiler, the standard use CXX.

exemple of Makefile:

NAME    =   foo

CXX ?= g++

RM = rm

DEBUG ?= no

LEVEL ?= 3

LIB = -l m

INCLUDE = -I include

CXXFLAGS += -Wall -Wextra -O$(LEVEL)
CXXFLAGS += -ansi -pedantic -std=c++11
CXXFLAGS += $(INCLUDE)

ifeq ($(CXX), clang++)
CXXFLAGS += -Weverything
endif

ifneq ($(DEBUG), no)
CXXFLAGS += -g
endif

LDFLAGS = $(LIB)

ifeq ($(DEBUG), no)
LDFLAGS += -s
endif

SRC = main.cpp
SRC += foo.cpp

DPD = $(SRC:.cpp=.dpd)

OBJ = $(SRC:.cpp=.o)

all : $(NAME)

$(NAME) : $(OBJ)
$(CXX) $(OBJ) -o $(NAME) $(LDFLAGS)

clean :
$(RM) -f $(OBJ)
$(RM) -f $(DPD)

fclean : clean
$(RM) -f $(NAME)

re : fclean
$(MAKE) -C .

%.dpd : %.cpp
$(CXX) -MM $(<) -o $(@) $(CXXFLAGS) -MT $(<:.cpp=.o)

%.o : %.cpp
$(CXX) -c $(<) -o $(@) $(CXXFLAGS)

.PHONY : all clean fclean re %.dpd %.o

.SUFFIXES : .o.cpp .dpd.cpp

include $(DPD)

makefile pathing issues on OSX

I tried your example on OSX and Linux, and got the same results that you did. I don't quite understand why that isn't working (and would love to know), but I do have two workarounds that might help.

export SHELL

Instead of setting the PATH in your Makefile, override the SHELL like this:

export SHELL=/Users/whatever/avr-dir/wrapper

Here's a possible version of that wrapper:

#!/bin/bash
PATH="/Users/whatever/avr-dir:${PATH}"
/bin/bash "$@"

Make will invoke this wrapper to run each line of yoru recipes. This is a little ugly, but it did work for me on OSX.

Outside

Fix the PATH outside of make. Perhaps create a script that you run once per login that fixes the PATH in your shell, or create a small script (I usually call it mk) that fixes the PATH and then invokes make passing along any parameters. Here's an exmaple:

#!/bin/bash
PATH="/Users/whatever/avr-dir:${PATH}" exec make "$@"

I know you asked for a Makefile solution, but I thought I would mention this option anyway. It is just my opinion, but things like PATHs tend to be machine specific (and not project specific), and I prefer to keep them separate from source code.



Related Topics



Leave a reply



Submit