Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make file for larger directory structure

I've got several directories with subdirectories containing c or asm files and I want them all compiled/assembled and then linked. I'm not especially picky where the object files go (e.g. a special bin folder or in the src folder) as long as a make clean removes them all.

The structure would look something like this:

/src
    /dir1
        /dir1_1
            +file1_1.s
            +file1_2.s
        +file1.s
    /dir2
        +file2.c

I'm sure there's some easy way to create a makefile that compiles all files without me having to specify where it should look (compiling all files in one directory is doable with wildcards, but what then?).

like image 665
Voo Avatar asked Feb 20 '11 02:02

Voo


People also ask

What does $() mean in makefile?

The $@ and $< are called automatic variables. The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.

How can I get PWD in makefile?

You can use shell function: current_dir = $(shell pwd) . Or shell in combination with notdir , if you need not absolute path: current_dir = $(notdir $(shell pwd)) .

How makefiles can be used to manage large C projects?

Makefile is a set of commands (similar to terminal commands) with variable names and targets to create object file and to remove them. In a single make file we can create multiple targets to compile and to remove object, binary files. You can compile your project (program) any number of times by using Makefile.


1 Answers

Do a Google search for 'recursive make considered harmful'. You'll find the original article which postulates that the recursive make procedure is a bad way of doing business, and you'll find some links to other places which debate the validity of the proposition.

Basically, there are two ways to do builds in a directory hierarchy (with make).

  1. Recursive make: each directory contains a makefile which builds in sub-directories and then builds in the current directory.
  2. Non-recursive make: the makefile includes all the dependent makefiles, and builds up the complete dependency structure for the entire project and only builds the requisite software.

I work routinely on a product where the main build sequence is driven by a hybrid system that uses a shell script plus one makefile for each directory. One section of the product is managed by a 'RMCH' makefile; most of it is not. The build script deals with phases of the build, and sequences the directories, and runs make in each directory when it is time to do so. (The source code is in 20k+ files spread over a multitude of directories - it is a big project/product.)

I've also converted a medium-small project (about 20 directories of relevance, and about 400 source files) to work with RMCH (from a script + makefile-per-directory system). It was a bit mind-blowing at first, but works pretty neatly now it is done. Whether I did it correctly is open for debate; it was primarily a learning exercise, though I also did some work modifying the code to work with a modern curses library instead of the archaic BSD library that was used as a part of the code (archaic, as in 1982-vintage - the code was last seriously developed in about 1986) and generally upgrading to modern (standard C) standards. It was also a chance to work with git - so, all in all, quite an extensive learning experience.

If you can wrap your brain around RMCH, it is a good system. If done correctly, with complete and accurate dependency tracking, it removes the guess-work from the build sequence, and it does run fast. However, migrating even a medium size project to it is fairly hard work - it would be a daunting task to do it on the main product I work on, though the system might well benefit from it.

An alternative is to look at other alternatives to make, such as cmake, rake, scons, bras, imake, or ant or whatever else takes your fancy. Most of those are easily discoverable via a Google search; the hard one is bras, which is based on Tcl (as in Tcl/Tk), but is probably largely dead now. And imake is mentioned more for completeness than as a serious suggestion. You might also look at the GNU Autotools. Those do not abandon make; they build atop make.

like image 92
Jonathan Leffler Avatar answered Sep 22 '22 06:09

Jonathan Leffler