Makefile Wildcard Issues - linux

So I am having some issues understanding how exactly the % wildcard actually works using makefile. I have looked at static pattern rules in the GNU make man but i am still pretty confused and I feel like I have seen them do something similar to what I have below.
EXEC = a.out
CC = gcc
FLAGS = -Wall -c
$(EXEC): %.o
$(CC) -o $(EXEC) $<
%.o: %.c
$(CC) $(FLAGS) $<
clean:
rm -rf *.o
I keep getting an error that says %.o rule not defined. If someone could explain why this is wrong (probably in many ways, guessing the automatic variable part is incorrect as well) that would be appreciated !

I'm not sure what you intend, but I'm pretty sure that this rule:
$(EXEC): %.o
$(CC) -o $(EXEC) $<
doesn't do it. In this rule, '%' is not any kind of wildcard, it's just a character. So when Make tries build a.out, it goes looking for a file called %.o, can't find it, doesn't have a rule to build it (since there is no %.c and no way to build that), and gives up.
Your intention is unclear. If you want the rule to be able to build a.out from a.o (and likewise foo.out from foo.o, and bar.out from bar.o, and so on), write a pattern rule:
%.out: %.o
$(CC) -o $# $<
$(EXEC): # Make will not use a pattern rule as the default, so we need this
(Note the use of $#.) Or (to restrict it to executables in the EXEC list) a static pattern rule:
$(EXEC): %.out : %.o
$(CC) -o $# $<
If, on the other hand, you want Make to use all the source files it can find to build this executable, you must do something like this:
SOURCES = $(wildcard *.c) # make a list a.c foo.c bar.c
OBJECTS = $(patsubst %.c, %.o, $(SOURCES)) # translate it into a.o foo.o bar.o
$(EXEC): $(OBJECTS)
$(CC) -o $^ $<
Note the use of the wildcard function, and $^ which expands to the list of prerequisites, and also note that "*.o" wouldn't do you much good.

when I used to use makefiles long time ago they looked more like below. For each executable we listed the required object files explicitly.
CC = gcc
FLAGS = -Wall -c
prog1: mod1.o mod2.o
$(CC) mod1.o mod2.o -o prog1
prog2: mod1.o mod3.o
$(CC) mod1.o mod3.o -o prog2
%.o: %.c
$(CC) $(FLAGS) $<
clean:
rm -rf *.o

Related

Multiple SRCDIR folders for compilation using makefile

I am trying to do the following, where SRCDIRS includes all folders containing the source code by doing the following in the makefile:
SRCDIRS := $(shell find $(SRCDIR) -type d )
$(OBJDIR)/%.o: $(SRCDIRS)/%.f90 Makefile
#$(F90) $(FFLAGS) $(POPTIONS) -o $# $<
My make file seems to ignore the %.o rule?
I also have a defined $(OBJS) which includes all my %.o files
You can't "multiply" strings that way in Make. And even if you could, you'd be specifying the wrong paths. Use vpath:
vpath %.f90 $(SRCDIRS)
$(OBJDIR)/%.o: %.f90 Makefile
#$(F90) $(FFLAGS) $(POPTIONS) -o $# $<

Makefile : How to specify where to generate an object

I would like to specify a repository for an object I generate in my makefile.
I searched for a while but only found elaborate solutions, for a list of objects, while I would like to TARGET ONE OBJECT ONLY.
(makefile is new for me, so the simpler the better)
Here is my code:
///////////////////////////////////
*definition of several directories*
*definition of CC, CFLAGS, CInclude*
cutgen:
$(CC) $(CFlags) -D__LINUX__ $(CDir)cutgen.c -o cutgen
check: cutgen cutcheck.c *list of objects here*
$(CC) $(CFlags) -I $(CHeaderDir) cutcheck.c *list of objects here* -o cutcheck
./cutcheck
cutcheck.c: cutgen test.o
./cutgen $(CDir)test.c -o cutcheck.c
test.o: util.o
$(CC) $(CFlags) -c $(CInclude) $(CDir)test.c
util.o: config.o
$(CC) $(CFlags) -c $(CInclude) $(GenDir)util.c
...
...
stubs.o:
$(CC) $(CFlags) $(CInclude) -c $(StubsDir)stubs.c
clean:
rm -f *.o *~ cutcheck* cutgen
all: check
///////////////////////////////////
Here for example, I would like to generate util.o in the Objects folder.
Any help would be appreciated, thank you in advance !
$(Objects)/util.o: config.o
$(CC) $(CFlags) -c $(CInclude) $(GenDir)util.c -o $#
(And are you sure about that prerequisite? I think $(GenDir)util.c might be better than config.o.)

I want to know about command in makefile

FC= ifort
FCFLAGS=-O2 -r8 -openmp -mcmodel=large -extend-source -shared-intel -I$(HOME)/usr/include
LDFLAGS=-L$(HOME)/usr/lib -lfftw3 -lm
TARGET=Project
Project: a.o b.o c.o d.o
#
all : $(TARGET)
%: %.o
$(FC) $(FCFLAGS) -o $# $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
all : $(TARGET)
clean :
rm *.o
when I studied makefile, there is no information for
#
all : $(TARGET)
and function of % and $^. I wanna check about these things. Thanks for your help.
all is a target (repeated twice in that makefile for no reason). So is clean. Targets are how make works. See Rule Example.
$^ is one of the Automatic Variables available for use in target recipes.
% is a wildcard used in some make functions and in Pattern Rules.

Makefiles output directory

I am a bit a beginner in using makefiles and I am trying to write a makefile for gcc that accepts the inputs from two different directories (in my case they are called kernel and drivers) and output the object files in a different directory (called tmp) using wildcards.
I have written this code to get the names of input files and output files
C_SOURCES = $(wildcard $(KERNEL_DIR)/*.c $(DRIVERS_DIR)/*.c)
#Creating a list for object files names
C_OBJ = $(C_SOURCES:.c=.o)
and I am using the following rule
%.o: %.c $(CC) $(CFLAGS) -c $< -o $#
but i can't get to output the object files in the desired directory.files
Something like this example should do it for you. I split things up a bit for readability, but I'm sure you'll get the idea:
KERNEL_SOURCES = $(wildcard $(KERNEL_DIR)/*.c)
DRIVER_SOURCES = $(wildcard $(DRIVER_DIR)/*.c)
OBJECTS = $(patsubst $(KERNEL_DIR)/%.c,tmp/%.o,$(KERNEL_SOURCES))
OBJECTS += $(patsubst $(DRIVER_DIR)/%.c,tmp/%.o,$(DRIVER_SOURCES))
Watch out for source files with the same name in both KERNEL_DIR and DRIVER_DIR!
You have to make a separate rule for each subdirectory, like this:
SOURCES := $(wildcard $(KERNEL_DIR)/*.c $(DRIVER_DIR)/*.c)
OBJECTS := $(patsubst %.c,$(OBJECT_DIR)/%.o,$(notdir $(SOURCES)))
all: $(OBJECTS)
$(OBJECT_DIR)/%.o : $(KERNEL_DIR)/%.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $# $<
$(OBJECT_DIR)/%.o : $(DRIVER_DIR)/%.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $# $<
Obviously you'll have big problems if you have a foo.c file in both source directories...

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

So my task is simple, I have created the makefile (New with makefiles) and I want to keep my .o files in a different folder to have a cleaner directory and allow the usage of .o files by others.
I searched and found many solution pointing to using -o $< $#
However, it is giving me that g++: cannot specify -o with -c or -S with multiple files
This is what I want to do:
$(OBJECT_PATH)/file1.o: $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp
$(CC) $(CFLAGS) $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp -o $#
file1.cpp has #include "file1.h", so from what I read I should include file1.cpp in the dependencies. However, now I can't export to a different directory.
Is there a solution? Or do I have the concept wrong?
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)
try
$(OBJECT_PATH)/file1.o: $(SOURCE_PATH)/file2.cpp $(SOURCE_PATH)/file1.cpp
$(CC) $(CFLAGS) $^ -c $#
and check that CFLAGS doesn't include -o -c or -s flags
also read about implicit rules. it might help you to orginzie your makefile

Resources