create objects files depending on the name of target - linux

Is it possible to create objects files in makefile depending on the name of the target?
something like
all : gsm gsm_db
if make gsm
%.o : %.cpp
$(CC) $(CFLAGS) $< -o $#
if make gsm_db
%.o : %.cpp
$(CC) $(CFLAGS_DB) $< -o $#

Something like this should work:
ifneq "$(filter gsm_db, $(MAKECMDGOALS))" ""
%.o : %.cpp
$(CC) $(CFLAGS_DB) $< -o $#
else
%.o : %.cpp
$(CC) $(CFLAGS) $< -o $#
endif

Related

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.)

Undefined reference error while compiling

I'm trying to compile a project that has multiple *.c files and *.h file when I type the following command:
$gcc -c -I ../hdr main.c gestic.c menu.c
the hdr folder is where the *.h files are located, the .o files are created but when I try to link them using the command:
$gcc -o main.o gestic.o menu.o
I see errors
gestic.c:(.text+0x..): undefined reference to functions that are declared in *.h files
$gcc -Wall -c -I../hdr -o main.o main.c
$gcc -Wall -c -I../hdr -o menu.o menu.c
$gcc -Wall -c -I../hdr -o gestic.o gestic.c
$gcc -Wall -o myprogram main.o menu.o gestic.o
Using a Makefile is very common for this task
example (untested) Makefile:
CC=gcc
CFLAGS=-Wall -I../hdr
all: myprogram
myprogram: main.o menu.o gestic.o
$(CC) -o $# $^
gestic.o: gestic.c
$(CC) $(CFLAGS) -c -o $# $<
main.o: main.c
$(CC) $(CFLAGS) -c -o $# $<
menu.o: menu.c
$(CC) $(CFLAGS) -c -o $# $<
Try:
$ gcc main.o gestic.o menu.o
-o filename: Place output in filename
Firstly header files are not included, secondly you might use the function that doesn't contain the definition.
The message undefined reference to 'function_name' implies that of all the object files you're giving to the linker, none of them has a definition for function_name. That means that either
You're not linking with *.o
*.c (as compiled) does not contain a definition for function_name -- by 'as compiled' I mean with all of the various preprocessor options you use on it.
here -Iinclude/
try,
gcc -c file.c -I<include_dir>
If you compile more files better to have makefile to create the objects of those files, link those objects along with header.
Sample makefile,
CC = gcc
CFLAGS = -Wall
INCLUDE = sample.h
OBJ = samople1.o sample2.o
%.o: %.c $(INCLUDE)
$(CC) $(CFLAGS) -c -o $# $<
go: $(OBJ)
gcc $(CFLAGS) -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.

Makefile auto-dependency generation

I am trying to see auto generated dependency the makefile is below:
OBJS := main.o
run : $(OBJS)
$(CC) $(OBJS) -o run -lstdc++
-include $(OBJS:.o=.d)
%.o : %.cpp
$(CC) -c $(CFLAGS) $*.cpp -o $*.o
%.d : %.cpp
#set -e; rm -f $#; \
$(CC) -M $(CPPFLAGS) $< > $#.$$$$; \
echo "creating dependency file."; \
sed 's,\($*\)\.o[ :]*,\1.o $# : ,g' < $#.$$$$ > $#; \
rm -f $#.$$$$
# remove compilation products
clean :
rm -f run *.o *.d*
But the makefile generate a huge list of dependency in main.d but the actual needed is the first few lines. So where I am getting wrong?
Try this instead:
OBJS := main.o
run : $(OBJS)
$(CC) $(OBJS) -o run -lstdc++
-include $(OBJS:.o=.d)
%.o : %.cpp
$(CC) -c -MMD -MP $(CFLAGS) $*.cpp -o $*.o
# remove compilation products
clean :
rm -f run *.o *.d*

Makefile Wildcard Issues

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

Resources