Makefile: ...is up to date - c

I have made a makefile for some c files. I have seen too many ways on the internet but i had always the same problem: make: `q_a' is up to date.
q_a:
gcc -o q_a quick_sort_i.c
q_g:
gcc -o q_g quick_sort_g.c
s_a:
gcc -o s_a shell_sort_i.c
s_g:
gcc -o s_g shell_sort_g.c
fork:
gcc -o fork fork.c
I have not files with the same name in my folder and I can compile them when I write in terminal. Can you help? Thanks in advance!

You have not specified dependencies for your targets.
What make does, is first checking if your target (q_a) exists as a file, and if it does, if its dependencies are newer (as in, have more recent modification time) as your target. Only if it needs to be updated (it does not exist or dependencies are newer) the rule is executed.
That means, if you need q_a to be recompiled every time quick_sort_i.c is changed, you need to add it as a dependency to q_a, like this:
q_a: quick_sort_i.c
gcc -o q_a quick_sort_i.c
With that, make will recompile q_a if necessary.

Related

Why gcc compiler giving the complied file a new name?

I have reinstalled mingw in my system and downloaded the gcc compiler.
I was shocked after compiling the first file which was "subject.c" but the name of the compiled file which gcc returned was "a.exe". It should be "subject.exe" but do not know why this happened.
Can anyone please explain the reason behind this ?
expected:
gcc subject.c
ls
subject.c subject.exe
tried:
gcc subject.c
ls
subject.c a.exe
-o can be used to give the name of the output file.
For example,
gcc -Wall -Wextra -pedantic subject.c -o subject.exe
(Do enable your compiler's warnings!)
gcc names its output files, in the absence of other instructions, a.out or a.exe depending on system environment because that is what it's supposed to do.
To override this default behavior, you can use the -o flag which tells gcc that the next argument is the desired name for the output file. For instance:
gcc -o subject.exe subject.c
There is no automatic functionality built into gcc to strip a source file of its file extension and add .exe to the end but this can be done manually with Makefiles or other similar scripts, for instance you can write a Makefile with the following contents:
%.exe: %.c
gcc -o $# $<
Then a command like make subject.exe would be translated to gcc -o subject.exe subject.c, which may be what you're looking for.
There is functionality built into gcc to strip source files of their extensions during different parts of the compilation process, which may have been what confused you. For instance a call like gcc -c subject.c can be expected to produce an object file called subject.o, likewise gcc -S subject.c can be expected to produce an assembly language file called subject.s, however this does not apply to executable files not only for historical reasons, but because programs can be compiled from multiple source files and there is not always a clear way to choose a name for the executable output.

Makefile order, doesn't compile everything

I have a makefile with this simple rules,
ref_approx_bs2_rsq_5_10_1ulp_arch1 : ref_approx_bs2_rsq_5_10_1ulp_arch1.o
gcc -I../CModels -L../CModels -std=c99 -o ref_approx_bs2_rsq_5_10_1ulp_arch1 ref_approx_bs2_rsq_5_10_1ulp_arch1.o -lm -limg_float
ref_approx_bs2_rsq_5_10_1ulp_arch1.o : ref_approx_rsq.c ../CModels/cogen_fp_bs2_rsq_5_10_1ulp_arch1.cpp ../CModels/cogen_fp_bs2_rsq_5_10_1ulp_arch1.h ../CModels/img_float.h ../CModels/img_float.c
gcc -DCMODELLOC=\"../CModels/cogen_fp_bs2_rsq_5_10_1ulp_arch1.cpp\" -DCMODEL_NAME=cogen_fp_bs2_rsq_5_10_1ulp_arch1 -std=c99 -o ref_approx_bs2_rsq_5_10_1ulp_arch1.o -c ref_approx_rsq.c
libimg_float.a : ../CModels/img_float.o
ar -rcs ../CModels/libimg_float.a ../CModels/img_float.o
img_float.o : ../CModels/img_float.h ../CModels/img_float.c
gcc -I ../CModels/ -o ../CModels/img_float.o -c ../CModels/img_float.c
But basically if I modify img_float.c and try to use the make file again it doesn't compile and create libimg_float.a.
The makefile itself looks correct to me since I've written all the prerequisites.
Any suggestion?
It won't recompile libimg_float.a because nothing depends on it.
Make doesn't go through your makefile and always try to rebuild every target. Make works by finding the first (explicit) target listed and trying to build that. Before building the first target, it will try to build all the prerequisites of that target, and before that it will try to build all the prerequisites of those targets, etc. until no more prerequisites are found.
If there is a target which is not a prerequisite of the first target (or its prerequisites, etc.) then it will not be built, by default. You can request that it be built by listing it on the command line: make libimg_float.a will tell make to build that target, instead of the first explicit target. Of course you can list lots of targets on the command line.
But generally people create one target first, commonly called all, which lists all the targets that should be built by default as a prerequisite.
Here, though, your makefile is not right because your ref_approx_bs2_rsq_5_10_1ulp_arch1 target does use libimg_float.a, but it's not listed as a prerequisite. That means it won't be updated when libimg_float.a is out of date. You should change your makefile to show that prerequisite relationship:
ref_approx_bs2_rsq_5_10_1ulp_arch1 : ref_approx_bs2_rsq_5_10_1ulp_arch1.o libimg_float.a

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.

What is an efficient workflow with C? - Makefile + bash script

I'm working on one of my first projects that will span more than one C file. For my first couple practice programs, I just wrote my code in main.c and compiled using gcc main.c -o main. This worked for me as I was learning.
Now, I'm working on a much bigger project on my own. I want to continue doing compilation on my own (or at least setting it up manually) so I can understand the process. After reading a bit, I decided to make a Makefile.
Note: I'm also using GTK+, so I had to look up how to add that into the compile command.
This is what it looks like after a bit of research:
main:
gcc -Wall -g main.c -o main `pkg-config --cflags --libs gtk+-2.0`
At first, I was just running "make". Then I was having some problems getting the error "main is up to date" even though I had changed the file.
So I wrote a script:
#!/bin/bash
rm main
make
./main
So I make changes, and then I run this script.
Is this a good/normal system? I want to have scalable system, since my project will grow. I assume I can keep that script and just add dependencies to the makefile and change the main compile command in the makefile. Am I correct?
Thanks in advance.
EDIT:
Thanks for the feedback about how to fix my Makefile.
So is the typical compilation process 1) type make then 2) ./main regardless of how the project is setup or its size (assuming you've written a proper makefile)?
You need to tell make that main depends on main.c. That way every time you make changes to main.c and then run make, main is regenerated. To delete main you can have a phony target called clean as:
main:main.c
gcc -Wall -g main.c -o main `pkg-config --cflags --libs gtk+-2.0`
.PHONY: clean
clean:
rm -f main
Now to delete main you can do : make clean
If you get make: main is up to date. It means you've not modified main.c and hence there is not need for regenerating main. But if you have to force regenerating main even when the dependencies have not been updated you can also use the -B option of make as suggested by Sjoerd in other answer.
Use make -B or make --always-make to compile even though the target is up to date
Append filenames after the colon to check whether these are updated.
Example:
a: a.c
gcc -o a a.c
a would only be built if a.c is newer than a.
I find command-line make to be quite sufficient for my needs, but writing Makefiles by hand becomes quite a chore. As your project grows in complexity, you'll find managing the dependencies by hand to become more and more annoying. What I suggest you do is learn how to do at least one of the following:
Write a dependency-tracking Makefile by calling e.g., gcc -M.
Learn to use a Makefile generator such as automake or CMake. I personally prefer automake because it is more mature (and doesn't do stupid things like try to put semicolon-separated lists on a command line).

Compile multiple C files with make

(I am running Linux Ubuntu 9.10, so the extension for an executable is executablefile.out) I am just getting into modular programming (programming with multiple files) in C and I want to know how to compile multiple files in a single makefile. For example, what would be the makefile to compile these files: main.c, dbAdapter.c, dbAdapter.h? (By the way, If you haven't figured it out yet, the main function is in main.c) Also could someone post a link to the documentation of a makefile?
The links posted are all good. For you particular case you can try this. Essentially all Makefiles follow this pattern. Everything else is shortcuts and macros.
program: main.o dbAdapter.o
gcc -o program main.o dbAdapter.o
main.o: main.c dbAdapter.h
gcc -c main.c
dbAdapter.o dbAdapter.c dbAdapter.h
gcc -c dbAdapter.c
The key thing here is that the Makefile looks at rules sequentially and builds as certain items are needed.
It will first look at program and see that to build program, it needs something called main.o and dbAdapter.o.
It will then find main.o. However, to build main.o, it will need main.c and dbAdapter.h (I assume dbAdapter.h is included in main.c).
It will use those sources to build main.o by compiling it using gcc. The -c indicates the we only want to compile.
It does the same thing with dbAdapter.o. When it has those two object files, it is ready to link them. It uses the gcc compiler for this step as well. The -o indicates that we are creating a file called program.
GNU make should be what you're looking for.

Resources