5

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?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Tim
  • 1
  • 141
  • 372
  • 590
  • 1
    The root folder seems to me the most natural. And easiest, as paths to file will always be "downside", you'll never have to write "`../XXX`". – kebs Apr 14 '18 at 21:55
  • It is really a matter of opinions (and conventions). In some cases, the `Makefile` is generated (perhaps by `cmake`) in some way that *require* a particular organization of the source tree. It also depends upon the project – Basile Starynkevitch Apr 14 '18 at 21:55
  • @BasileStarynkevitch can you provide cases when it is better to put makefile in `src/` for what reasons? – Tim Apr 14 '18 at 21:58
  • @BasileStarynkevitch "It is really a matter of opinions". Agree, and as such, I wonder if this question should'nt be closed. – kebs Apr 14 '18 at 21:59
  • I voted to close it, since matter of opinion – Basile Starynkevitch Apr 14 '18 at 21:59
  • @Tim: "can you provide cases when it is better to put makefile in src/ for what reasons?" that is a very different question, much less opinion based. You could ask it; but you should search by yourself first for examples. (I need several paragraphs to answer that one, so I won't try in a comment) – Basile Starynkevitch Apr 14 '18 at 22:01
  • Voting to keep open, since the question is about if there's a _convention_, which I'd argue that there is. Convention is to have it in the root of the project. – rtn Apr 15 '18 at 13:39
  • @Tim The `makefile` would be placed in the `src/` directory for convenience. You would go to the `src/` directory and open your editor from there. Since the current-working directory is there, running `make` would not required switching directories. And avoids the need to switch back if you want to edit more files. – shawnhcorey Apr 15 '18 at 14:36
  • Another place the `makefile` might be placed is the `build/` directory. This directory is used for the intermediate files of the make process. So it might seem logical for it to be placed there. – shawnhcorey Apr 15 '18 at 14:38
  • @shawnhcorey https://stackoverflow.com/a/1278209/156458 recommended against placing makefile under `src/`: "Make is good at using a source there to make something here, but not the other way around. " "This will give you a problem with Makefile.depend". So I am confused by your comment and his reply. If you could elaborate here or there, I would appreciate it. – Tim Apr 15 '18 at 14:40
  • @ralphtheninja Thanks. You can now vote to reopen, and I appreciate it. – Tim Apr 15 '18 at 14:41
  • 1
    @ralphtheninja Conventions are still just opinions, so they fall under the POB close reason here on Stack Overflow. At any rate, I narrowed the question's opinion factor quite a bit and voted to reopen the question; Basile's answer provides a great save to a question on the fence. – TylerH Apr 15 '18 at 16:06

1 Answers1

5

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.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547