7

Forgive me if I posted this in the wrong Stack. Every time I run make for a file without any Makefiles in the directory, make still works and compiles the source code but only with the arguments: gcc filename.c -o filename

For example, if I enter make test with test.c in the directory, it does : gcc test.c -o test

I wish to change this, so that ever time I run make without a Makefile, it will instead do : gcc -ggdb -std=c99 -Wall -Werror -o filename filename.c -lcs50 -lm

I also which that this change becomes permanent and does not change regardless if I restart or change directories.

I'm currently running Crunchbang Weezy on an AMD 64bit processor.

Anfernee
  • 195
  • 1
  • 2
  • 11

4 Answers4

4

You want the CFLAGS environment variable.

For example:

$ export CFLAGS='-ggdb3'
$ make test
cc -ggdb3    test.c   -o test
X Tian
  • 10,413
  • 2
  • 33
  • 48
phemmer
  • 70,657
  • 19
  • 188
  • 223
  • Actually the default recipe used to compile a C source file actually says `$(CC) -c $(CFLAGS) $(CPPFLAGS)`. You can set any of those environment variables as you like. – X Tian Mar 22 '14 at 07:55
  • you say the default has a `-c` in it, yet when I ran it there was no `-c`. – phemmer Mar 22 '14 at 15:05
  • It works. However can I use this to change the compiler to clang instead of gcc? – Anfernee Mar 22 '14 at 17:19
  • 1
    @AJPennster yes. `export CC=clang`. Though with this much customization, I suggest using a `Makefile`. – phemmer Mar 22 '14 at 17:44
  • One more issue. When I compile somewhere else, it changes back to `cc test.c test` How can I make this permanent? I want to be able to always do these things so I don't have to specify the gdb flag when I want to do debugging, even on small projects. – Anfernee Mar 22 '14 at 17:47
  • @AJPennster if you want it global, you put it in your `.bashrc` or `.profile`, or whatever your shell uses. – phemmer Mar 22 '14 at 17:49
  • I'm not sure what my shell uses. You know a command I can use to check? – Anfernee Mar 22 '14 at 17:52
  • @AJPennster - `echo $SHELL` – slm Mar 22 '14 at 18:12
  • @Patrick Ooops ! typo sorry no -c – X Tian Mar 22 '14 at 18:26
  • I got it! It works and its permanent. Thanks a lot everyone! Patrick gets correct answer. Thanks Patrick. – Anfernee Mar 22 '14 at 18:47
  • One more question @Patrick. I tried to compile with make, however I'm getting issues with the libraries. I think its because when I use make, the libraries are specified before the source file. like Clang -lcs50 test.c -o test. How can I fix that by editing the .bashrc so it is permanent? – Anfernee Mar 23 '14 at 02:13
3

Generally when you type make test if you're missing a Makefile the make tool will attempt to use a vanilla compile command.

Example

Say we have the following test.c:

$ cat test.c 
#include <stdio.h>
int main()
{
    printf( "I am alive!  Beware.\n" );
    return 0;
}

Without a Makefile when we run make test we'd get the following behavior:

$ make test
cc     test.c   -o test

NOTE: Subsequent runs would result in:

$ make test
make: `test' is up to date.

A test run:

$ ./test 
I am alive!  Beware.

If you're typing make test you must have a Makefile somewhere. When I run that command in a directory that doesn't have a Makefile I get the following:

$ make test
make: *** No rule to make target `test'.  Stop.

Using CFLAGS

If you want to override make's default command line options you can do something like this:

$ export CFLAGS="-ggdb -std=c99 -Wall -Werror -lcs50 -lm"

Now when we run make:

$ make test
cc -ggdb -std=c99 -Wall -Werror -lcs50 -lm    test.c   -o test

References

slm
  • 363,520
  • 117
  • 767
  • 871
  • Actually `make test` does not require a makefile if you have a file called `test.c`. – phemmer Mar 22 '14 at 03:21
  • @Patrick - thanks never knew this. Updated. – slm Mar 22 '14 at 04:23
  • How can I make these flags permanent though? – Anfernee Mar 22 '14 at 17:35
  • @AJPennster - add them to your `~/.bashrc` file if you're using Bash as your shell. Simply add this line to the end of that file: `export CFLAGS="-ggdb -std=c99 -Wall -Werror -lcs50 -lm"`. To confirm your shell, `echo $SHELL`. – slm Mar 22 '14 at 18:09
1

[Edit]

From the GNU make man page:

If no -f option is present, make will look for the makefiles GNUmakefile, makefile, and Makefile, in that order.

Passing arguments are only possible if you have a variable for example CFLAGS defined in your Makefile:

CC=gcc
CFLAGS=-g -O -Wall -Werror

all: foo

foo: foo.o
    $(CC) $(CFLAGS) $<

Here you are able to override the variable with

$ make CFLAGS="-ggdb -std=c99 -Wall -Werror"
gcc -ggdb -std=c99 -Wall -Werror   -c -o foo.o foo.c
gcc -ggdb -std=c99 -Wall -Werror foo.o

However, it is easier to edit the Makefile.

  • For project specific build flags I think you should definitely set them in Makefile. – ek9 Mar 22 '14 at 13:07
  • Sure, and even if you have a makefile, passing arguments to it is usual. –  Mar 22 '14 at 15:30
  • @edvinas.me - I don't think any of these answers were implying that you shouldn't use a Makefile. That's the prescribed way to accomplish this, the OP was merely asking where the defaults are coming from and we're showing how. – slm Mar 22 '14 at 18:10
0

That depends on the exact make(1) you have got, and the makefile being used.

For example, GNU make helpfully assumes a set of default rules and macros. I.e., the macro CC gives the name of the C compiler, CXX the C++ one; CFLAGS are flags for CC and CXXFLAGS for CXX.

It also defines a slew of default rules, i.e., to create a foo.o from foo.c by calling $(CC) $(CFLAGS) -c foo.c, and create an executable foo from foo.o by doing $(CC) $(CFLAGS) -o foo foo.o. Again, other versions of make might define other default macros and rules (but CC and CFLAGS seem to be universal).

If there is no makefile, GNU make uses the above rules, and you can override the macros by e.g. creating tst from tst.c with:

make CC=clang CFLAGS='-O2 -g -Wall' tst

Off the top of my head I don't know how other makes react, I seem to remember others just error out when there is no makefile.

If there is a makefile (could be called a few different names, check the manual; at least makefile and Makefile) the macro definitions and rules it defines take over. Most makefiles don't, so you'd get away with the above command. But there are no guarantees. Check for any instructions in files called typically INSTALL, README or some variation, or in the makefile itself.

And finally, there are a few alternatives to make (their default control files are mostly called some variation on makefile), but as make(1) is almost universal, their use should be documented somewhere.

vonbrand
  • 18,156
  • 2
  • 37
  • 59