XNor
XNor

Reputation: 658

Makefiles and large projects with complex interdependencies

I am trying to come up with a build system for a large project that has a structure like this:

├── deploy
├── docs
├── libs
│   ├── lib1
│   └── lib2
├── scripts
└── tools
    ├── prog1
    └── prog2

My problem is that libs and programs may depend on each other in an order that may change very often. I have looked up info on the internet and I get mixed messages. Some people say that I should just use makefiles and some other say that recursive makefiles are evil.

Besides that, I don't know how to manage dependencies with makefiles (if lib2 needs lib1 to build, how to tell make to build lib1 first). Someone told me that it is easily achievable using the variable VPATH but I have read the documentation and I think it has nothing to do with this.

So my questions are:

Upvotes: 1

Views: 1731

Answers (2)

bobbogo
bobbogo

Reputation: 15493

I am in the don't lie to make camp. Here, fine-grained dependencies are your friend. Get away from thinking that you need to express that prog1 depends on lib2. What you really want to say to make is something like:

"To link prog1 you need all the .o files, and all the appropriate .a files."

If you can express this, it will improve a number of very important parameters for your build:

  1. Parallel build works properly
    • The .o file for prog1 can compile at the same time as those for lib2.a
    • This is more important if you run tests as a part of the build (you do do that, don't you?)
  2. Time-to-do-nothing is very close to zero
    • Nothing worse than issuing a build, and several minutes later you get a build was already up-to-date (WinCE, I'm looking at you)
  3. Work is properly culled
    • In other words you can rely on your dependencies, and never have to do a make clean because you don't trust them

After all, these goals are really the whole point of using make. Get them wrong and you might as well use a batch file. (It's pretty tricky getting them right in a recursive make system BTW.)

Of course, expressing this cleanly in make does take a bit of effort, but you did say you had a large project.

Upvotes: 4

John
John

Reputation: 3520

I'm not in the recursive makefiles are evil camp -- while it's true that recursive makefiles are not as efficient (they don't maximize concurrency, etc), it's usually negligible. On the flip side, using recursive makefiles makes your project more scalable -- it's simpler to move modules in and out, share with other groups, etc.

In your case, if lib2 depends on lib1, you can just do:

 lib2: lib1
    make -C libs/lib2

Now make will build lib1 before lib2 (even if you have -j specified).

Now if you have cross-dependencies (something in lib1 depends on something in lib2, which in turn depends on something else in lib1), then you might want to consider either restructuring your directories to avoid the cross-dependencies, or using a single makefile (there's lots of sharp sticks exposed if you try to use recursive makefiles in this case).

Upvotes: 1

Related Questions