How to up handle an uncle directory in Makefile? - makefile

How can I call within my Makefile a grand-uncle directory?
I have
LIBDIR = $(ROOTDIR)/lib
SRCDIR = $(ROOTDIR)/src
and my Makefile is in $(ROOTDIR)/src/utils.
I figured out how to go up one directory with
DIRUP := $(dir $(abspath $(lastword $(MAKEFILE_LIST))/..))
but I couldn't make it further!

Related

multiple Makefile for a single project

I am trying build a project with several modules included. the file tree looks like this:
the individual Makefiles for lib_one, lib_two and Main.cpp works fine, generating the 2 DLL and the EXE for the project, but requires enter at each directory and execute the command 'make' for each module.
I want now a Makefile in the top level directory ('/project') which triggers the building for all the other modules (DLLs and EXE) once. Based on some search results I got something like that:
lib_one := ./src/lib_one
lib_two := ./src/lib_two
libraries := $(lib_one) $(lib_two)
player := ./src
.PHONY: all $(player) $(libraries)
all: $(player)
$(player) $(libraries):
$(MAKE) --directory=$#
$(player): $(libraries)
when I execute the command 'make' I got this error:
Makefile:10: ***. Stop.
(the line 10 is this one: $(MAKE) --directory=$#). Besides a way to fix this error, I am looking to a way to accomplish this 3 things:
1)
the object files (*.o) from all the modules (DLLs and EXE) should be stores on a directory build in the same place from the directory src.
2)
the final files (*.dll and *.exe) should be placed in a directory reelease alongside the directories src and build.
3) if item 2 was possible, would be nice if each type of file being placed in a specific directory inside release (bin for *.exe, lib for *.dll and shared for other types). also, even with the exe and dlls in different directories, would be possible run the executable from this directory (making it search for the necessary libraries in ../lib alongside the other usual places?).
#Maxim is likely right for the cause of the error -- spaces vs tabs. As far as a your other questions go, without using non-recursive make, you could do something like:
Makefile:
export base_dir := ${CURDIR}
export obj_dir := ${base_dir}/build
export release_dir := ${base_dir}/release
lib_one := ${base_dir}/src/lib_one
lib_two := ${base_dir}/src/lib_two
libraries := $(lib_one) $(lib_two)
player := ${base_dir}/src
.PHONY: all $(player) $(libraries)
all: $(player)
$(player) $(libraries): | ${obj_dir} ${release_dir}
$(MAKE) --directory=$#
$(player): $(libraries)
${obj_dir} ${release_dir} :
#mkdir -f $#
The sub-makefiles would have access to any exported variable from the parent (see here), so in these you could do stuff like:
${obj_dir}/%.o : %.c
#echo compiling "$^ ==> $#"
$(CC) -c -o $# $^ $(CFLAGS)
which would compile the objects to the right directory.
Beware though -- if you have two components that produce an object file with the same name, because they're being produced in the same directory, you will end up with a potentially hard to debug race condition. Typically each component produces object files in its own unique directory to avoid this very thing.

How to replace .c and .cpp file together?

I am currently have an Android.mk file. For some requirement I need to write a standard GNU make file to build the same program.
As you know in Android native build, we simply put all source files together like
LOCAL_SRC_FILES := a.c b.c d.cpp e.cpp
Now I want to do something in Makefile like:
OBJ = $(LOCAL_SRC_FILES: .c=.o)
This will only transform .c files with .o object targets. How can I combine the condition ".c or .cpp" together?
I think I am too busy to forget that I can just achieve this target by execute this function twice.
TMP_OBJ = $(LOCAL_SRC_FILES: .c=.o)
OBJ = $(TMP_OBJ: .cpp=.o)
Sorry for this silly question.
You could use basename:
OBJ := $(addsuffix .o,$(basename $(LOCAL_SRC_FILES)))
(strips off the suffix of each file in LOCAL_SRC_FILES then adds .o to the end)
Doing it in two steps:
SRC := main.c hello.cpp
OBJ := $(SRC:.c=.o)
OBJ := $(OBJ:.cpp=.o)

makefiles compiling files to library

I'm new to makefiles , recently I was looking at a makefile and could not understand what this means
OBJS := $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
where
PROJECT_ROOT=.
EXTERNAL_ROOT=$(PROJECT_ROOT)/external
SRCDIR = $(PROJECT_ROOT)/src
OBJDIR = $(PROJECT_ROOT)/myobjs
BINDIR = $(PROJECT_ROOT)/mybins
DOCDIR = $(PROJECT_ROOT)/doc
what does it represent? Also i wish to make static library consistly of all files in in the myobjs folder or $(OBJS) except main.o a file in it how to write the command
ar -cvq mylibs/libCS296test.a $(OBJS); for such a case?
Please create different SO requests for very different questions.
For your first question, that is equivalent to this function:
$(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SOURCES))
which basically says "look through the value of the $(SOURCES) variable and for every word matching the pattern $(SRCDIR)/%.cpp, replace it with the pattern $(OBJDIR)/%.o. So, if SOURCES contained a word ./external/src/foo/bar/biz.cpp that would be replaced with ./external/myobjs/foo/bar/biz.o.

Include all libraries in a directory

How do includee all libraries from a directory in a Makefile?
Say I want to include all libraries in the directory /libdir, how would I do this?
The result should be something like:
INCLUDES = -I/libdir/lib1 -I/libdir/lib2 -I/libdir/lib3 ...
LIBDIRS = $(wildcard /libdir/*)
INCLUDES = $(addprefix -I, $(LIBDIRS))

Generate a list of files/objects dynamically from within makefile

I am trying to do this:
From a directory, pick all the C (.c) files, generate .o and add it to
my final target executable. The C files can be added or removed at anytime, so when I
run make for my target, the available C files from the directory has to be picked
to compile and link with my target.
So far, I have the following:
define test_tgt =
DIR = full/path/to/dir
FILES = $(wildcard $(DIR)/*.c)
OBJS = <rule-to-convert-C-to-O>
endef
get_new_files:
$(eval $(test_tgt))
final-target: get_new_files
$(CC) <other-objs> $(OBJS)
Somehow this doesn't seem to work. I see a lot of similar examples, but not sure what
is wrong here. If this approach is not correct, can anyone suggest a better way to
accomplish this.
TIA.
You are trying to program a check that make does by itself.
Just list $(OBJS) as dependencies of final-target.
Something like this should work under GNU make:
DIR = full/path/to/dir
FILES = $(wildcard $(DIR)/*.c)
OBJS = $(subst .c,.o,$(FILES))
final-target: $(OBJS)
$(LD) -o $# $+ # or similar
Full documentation is here: https://www.gnu.org/software/make/manual/html_node/Text-Functions.html

Resources