Assume the directory of a project contains subdirectories such as src
, bin
, lib
, doc
, etc. Where do I put the makefile of a project?
For example,
some projects put their makefile in src/
subdirectory of the root directories of the projects,
some projects put their makefiles in the root directory of the project.
The second way feels more logically organized to me. Can you provide cases when it is better to put makefile in the root directory, src/
or some other directory for what reasons?
The rest of the question is opinion based, but the last part is much less opinion based:
Can you provide cases when it is better to put makefile in the root directory, src/ or some other directory for what reasons?
First, that directory might not be called src/
but some other ways.
Sometimes the Makefile
is itself generated (e.g. by cmake or autoconf) and its generator requires some specific file tree organization.
A common reason to put all sources in src/
is cross-compilation, or compilation for different styles of targets (perhaps a debug release, and an optimized one). Then you would put all source code in src/
and ensure that make
(and gcc
) don't put object files in that src/
directory, but in some other one (e.g. obj-x86
for X86 object files, obj-arm
for ARM object files, etc...), perhaps specific not only to the ISA but also to the ABI. So you could end up putting object files and executables in a long named directory such asobj-x86_64-linux-optimized
and obj-PowerPC-AIX-debug
. BTW, the src/
directory could even be shared on several machines (e.g. NFS mounted) and read-only (e.g. shareable by several users).
Notice that GCC requires to be built outside of its source tree.
Then, source code has somehow a different meaning for make
(actually, for compilers like GCC) and for developers.
The social definition (used by developers) of source code is: the preferred form of a program on which human developers work (You'll find that definition expressed clearly by free software movements).
For a compiler like GCC or Clang, the source code is simply the translation unit given as input to the compiler (that is .c
and .h
files processed as input by the gcc
compiler). In many (but not all) cases, such C files are genuine source code, because the human developers write them.
In some cases, C or C++ "source" files (as known by gcc
or g++
or clang
or clang++
) are generated (in that case, for developers they are no more source code, but for gcc
they are still an input source). A classical example is of course C files generated by bison. See this mine answer for a general discussion of that idea.
An other example (where C files are in some common directory) is given by domain-specific (or high-level) languages implementations compiled to C (e.g. Bigloo, Chicken Scheme, my old GCC MELT, or even the old C with classes -precursor of C++- in the 1980s).
When such implementations are more or less (or even entirely) bootstrapped, you really want to keep the generated C files together, perhaps in some src/
directory (or some generated/
one). And you could even put these under your version control system (e.g. git), notably for languages having a single implementation (otherwise, you won't be able to build such a compiler; you need the generated C code to build it and later recompile it with itself), and you'll certainly distribute such (generated) C files in a source tarball.
At last, very large projects of thousands of C or C++ -or Ocaml- files (even entirely human written) tend to group these in subdirectories, in particular because a single large directory of many thousands *.c
files is not "readable" by (or friendly to) humans.
On the contrary, for a small project of at most a hundred thousands lines of code in several dozens of C source files with a manually written Makefile
, you'll better put all *.c
& .h
files in the same directory containing that Makefile
.
But having or not some src/
directory, or putting or not the object files produced by the compiler in the same directory containing the source files or the Makefile
, is still largely a matter of taste, opinions, conventions, and habits. I recommend to study the existing practice in free software projects (similar to your project) on github or elsewhere.