Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid recompilation with git and make

Tags:

I have two development branches in git and I frequently need to change between the two. However, the really frustrating thing is that every time I change branches in git, the entire project gets rebuilt because the file-system timestamps for some files will change.

Ofc, the makefiles are configured to build the project into two different build directories .

Is there any way around this? Compilation is a very long and time-consuming process...

Edit:- This is a slightly more detailed explanation of the question... Say I have a header files Basic.h which is included in a number of other files. Basic.h is different between branch 1 and branch 2.

Now let's say I have compiled branch 1 into build_branch1 and branch 2 into build_branch2. Say I have branch 2 currently checked out. Now I checkout branch 1 and change File1.cpp and recompile. Ideally, since only File1.cpp has changed since I compiled it the last time, this is the only file that should be recompiled.

However, since Basic.h has it's timestamp changed due to the checkout, all files that are including Basic.h will get recompiled. I want to avoid this.

like image 580
owagh Avatar asked Apr 27 '12 18:04

owagh


3 Answers

Git changes only the files that are updated between branches. But if your compiler does a full rebuild even if any single file was changed you can always clone and checkout your different branches into different directories. That's like:

/your-repo-name.branch1
/your-repo-name.branch2

This takes extra disk space but is much more convenient than switching divergent branches in a huge repo.

like image 161
Sergey K. Avatar answered Sep 18 '22 19:09

Sergey K.


Another partial answer: compiler cache.

When you switch back to the original branch and rebuild, although the dependencies say that numerous files dependent on Basic.h have to be rebuilt, the object files can be pulled from a compiler cache.

ccache ( http://ccache.samba.org/ ) still has to do some fairly expensive work (processing the pre-processed translation unit, since an entire translation unit is used a hash key) but it's a lot cheaper than compiling.

In some cases ccache can eliminate a compile in the face of a change that does not affect it, like some whitespace changes. For instance if you change a comment in a dependent file (header or source), that does not invalidate the cached object file.

So it can help even if you do a git pull and pick up a new change to Basic.h you haven't seen before.

like image 27
Kaz Avatar answered Sep 18 '22 19:09

Kaz


If you know which files actually need compilation, and do those manually, GNU Make (at least, I don't know about other implementations) has a flag for you: -t, which basically runs over your Makefile and changes timestamps instead of running commands.

You'll still need to update the files that need updating before using this flag, or you'll end up with object files that are legitimately out-of-date but look updated. See the linked doc for details.

The -o option might also interest you, depending on how much changes when you switch branches.

like image 28
Adam Blinkinsop Avatar answered Sep 21 '22 19:09

Adam Blinkinsop