开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜