The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.
The make command uses information from a description file, which you create, to build a file containing the completed program, which is then called a target file. The internal rules for the make command are located in a file that looks like a description file.
The answers above are all mostly correct. However, the details are a bit misleading. For example, there's no need to add an extra job for a "managing thread" (note: make
is not actually multithreaded). make
never counts itself as a job for the purposes of -j
, so, as Huygens says above, if you say -j5
you'll get 5 compile jobs running, not 4 plus make.
The reason most people use [number of cores] + [some padding] has nothing to do with make
or what it needs, but rather with the nature of the compiler. A compiler is really just a very complicated text translation tool: it reads in text in one form and converts it to "text" (binary) in another form. A lot of this (especially as your language gets more complex, like C++), requires a lot of CPU. But it also requires a lot of disk I/O. Disk I/O is slow, so while one compiler is waiting for some data from the disk, the kernel schedules other jobs to run. That is why you can usefully have more than the number of cores compiles running at the same time.
Exactly how large you can get -j
before you start seeing diminishing returns (your builds actually start going slower, at some point, with more -j
) depends completely on your hardware, the kinds of builds you're doing, etc. The only way to know for sure is experimentation.
However, [number of cores]+[a few] is typically a good approximation.
As you say the -j
flag tells make that it is allowed to spawn the provided amount of 'threads'. Ideally each thread is executed on its own core/CPU, so your multi-core/CPU environment is used to its fullest.
make
itself does not compile the source files. This is done by a compiler (gcc). The Makefile (input for make
) contains a set of targets. Each target has a set of dependencies (on other targets) and rules how to build the target. make
reads the Makefile(s) and manages all targets, dependencies and build rules. Besides compiling source files you can use make
to perform any task that can be described by shell commands.
If you set the allowed number of threads too high, it is not possible to schedule each thread on its own core. Additional scheduling (context) switches are required to let all threads execute. This additional resource usage obviously result in lower performance.
There are multiple rules-of-thumb, but I guess that setting to total amount to <number of cores> + 1
is the most common. The idea behind this is that all cores have their own thread and there is one additional managing thread that handles the targets and which is next to be build.
One CPU per thread plus one manager/loader. Since a thread that does disk operations is technically almost idle from CPU point of view, add one to the total number of cores.
If the CPU is using hyperthreading, you can safely count each core as two cores and double the number of threads, so a quad core Intel Core i7 should get -j9 (eight virtual cores plus manager.) On a quad core AMD use -j5
The -j
option is only use to speed up application build, it determines how many jobs make
can spawn for the build. You can either set -j<nb core>
or even higher -j<nb-core * 1.5>
so that compilation can happen in parallel.
It has no impact on the compiled code.
For a 4 core system, you could try make -j6
. If make can run parallel builds, it will launch up to 6 simultaneous compilation process (e.g. 6 calls to gcc).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With