0

I am wondering how to create a Makefile to compile hello.c:

// for example

int main(int argc, char *argv[]) {
    puts("Hello world");
    return 0;
}

I am aware that I compile the program by the help off gcc hello.c -o hello and how I run it but that is as much as i know at the moment.

closed as unclear what you're asking by l0b0, Gilles, Ramesh, slm, Anthon May 31 '14 at 17:54

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I don't understand what Bash has to do with it. Other than that, what have you tried? – l0b0 May 31 '14 at 13:16
  • 2
    It's also unclear what "converting from sudo" means. Sudo is an utility that allows you to run things as another user(as root for instance). Here is a very basic Makefile tutorial. – Leiaz May 31 '14 at 13:40
  • 1
    You need to learn (1) how Makefiles are written (their "language": syntax and semantics), and (2) how to create a file and write something to it when you are using bash. Which question do you want to be answered? As for (1), look into the manual for make (with info make). As for (2), the answer will be the same -- no matter whether you want to create a "Makefile" or some other kind of a plain text file. If your question is (2), please make it more clear by making the question more general and mentioning Makefile only as an example. Otherwise it's confusing for us: (1) or (2)? – imz -- Ivan Zakharyaschev May 31 '14 at 13:54
  • Please restate your question in a more sensible way: You converted from "sudo"? sudo is a shell command to get privileged access. I suggest you take your time stating your question more carefully! – polemon May 31 '14 at 14:41
  • I've edited out references to bash and sudo since they do not really have much of anything to do with the question. – goldilocks May 31 '14 at 15:06
2

GNU make has a very substantial online manual, and while IMO it is aggravating and obtuse at many points, it does make a decent reference. As others have said, just look around for a tutorial that works for you, and consult the manual along with that so you get used how it is organized, etc.

A basic (GNU make) makefile for building hello.c might look like:

CFLAGS += -Wall -g -O0
PROGS = hello

.PHONY: clean

%: %.c
    $(CC) $(CFLAGS) $< -o $@

clean:
    -rm $(PROGS)

$(CC) is a built-in variable; if you don't redefine it, the default is cc, which on a GNU system will be a symlink to gcc. % indicates a pattern rule; in this case it will match anything, although if there is no anything.c in the directory the recipe will fail. $< and $@ are automatic variables. So if you now run:

make hello

Make will execute:

cc -Wall -g -O0 hello.c -o hello

Using += with `$(CFLAGS) allows you to do stuff like this:

CFLAGS="--std=c99" make hello   

So that -Wall -g -O0 will be appended to --std=c99, separated by a space. Note that if you use make CFLAGS="--std=c99" hello, that value will replace any definition in the makefile.

Rules have three basic parts, the targets, the prerequisites, and the recipe (see here). The rule will run if:

  • The target file does not exist.
  • The target file is older than one of the prerequisites.

.PHONY targets will run no matter what. So running make clean with the above make file will execute:

rm hello

In this case $(PROGS) is not used anywhere else, although in a more complex project make file it might be used as a prerequisite for something else. E.g., if you add this rule to the top (after the variable declarations):

all: $(PROGS)

And append all to the .PHONY: list, you can now just enter make and everything in the $(PROGS) list will be built using the %: %.c rule, since this is a prerequisite to make all, and all is the first rule in the file -- used by default if you don't specify one (i.e., you can still use make hello to build just the "hello" program).

1

To create an appropriate Makefile, one needs these two things:

  • Macros
  • Rules

Macros are what we use in Makefiles to shorten the syntax and make it easier to edit the file if something has changed. For example:

C = gcc # sets the macro for the C compiler to C

And so $(C) can be substituted for gcc

Rules are what are used for checking the changes of files and their dependencies. There must always be an all rule so that when make is run, it checks the all rule first. Just like your C program, where the main() function is executed first.

Example Makefile:

C = gcc
CFLAGS = -o
INPUT = hello
OUT = $(INPUT)

all: $(INPUT)

$(OUT): $(INPUT).c
        $(C) $(INPUT).cpp $(CFLAGS) $(OUT)

A rule can be declared by giving its name + a semicolon (e.g. do_this:), adding any dependant files or rules after it (e.g. another_rule $(DEPENDANDTFILE)) and then adding commands on the next line after a TAB.

NOTE: Rules will not work unless there is a TAB at the beggining of the statement's line.

  • Using $(OUT) as an exact duplicate of $(INPUT) seems pointless and confusing. Also the suffix should really be .c, to match the question and the value of $(c). – goldilocks May 31 '14 at 14:24
  • To me it would seem a little confusing to use $(INPUT) for the name of the rule, so I created another macro $(OUT) to take away my confusion. Whether or not you find using $(OUT) confusing seems to depend on the person. What would you suggest that I use as a name? Ah, yes. The .cpp, I was just using C++ and completely didn't realise that it was C we were using! My bad! :) – user133987 May 31 '14 at 14:47
  • There is a lot of leeway WRT to style and preference in makefiles. If you are used to using "input" and "output" semantics, fair enough, but it seems simpler here if you just replace both of them with, e.g. PROGRAMS, since they the same. Also, using them in the recipe line is a bad idea (think what will happen if you add another item to that list). You should als edit the recipe now, since it refers to a .cpp file but the prerequisite is a .c. – goldilocks May 31 '14 at 15:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.