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
ormake --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 asautomake
orCMake
. I personally preferautomake
because it is more mature (and doesn't do stupid things like try to put semicolon-separated lists on a command line).
精彩评论