Trouble using vpath in makefile - c

I had a bunch of src files ( all in one folder) and .h files spread over different folders. With a makefile i was able to build the .c files successfully.
Now, i introduced 2 .c files , but in a different folder to the makefile and am not able to make a successful build. I went through online and came to know that i need to use vpath for this. But even after using vpath, i get errors in the building of the .c file in the new folder.
1) In the below make file, the new .c files added later were fbpath.c and stream.c.
2) I also include the relative path for the include files that these .c files reference.
3) Then i added VPATH, to point to the place where .c files are present.
The error i get is
fbpath.c:30:24: fatal error: config.h: No such file or directory
compilation terminated.
but the config.h file is very much present in the INC. I also provided the full path.
Can someone please point me to any mistakes i have done.
Thanks
here is my make file
CC=arm-linux-gnueabihf-gcc
CFLAGS= -c -Wall -std=c99 -fmessage-length=0 -O0
INC = -I. -I../inc -I../APP/inc -I../../../common -I/home/user/workdir/Final/test -I/home/user/workdir/Final/inc -I../../inc
LDFLAGS=-lm
VPATH:=../APP/src
OBJ = main.o correct.o alignment.o fastmath.o cov_est.o subsample.o state.o cconv.o fbpath.o stream.o
myprogram: $(OBJ)
$(CC) $(LDFLAGS) -o myprogram $(OBJ)
correct.o : correct.c
$(CC) $(CFLAGS) $(INC) correct.c
alignment.o : alignment.c
$(CC) $(CFLAGS) $(INC) alignment.c
fastmath.o : fastmath.c
$(CC) $(CFLAGS) $(INC) fastmath.c
cov_est.o : cov_est.c
$(CC) $(CFLAGS) $(INC) cov_est.c
subsample.o : subsample.c
$(CC) $(CFLAGS) $(INC) subsample.c
state.o : state.c
$(CC) $(CFLAGS) $(INC) state.c
cconv.o : cconv.c
$(CC) $(CFLAGS) $(INC) cconv.c
fbpath.o :fbpath.c
$(CC) $(CFLAGS) $(INC) fbpath.c
stream.o : stream.c
$(CC) $(CFLAGS) $(INC) stream.c
main.o : main.c
$(CC) $(CFLAGS) $(INC) main.c
clean:
rm -rf *o myprogram

Related

Makefile how to use logical OR between prerequisites?

My source files are organized nicely in a folder, that contains subfolders, that also contains source files.
The subfolders don't branch any further.
All object files are just meant to be created and stored in the same folder.
I don't want to manually list the name of the subdirs in the prerequisites when writing the target that generates my object files:
Right now this works:
$(OBJ)/%.o: $(SRC)/%.c
$(CC) -c $< -o $# $(CFLAGS)
$(OBJ)/%.o: $(SRC)/$(subdir1)/%.c
$(CC) -c $< -o $# $(CFLAGS)
$(OBJ)/%.o: $(SRC)/$(subdir2)/%.c
$(CC) -c $< -o $# $(CFLAGS)
...
But I want it to look something like this:
$(OBJ)/%.o: $(SRC)/%.c OR $(SRC)/*/%.c
$(CC) -c $< -o $# $(CFLAGS)
I understand that the title most likely isn't the real question to be asked, but I'm looking for any solution. Also, I know that the * doesn't work as a placeholder here.
First, you can simplify the makefile you have by using vpath:
$(OBJ)/%.o: %.c
$(CC) -c $< -o $# $(CFLAGS)
vpath %.c $(SRC) $(SRC)/$(subdir1) $(SRC)/$(subdir2)
Then, if you really don't want to specify the subdirectories:
vpath %.c $(shell find $(SRC) -type d)

Creating a makefile with different tests

I'm trying to understand if I have create the Makefile right. I have the following files:
Student.h Student.C University.h University.c list.h IDCard.h IDCard.c union.h
Also I have a library mylib which I use the list.h and union.h from.
Furthermore, I have the following hierarchy:
- University
- Student
- list
- IDCard
- union
This means that University imports Student and union and Student import list and IDCard.
The steps I need to follow:
Use the make command to create testing1.exe - release mode without asserts. This file is the runnable of the given testing1.c.
Use make testing2.exe for creating test2.exe - release mode without asserts. This file is the runable of testing2.c.
Use make testing2_debug.exe for creating testing2_debug.exe - debug mode, with asserts. This file is the runable of test2.c.
Use make test for creating test.exe - release mode without asserts. This file is runnable of test.c.
Use make clean to clean so the rebuild will succeed.
The Makefile I wrote looks like:
CC = gcc
OBJS = IDCard.o Student.o University.o
DEBUG_OBJS = IDCard_debug.o Student_debug.o University_debug.o
SOURCE = IDCard.c Student.c University.c
HEADER = IDCard.h Student.h University.h list.h union.h
CFLAGS = -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -L. -mylib
EXEC = testing.exe testing1.exe testing2.exe testing2_debug.exe
testing_O = testing1.o testing2.o testing2_debug.o testing.o
#make testing1.exe
testing1.exe : $(OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
#make testing2.exe
testing2.exe : $(OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
#testing2_debug.exe
testing2_debug.exe : $(DEBUG_OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
#make testing.exe
testing.exe : $(OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
testing1.o : testing1.c Student.h University.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
Student.o : list.h IDCard.h Student.c Student.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
University.o : union.h University.c University.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
IDCard.o : IDCard.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
testing2_debug.o : testing2.c Student.h University.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
Student_debug.o : list.h IDCard.h Student.c Student.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
University_debug.o : union.h University.c University.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
IDCard_debug.o : IDCard.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
clean :
rm -f $(OBJS) $(DEBUG_OBJS) $(EXEC) $(testing_O)
I'm a bit new to creating Makefiles so I'm try to make as few mistakes as possible. Does my Makefile do what I need? Can it be simplified? Does it follow the conventions?
$*.o shouldn't be a dependency. $(OBJS) already covers that.
As a general rule, you can avoid targets for individual object files.
Here's an example target that may need modification to suit your needs:
%.o: %.c %.h
<tab>$(CC) -DNDEBUG -c $(CFLAGS) -o $# $<
%_debug.o: %.c %.h
<tab>$(CC) -c -g $(CFLAGS) -o $# $<
This requires the header file to have the same base name as the source file.
Another option that may work is listing off the header file dependencies of each object file and then doing the matching:
testing1.o: Student.h University.h
Student.o: list.h IDCard.h Student.h
University.o: union.h University.h
IDCard.o: IDCard.h
testing2_debug.o: Student.h University.h
Student_debug.o: list.h IDCard.h Student.h
University_debug.o: union.h University.h
IDCard_debug.o: IDCard.h
%.o: %.c
<tab>$(CC) -DNDEBUG -c $(CFLAGS) -o $# $<
%_debug.o: %.c
<tab>$(CC) -c -g $(CFLAGS) -o $# $<
A similar rule can be followed for .exe files:
%.exe: $(OBJS)
<tab>$(CC) -DNDEBUG $(CFLAGS) $^ -o $# -L. -lmylib
%_debug.exe: $(DEBUG_OBJS)
<tab>$(CC) -g $(CFLAGS) $^ -o $# -L. -lmylib
Also, make sure to replace <tab> in these examples with hard tabs for your Makefile to be valid.
IDCard.o : IDCard.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
but .h files aren't compiled
As a general style form list .c dependencies before .h dependencies.
EDIT: Community Wiki. If it weren't for the clarifying comment by OP I would now delete this post.

Makefile not compiling all C files in directory

Iam working with gcc and MinGW on a Windows platform. I have a directory containing two *.c files:
main.c and funcs.c
I am using the following makefile:
CC=gcc
CFLAGS=-c
LDFLAGS=
SOURCEDIR = src
BUILDDIR = build
SOURCES=$(wildcard $(SOURCEDIR)/*.c)
OBJECTS=$(patsubst $(SOURCEDIR)/%.c,$(BUILDDIR)/%.o,$(SOURCES))
LIBRARIES=-L/mingw64/lib
INC= -I./include
EXECUTABLE=testLink
VPATH = src include build
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) $(LIBRARIES) -o ./dist/$#
$(OBJECTS): $(SOURCES)
$(CC) $(INC) $(CFLAGS) $< -o $#
Which should take the *.c files and generate *.o files with the same name. However I get the following output on make -
$ make
gcc -I./include -c src/funcs.c -o build/funcs.o
gcc -I./include -c src/funcs.c -o build/main.o
gcc build/funcs.o build/main.o -L/mingw64/lib -o ./dist/testLink
followed of course by a bunch of multiple definition errors. As you can see from the first two lines it is taking the same *.c file and compiling it twice into two different *.o files.
I am new to makefiles but I assume it is something wrong with my $(OBJECTS) rule and I'm pretty sure it's the $< which is causing the problem. I'm trying to create a generic makefile which will always work on my projects which have the same directory structure and take .c files turn them into .o files and link. Am I going about this entirely the wrong way or is there a simple fix to my makefile?
Thanks!
James
This rule:
$(OBJECTS): $(SOURCES)
$(CC) $(INC) $(CFLAGS) $< -o $#
expands to:
funcs.o main.c: funcs.c main.c
$(CC) $(INC) $(CFLAGS) $< -o $#
which is equivalent to:
funcs.o: funcs.c main.c
$(CC) $(INC) $(CFLAGS) $< -o $#
main.o: funcs.c main.c
$(CC) $(INC) $(CFLAGS) $< -o $#
$< refers to the first dependency (funcs.c) so your Makefile is trying to generate both funcs.o and main.o from the same source.
You just want a generic rule using % wildcard matching:
%.o: %.c
$(CC) $(INC) $(CFLAGS) $< -o $#
See https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html
Jeff pointed the mistake in his answer (all objects depend on all sources: that isn't a generic compilation rule for c sources).
However, the generic rule must have source & object paths. To sum it up, just replace
$(OBJECTS): $(SOURCES)
$(CC) $(INC) $(CFLAGS) $< -o $#
by
$(BUILDDIR)/%.o : $(SOURCEDIR)/%.c
$(CC) $(INC) $(CFLAGS) $< -o $#
(as explained in How to generate a Makefile with source in sub-directories using just one makefile)
note that this kind of dependency test doesn't take included .h files into account, so it's only intended for first builds. Modifying .h files afterwards doesn't trigger a compilation since the header files are not listed as dependencies.

Set Option in MakeFile to send object files to specific Folder

I made a test makefile using an online tutorial. It works, but I also want to have all of my .o files go to a specific sub-folder. Is there a way to do this using a makefile? Here is what I have so far.
CC=gcc # specifies the compiler to use.
CFLAGS=-I. # specifies to look in the current directory.
DEPS = path_tools.h # DEPS stores each .h file to be added.
OBJ = checkpath.o path_tools.o # OBJ stores each object file to compile.
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
checkpath.exe: $(OBJ)
gcc -o $# $^ $(CFLAGS)
For GNU make you can use this Makefile.
ODIR:=obj
CC:=gcc
CFLAGS:=-I.
DEPS:=path_tools.h
OBJ_:= checkpath.o path_tools.o
OBJ:=$(addprefix $(ODIR)/, $(OBJ_))
PROG=checkpath.exe
all:$(PROG)
$(OBJ): $(DEPS)
$(ODIR)/%.o: %.c
$(CC) -c -o $# $&lt $(CFLAGS)
$(PROG): $(OBJ)
$(CC) -o $# $^ $(CFLAGS)
clean:
rm -f $(OBJ) $(PROG)
You can pass the path of your folder to makefile to create and put the results in.
To pass parameter to makefile:
make DPATH=your-path
To use in makefile:
$(DPATH)
Create this path and add it to head of your *.o files as a path.

Using a Makefile to store object files in two different directories? [C]

I need to modify the Makefile I have to store only the object file associated with "record.c" into the bin folder. Here is what my directory structure looks like before executing Make.
bin/
include/
-hash_table.h
-history.h
-parser.h
-record.h
-shell.h
-variables.h
lib/
obj/
src/
-hash_table.c
-history.c
-parser.c
-record.c
-shutil.c
-sshell.c
-variables.c
...and here is the Makefile:
# Beginning of Makefile
SRC = src/shutil.c src/parser.c src/sshell.c src/history.c src/hash_table.c src/variables.c src/record.c
OBJS = obj/shutil.o obj/parser.o obj/sshell.o obj/history.o obj/hash_table.o obj/variables.o bin/record.o //<----
HEADER_FILES = include/shell.h include/parser.h include/history.h include/hash_table.h include/variables.h include/record.h
EXECUTABLE = sshell
LIBS = lib/libshell.so lib/libparser.so lib/libhistory.so lib/libhash_table.so lib/libvariables.so lib/librecord.so
LIBCFLAGS = $(CFLAGS) -D_REENTRANT -fPIC
CFLAGS = -Wall
CC = gcc
# End of configuration options
#What needs to be built to make all files and dependencies
all: $(EXECUTABLE)
#Create the main executable
$(EXECUTABLE): $(OBJS) $(LIBS)
$(CC) -o $(EXECUTABLE) obj/sshell.o -Llib -lparser -lshell -lhistory -lhash_table -lvariables -lrecord
#Create the library files
lib/libparser.so: obj/parser.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libshell.so: obj/shutil.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libhistory.so: obj/history.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libhash_table.so: obj/hash_table.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/libvariables.so: obj/variables.o
$(CC) $(LIBFLAGS) -shared $^ -o $#
lib/librecord.so: bin/record.o //<----
$(CC) $(LIBFLAGS) -shared $^ -o $#
#Recursively build object files
obj/%.o: src/%.c //<---- I feel like this is causing the problem.
$(CC) $(CFLAGS) -I./include/ -c $< -o $#
#Define dependencies for objects based on header files
#We are overly conservative here, parser.o should depend on parser.h only
$(OBJS) : $(HEADER_FILES)
clean:
-rm -f $(EXECUTABLE) obj/*.o lib/*.so lib/*.a bin/*.o
-rm -f .sshell_history.txt
run: $(EXECUTABLE)
(export LD_LIBRARY_PATH=lib; ./$(EXECUTABLE))
# End of Makefile
With what I have done (most likely completely off) it doesn't compile record.c and says bin/record.o does not exist. I am not really experienced with Makefiles so I am wondering if I can have some help. Thanks!
Try using the rule .c.o instead of obj/%.o: src/%.c
Edit:
If that doesn't work, maybe adding the following rule will do the job:
bin/%.o: src/%.c
$(CC) $(CFLAGS) -I./include/ -c $< -o $#

Resources