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
How to Build a Linux Kernel Module So That It Is Compatible with All Kernel Releases
Qt Development on Linux Using Eclipse
Makefile with Multiple Targets
Perl Fails to Set Locale Even Though It Is Installed
Can't Find Out Where Does a Node.Js App Running and Can't Kill It
What Is the Linux Process Table? What Does It Consist Of
How to See Linux' View of the Ram in Order to Determinate the Fragmentation
Track the Time a Command Takes in Unix/Linux
Will Adding the -Rdynamic Linker Option to Gcc/G++ Impact Performance
Pyqt5 Error "Pycapsule_Getpointer Called with Incorrect Name"
Rename Part of File Name Based on Exact Match in Contents of Another File
Linux. Sol_Netlink Not Defined
How to Ignore Line Breaks in Input Using Nasm Assembly
How to Convert a PDF into Jpg with Command Line in Linux
Linux-Shell: Renaming Files to Creation Time
How to Get the Exit Code of Spawned Process in Expect Shell Script