Building library with make - makefile

I have makefile with the following content:
libcommon.a : $(COMMON_CFILES:.c=.o) filter_scan.o filter_expr.o $(META_O_FILES)
ar rcv $# $^
So I have a few small questions about this syntax.
What are .a .so .o extenstions?
What does mean
$(COMMON_CFILES:.c=.o)
specifically, what are .c and .o?
(there is a COMMON_CFILES "label", (i don't know how to name that) with the list of .c files)
What is ar rcv $# $^?

.a is a static library. They are maintained with the ar command.
.so is a shared library.
$(COMMON_CFILES:.c=.o) takes a Makefile macro named COMMON_CFILES, splits it into words, and replaces .c with .o in each token. So it converts C source file names to their corresponding object file names.
.c is the suffix of C source files.
ar rcv $# $^ updates the archive libcommon.a ($#) with the files from its dependencies. ($^)

Related

object files both in prerequisites and recipe output as targets in makefile

With coding like
$(PROG): $(PROCESS) $(CHECK_SA) makefile $(LIBS)
$(FC) $(FFLAGS) -o $(PROG) $(PROCESS) $(CHECK_SA) $(LINKLIBS)
The $(PROCESS) is .o object files.
There don't exist .o files in the directory at beginning. So when run make, it will first generate object files as prerequisites. So the target $(PROCESS) after -o is for creating the prerequisites? Is that correct?
But one thing that is strange is that, suppose I already have the object files at the beginning, it surely will come as prerequisites. But why do we still need the object file after -o as targets?
So what is the use of the same object files appearing both in the prerequisite and targets? Especially the target object files after -o.

How do I assemble multiple assembly files into multiple object files with a Makefile?

I want to be able to turn all the *.asm files in a folder to *.o files. For example, if I have header.asm and main.asm, I want header.o and main.o. Nasm can only assemble 1 input file to 1 output file.
I have tried this:
%.o : %.asm
nasm -f elf64 $(patsubst %.o,%.asm,$#) -o $#
along with multiple other things but to no success.
Somewhere you have to tell make what files you want to assemble. A pattern rule is just a template for how to build a .o from a .asm. It's not an instruction that says "go find all .asm files and turn them into .o files". It's a template that says, IF you want to build a .o file, and you can find a .asm file, then here's how you can turn the latter into the former.
So, you need a pattern rule to describe how to build things:
%.o : %.asm
nasm -f elf64 $< -o $#
then you also need a list of the things you want to build; say:
all: foo.o bar.o baz.o
(since you haven't told us anything about the names of the .asm files you want to build I just used random names).

Makefile pattern to compile all source files to executables

I want my makefile to identify and build every source file in the directory.
Both .f files and their executables exists in the current directory. All source files are short, independent pieces (no linking to each other). I want executables to be named the same as the source files sans .f (foo.f -> foo)
The following does not work:
FC=gfortran
% :: %.f
${FC} -Wall $< -o $#
When I run Make I get
make: *** No targets. Stop.
How can I get make to do what I want?
The following makefile does what I want:
FC=gfortran
FFLAGS=-Wall
SRC = $(wildcard *.f)
EXE = $(SRC:.f=)
all : $(EXE)

.cpp to .o files in Makefile

How can I generate .o file corresponding to all the .cpp files in a directory using Makefile?
I have a directory that contains .cpp files. Now, I want to compile them in .o files. The name of the .o files should be same as corresponding .cpp files. What should I do?
Actually, I already had an implementation but I am not sure how it work
SRCS := $(wildcard $(SRCDIR)/*.cpp)
OBJS := $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
// Recipe //
Try this
SRCS=$(wildcard *.cpp)
OBJS=$(SRCS:.cpp=.o )
%.o: %.cpp
$(CC) -c $< -o $#
Let me add some more explaination to it.
SRCS := $(wildcard $(SRCDIR)/*.cpp) - It will list all the .cpp files under SRCDIR directory and will assign to SRCS
OBJS := $(SRCS:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o) - It will replace all the files with .cpp listed from the above statement to .o ex: main.cpp would be changed to main.o and assigned to OBJS
$(OBJDIR)/%.o : $(SRCDIR)/%.cpp - Object files depends on respective .cpp files and in the rule you can write rule to create object files
The % character can be used for wildcard pattern-matching, to provide generic targets. For example:
%.o: %.c
[TAB] actions
When % appears in the dependency list, it is replaced with the same string that was used to perform substitution in the target.
If the above explanation is not clear just go through the Makefile Basics once and try writing without using special variables and then go to the complex rules.

How to define a pattern which is valid for all files in the directory including subdirectories?

I'm writing a pattern for compiling all .c file in the test directory.
Details of the directory is as follows:
./prj/makefile
./prj/test
./prj/test/test1/a.c
./prj/test/test1/b.c
./prj/test/test2/c.c
./prj/test/test2/d.c
./prj/test/e.c
...
Just a demo. This is my content of makefile:
# Find all files
rwildcard := $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
# All .c files
SRC_FILES := $(call rwildcard,test,*.c)
# All .o files
OBJ_FILES := $(SRC_FILES:.o=.c)
all : $(OBJ_FILES)
echo $(OBJ_FILES)
%.o : %.c
echo $# $<
Make prints No rule to make target '...'. I think make need know path of .o files and .c files. But I don't know how to setting the path, Since there is so many .c files in my prj.
Because OBJ_FILES has includes all .o files. Then I guess the pattern should be like this:
$(output_dir)/%.o : $(input_dir)/%.c
echo $# $
Since here may have many directories in ./prj/test, I cann't hardcoded it in makefile
Thanks for another friend, the above approach is right. since % can match many Multi-level directories。
We can't really solve your problem because you still have not specified where the object files should go. All in a specific directory? Always in the parent directory of the source file? Somewhere else?
Regardless of how you resolve that, you can add all your source directories to VPATH and have Make resolve the precise location while figuring out the dependencies.
VPATH=test:test/test1:test/test2
experiment: a.c d.c
echo $^
will echo test/test1/a.c test/test2/d.c with full paths.
So with this you can remove the hard-coded directory names from your %.o rule and simply specify which .o files you want built for the all target.
You can use this to get all c files in subdirectories:
$(wildcard */*.c)
Or also this to get all c files in subdirectories at any depth:
$(wildcard **/*.c)

Resources