makefile not finding the .o file - c

I have the strangest problem.
when I run : make tests
in the console I get the following error:
gcc: album_test.o: No such file or directory
sorry for attaching the content as a pic,
the site kept giving me a: "Your post appears to contain code that's not properly formatted
as code"
when I change this line :
album_test.o: ./tests/album_test.c album.h
to be :
album_test.o: album_test.c album.h
and place the album_test.c in the same directory as the makefile
everything compiles!
It's very important that the file will be in a separate tests directory.
any ideas?
Thanks!

You're trying to use make's built-in implicit rules to build your object files. That works when make can find the source file in the current directory, but not otherwise. Update this rule:
album_test.o: ./tests/album_test.c album.h
To include a recipe:
album_test.o: ./tests/album_test.c album.h
$(CC) $(CFLAGS) -c -o $# $<

Related

Makefile, "nothing to be done for all" error

So I have a make file, stored in a directory called "temp" the following directory has a src folder, with 2 .c files "file1.c" and "file2.c". The temp directory also holds a include folder (which is empty), and a bin folder (which is empty until the make command is so posed to be run). I'm currently to trying get a single .c file to compile (get it working),but a single file doesn't even seem to work here.
This is how the directories look:
temp
cd into temp..
bin include Makefile src
Here is my makefile:
all:
gcc -Wall -pedantic -std=c99 src/file1.c -Iinclude -o bin/runMe -lncurses
And yes, there is a tab before the gcc. Any help on this frustrating issue, would be much appreciated. Also, if possible any input on compiling the second .c file, would also be very helpful!
Nothing to be done for TARGET means that a target has no commands which, in this case, almost certainly means that you do not have a tab on that gcc line.
That being said that's only the immediate problem. This makefile is also not following good practices and will unnecessarily recompile your program (as well as ceasing to work entirely should an all file be created).
DrC had, in a currently deleted answer, very good suggestions for how to improve your makefile to avoid both of those latter issues.
Specically, your makefile should look more like this:
.PHONY: all
all: bin/runMe
bin/runMe: src/file1.c
gcc -Wall -pedantic -std=c99 $^ -Iinclude -o $# -lncurses
Which marks the all target as a .PHONY so that an all file or directory getting created won't confuse make as well as setting up a prerequisite on the source file for your built binary so that make can tell when it does (and doesn't) need to rebuild the binary.

How does Redis Makefile include header file prerequisites

I was teaching myself GNU Make and thought a look at the Redis Makefile would teach me a thing or two about the tool.
The rule that compiles the source file to the object file is here:
%.o: %.c .make-prerequisites
$(REDIS_CC) -c $<
Notice that the suffix rule just mentions the C source file (with %.c) as a prerequisite.
But if I add a echo in the middle and run make:
%.o: %.c .make-prerequisites
echo $^
$(REDIS_CC) -c $<
Then the first few lines of the output from make is like below:
cd src && make all
make[1]: Entering directory `/home/cltpadmin/code/redis/src'
echo adlist.c .make-prerequisites adlist.h zmalloc.h
adlist.c .make-prerequisites adlist.h zmalloc.h
CC adlist.o
How did make know that adlist.c depends on adlist.h and zmalloc.h?
The prerequisites in question come from line one of the Makefile.dep included makefile (included on line 134).
The dep target on line 136 generates that file.
This was a fairly common (though entirely avoidable) step for using the compiler to generate the necessary header file includes. This static method also has issues with conditional header includes I believe.
To clarify, the "avoidable" part of this is that it need not be a separate step and a static dependency file at all. See Advanced Auto-Dependency Generation for details about this idea.

Makefile to move .o files to Different Directory

I have source code in one directory and have a makefile in a different directory. I am able to compile the code using the make system's vpath mechanism. The .o files are being created in the same folder where the makefile is. But I want to move those .o files to a different directory called obj. I tried the following:
vpath %.o obj
However, they are still being created in the same folder as the makefile. Can anyone help me to solve this issue?
Here are some highlighted lines of the makefile:
PATH_TO_OBJ:- ../obj
SRC :- .c files
OBJS :- $(SRC:.c = .o)
.c.o = $(CC) $(CFLAGS) -c
exe: cc $(LFLAGS) -o $(PATH_TO_OBJ) $(SRC).
After this also, .o file is creating in same folder of Makefile. Not moving to obj
-o option defines where to save the output file, produced by a gcc compiler.
gcc main.c -c -o path/to/object/files/main.o
Make's VPATH is only for finding source files. The placement of object files is up to the thing that is building them. There's a nice description at http://mad-scientist.net/make/vpath.html (I see someone beat me to posting this in a comment).
The *BSD build systems use variants of make that can place object files (and other generated files, including C sources from lex and yacc variants) in /usr/obj automatically. If you have access to that version of make, that will likely be a good way to deal with whatever underlying problem you are trying to solve.

make: Nothing to be done for `all'

I am going through an eg pgm to create a make file.
http://mrbook.org/tutorials/make/
My folder eg_make_creation contains the following files,
desktop:~/eg_make_creation$ ls
factorial.c functions.h hello hello.c main.c Makefile
Makefile
# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=gcc
# Hwy!, I am comment no.2. I want to say that CFLAGS will be the
#options I'll pass to the compiler
CFLAGS=-c -Wall
all:hello
hello:main.o factorial.o hello.o
$(CC) main.o factorial.o hello.o -o hello
main.o:main.c
$(CC) $(CFLAGS) main.c
factorial.o:factorial.c
$(CC) $(CFLAGS) factorial.c
hello.o:hello.c
$(CC) $(CFLAGS) hello.c
clean:
rm -rf *o hello
error:
desktop:~/eg_make_creation$ make all
make: Nothing to be done for `all'.
Please help me understand to compile this program.
Sometimes "Nothing to be done for all" error can be caused by spaces before command in makefile rule instead of tab. Please ensure that you use tabs instead of spaces inside of your rules.
all:
<\t>$(CC) $(CFLAGS) ...
instead of
all:
$(CC) $(CFLAGS) ...
Please see the GNU make manual for the rule syntax description: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax
Remove the hello file from your folder and try again.
The all target depends on the hello target. The hello target first tries to find the corresponding file in the filesystem. If it finds it and it is up to date with the dependent files—there is nothing to do.
When you just give make, it makes the first rule in your makefile, i.e "all". You have specified that "all" depends on "hello", which depends on main.o, factorial.o and hello.o. So 'make' tries to see if those files are present.
If they are present, 'make' sees if their dependencies, e.g. main.o has a dependency main.c, have changed. If they have changed, make rebuilds them, else skips the rule. Similarly it recursively goes on building the files that have changed and finally runs the top most command, "all" in your case to give you a executable, 'hello' in your case.
If they are not present, make blindly builds everything under the rule.
Coming to your problem, it isn't an error but 'make' is saying that every dependency in your makefile is up to date and it doesn't need to make anything!
Make is behaving correctly. hello already exists and is not older than the .c files, and therefore there is no more work to be done. There are four scenarios in which make will need to (re)build:
If you modify one of your .c files, then it will be newer than hello, and then it will have to rebuild when you run make.
If you delete hello, then it will obviously have to rebuild it
You can force make to rebuild everything with the -B option. make -B all
make clean all will delete hello and require a rebuild. (I suggest you look at #Mat's comment about rm -f *.o hello
I think you missed a tab in 9th line.
The line following all:hello must be a blank tab. Make sure that you have a blank tab in 9th line. It will make the interpreter understand that you want to use default recipe for makefile.
That is not an error; the make command in unix works based on the timestamps. I.e let's say if you have made certain changes to factorial.cpp and compile using make then make shows
the information that only the cc -o factorial.cpp command is executed. Next time if you execute the same command i.e make without making any changes to any file with .cpp extension the compiler says that the output file is up to date. The compiler gives this information until we make certain changes to any file.cpp.
The advantage of the makefile is that it reduces the recompiling time by compiling the only files that are modified and by using the object (.o) files of the unmodified files directly.
Using the comment from Paul R, I found that
make clean
followed by
make
or
make all
fixed my problem.
I arrived at this peculiar, hard-to-debug error through a different route. My trouble ended up being that I was using a pattern rule in a build step when the target and the dependency were located in distinct directories. Something like this:
foo/apple.o: bar/apple.c $(FOODEPS)
%.o: %.c
$(CC) $< -o $#
I had several dependencies set up this way, and was trying to use one pattern recipe for them all. Clearly, a single substitution for "%" isn't going to work here. I made explicit rules for each dependency, and I found myself back among the puppies and unicorns!
foo/apple.o: bar/apple.c $(FOODEPS)
$(CC) $< -o $#
Hope this helps someone!
I was trying to install libuv on Ubuntu and i also got the error make: Nothing to be done for 'all'. As i see it, using make gives two ways to solve the problem, one for check and one for install. But i found a workaround
still use the sudo make check command - it helps to read all the error messages before deciding on further actions. Basically, i've introduced a regression that makes the update workaround inefficient. This error comes from make however, the workaround from install fixes this, just try to run sudo make install and see what happens.
The make command will be a local optimization at the expense of the overall result of check/install - c'est ma façon de parler.
I believe i have narrowed down the problem considerably: in the first case after check i have "FAIL: test/run-tests" and in the second after install i get "specify the full pathname of the library, or use the '-LLIBDIR'" This argument to check/install can be a list object to store information about completed installations.
So install reports partial success when nothing actually happened.
Try running the commands from root:
cd your_program
sh autogen.sh
./configure
make
make check
make install
And then he writes that the installation was successful:
Libraries have been installed in:
/usr/local/lib
In your case, I strongly feel the only and simple problem you had is that you only preprocessed your app. You did so by having the flag -c under CFLAGS.

Is it possible to match sets in a make file?

I have a make file that uses pattern matching to automate compilation using a rule like this:
%.o : %.c
gcc -c $<
However in this project I have a number of source files which differ in case of their extension. Is there a way to match sets in make files like in regular expressions.
Pseudo-example:
%.o : %.[cC]
gcc -c $<
It is not possible to simply change the case of the source files as this is used for module testing of an existing project which mixes modules from several other.
I found the solution. It turns out that the makefile had several issues.
First the example I posted actually works as Banthar pointed out. However my problem was that my sourcefiles weren't in the root directory but in a src/ subdirectory which I had added to vpath. I honestly thought it was irrelevant to my question as I believed make would automatically scan its vpath for source files. Turns out vpath does not apply to rule checking.
To make it work do:
vpath = %.c src
vpath = %.C src
%o : src/%.[Cc]
gcc -c $<
Next as I was working through examples of how to get it done make would sometimes build sourcefiles behind my back. If you do:
all : main.o
gcc -o test main.o
... and not have rule to build the .o file make will build it using implicit inbuild rules. Quite confusing. It can be disabled using the -r flag.
make -r all
Third compiling .C files using gcc without any extra options will result in linker errors because gcc interprets .C files as C++ files as default. In order to compiles as C files use -x flag.
%.o : %.C
gcc -x c -c %<
Hope this helps someone.
The easiest option I can see is simply to link non-matching cases:
%.c : %.C
ln $< $#
and let rule chaining do the rest.

Resources