12

I want to tell make that it shall always use -j4 option even if I didn't specify it vie command line. Normally i would do this in some configuration file (i.e. ~/.makerc).

Does such file exist for gnu make?

devemouse
  • 5,302
  • 5
  • 22
  • 22

5 Answers5

10

Have a read about the $(MAKEFLAGS) variable:

export MAKEFLAGS=j4

However this will likely interfere with recursive-make-based builds (not that sensible people are using recursive make anyway!), by interfering with GNU make's ability to communicate with its sub-makes.

So the more sensible approach is probably a wrapper script or an alias or shell function.

John Marshall
  • 6,815
  • 1
  • 28
  • 38
3

Well, yes and no --- normally you would use an include file. Put your common configuration items together in a file, say common.mk and add

include common.mk

at the top of your makefile. If the flag doesn't have a matching way to configure it from inside the make file, you can use a function

function mk {
    make -j4 $*
}
Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • as far as that goes, alias make="make -j4". But aliases are so relatively inflexible and shell functions so straightforward that I almost always use functions. – Charlie Martin May 18 '11 at 22:45
  • 3
    How straightforward are they, really? You even have an error in this one: if any of your parameters to mk contain spaces, $* breaks; use "$@" instead. – Fred Nurk May 18 '11 at 22:49
  • 1
    And unquoted $* breaks in another way: it does pathname expansion; e.g. `mk '*'`. These breakages do matter, because while targets will almost never contain spaces, asterisks, brackets, or question marks, variables you pass to make ("make CFLAGS='-g -O2' target") might. – Fred Nurk May 19 '11 at 04:35
0

I would like to expand a bit on the solution hinted in John Marshall's answer.

You can simply put a one-line wrapper script somewhere earlier in the $PATH with the following contents:

#!/bin/bash
$(type -ap make | sed -n 2p) -j4 "$@"

(The script doesn't have to be named make, and that would make it simpler, but I find it convenient if it is.)

I would argue that this is better than the other approaches for the following reasons:

  • Unlike MAKEFLAGS approach, it does not break recursive builds (which are actually quite common in my experience).
  • Unlike include .makerc approach, it can be applied locally without changing any existing makefiles or your workflow in any way.
  • Unlike shell alias or function approach, it is shell-agnostic (doesn't tie you to any particular shell) and works in any additional build scripts that you might have to use, too, as long as you launch them in the same environment.
eush77
  • 3,870
  • 1
  • 23
  • 30
0

I like the MAKEFLAGS approach suggested by John Marshall in lieu of make supporting something like an automatic .makerc project config file. However, I didn't want to have to remember to source a .env or similar environment variables beforehand (and unsetting them afterward).

A solution to this is to put the MAKEFLAGS assignment at the top of the Makefile itself:

#!/usr/bin/env make

MAKEFLAGS=s

.PHONY: foo
foo:
    echo "hello, make"

Run it:

$ make foo
hello, make

Compared to running without the MAKEFLAGS=... line:

$ make foo
echo "hello, make"
hello, make
Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
0

It doesn't exist, but you can do this by having a recursive call into make.

For example:


Makefile:

-include $(HOME)/.makerc

.DEFAULT_GOAL: all

# This will handle a default goal if make is just called without any target
all:
    $(MAKE) $(MAKE_OPTIONS) -f Makefile.real $(MAKECMDGOALS)

# This handles all targets and passes it through
%:
    $(MAKE) $(MAKE_OPTIONS) -f Makefile.real $(MAKECMDGOALS)


$(HOME)/.makerc:

MAKE_OPTIONS := -j4
Mark Trinh
  • 452
  • 2
  • 8
  • 18