views:

131

answers:

5

I have a .h file which is used almost throughout the source code (in my case, it is just one directory with. .cc and .h files). Basically, I keep two versions of .h file: one with some debugging info for code analysis and the regular one. The debugging version has only one extra macro and extern function declaration. I switch pretty regularly between two versions. However, this causes a 20 minute recompilation.

How would you recommend to avoid this issue of recompilation? Perhaps to set some flags, create different tree? what are the common solutions and how to embed them?

The new .h file contains:

extern  void (foo)(/*some params*/);

/***extra stuff****/
#define foo(...) ( /*call_some_function*/) , foo())
/*some_functions*_for_debugging/

As, you can see that will ensue a recompilation. I build with gcc on Linux AS 3

Thanks

+2  A: 

You need to minimize the amount of your code (specifically - the number of files) that depend on that header file. Other than that you can't do much - when you need to change the header you will face recompilation of everything that includes it.

So you need to reorganize your code in such a way that only a select files include the header. For example you could move the functions that need its contents into a separate source file (or several files) and only include the header into those but into other files.

sharptooth
That's not a solution i can adapt. And I need a lot of file to depend on that .h file (it is an equivalent to common.h, hence i add debugging info there)
vehomzzz
+1  A: 

Why not move the macro to its own header and only include it where needed.

Just another thought.

I cannot see how you can avoid recompiling the dependent source files. However you may be able to speed up the other processing in the build.

For example can you use a form of precompiled headers, and only include your headerr in the code files and not other headers. Another way could be to parallelise the build or perhaps use a fast piece of hardware such as a solid state drive.

Remember that hardware is cheap programmers are expensive to quote wotshisname.

Preet Sangha
cuz I will have to modify 100 cpp files, at least
vehomzzz
But that modification can be done automatically?
MSalters
Are you asking me? I don't know!
vehomzzz
You can easily do this with a `sed` script, or a number of other methods. (Just make sure you have a backup/checkin first!)
gavinb
what is it going to solve? I will still need to rebuild all those .c files that use the macro?
vehomzzz
+2  A: 

If the debugging macros are actually used in most of the files that include the header, then they need to be recompiled anyway! In this case, you have two options:

  1. Keep two sets of object files, one without debugging code and one with. Use different makefiles/build configurations to allow them to be kept in separate locations.

  2. Use a global variable, along these lines:

In your common.h:

extern int debug;

In your debug.c:

int debug = 1;

Everywhere else (can use a macro for this):

if (debug) {
    /*(do_debug_stuff*/
}

A slight variation of the concept is to call an actual function in debug.c that might just do nothing if debugging is disabled.

Artelius
+1 how and where do I set debug? can you show the example of 1 and 2 with a simple example?
vehomzzz
On second thought, it cannot work. Please take a look at what I have in .h file. I updated the question
vehomzzz
+1 for keeping sperate optimized/debug trees for object files. That is what we do. Just have 2 separate targets in your makefile and a switch in your make command's wrapper to change the version of .h file as well as target for object files.
DVK
+3  A: 

To avoid the issue with an external function , you could leave the prototype in both versions, it doesn't harm being there, if not used. But with the macro no chance, you can forget it, it needs recompilation for code replacements.

I would make intensive use of precompiled headers to fasten recompilation (as it cannot be avoided). GCC and Precompiled-Headers. For other compilers use your favorite search engine. Any modern compiler should support this feature, for large scale projects it's inevitable you have to use it otherwise you'll be really unproductive.

Beside this, if you have enough disk space, I would check out two working copies. Each of them compiled with different settings. You would have to commit and update each time to transfer changes to the other working copy but it'll take for sure less than 20mins ;-)

jdehaan
I am leaning towards making two copies. Let me take a look GCC and Precompiled-Headers, as I have never used it on linux, only on windows.
vehomzzz
Why have two copies of your code when you can just get your build system to use two different build trees?
Artelius
@Andrei, of course you would have to make changes everywhere to use the precompiled header but it's a one time effort and it seems to me that you can drastically reduce compile time if you did not yet set it up. My prognostic is that you'll get easily under 5 minutes by choosing the right headers...
jdehaan
@Artelius, I supposed he's using automake/autoconf like stuff, that's why I posted the link regarding gcc. Using the auto... scripts, everything builds in the source tree and not so easy to configure differently (it is probably possible but I switched to cmake after loosing much hair on my head ;-) so I'm not keen on switching back)
jdehaan
Oh dear. Yeah, ok.
Artelius
+2  A: 

I don't exactly understand your problem. As I understood, you are trying to create a test framework. I can suggest something. You may move the changing stuff to .c file like follows.

In new.h

extern  void (foo)(/*some params*/);

/***extra stuff****/
#define foo(...) ( /*call_some_function_dummy*/) , foo())
/*some_functions*_for_debugging/

In new.c

call_some_function_dummy()
{

#ifdef _DEBUG

    call_some_function()

#endif

}

Now if you switch to debug mode, only New.c need to be recompiled and compilation will be much faster. Hope this will help you.

Solution 2:

In New.h

extern void (foo)(/*some params*/);

/***extra stuff****/ 
#define foo(...) ( /*call_some_function[0]*/) , foo()) 
/*some_functions*_for_debugging/

In New.c

#ifdef _DEBUG 

call_some_function[] = 
{
    call_some_function0,
    call_some_function1
};

#else 

call_some_function[]
{
    dummy_nop,
    dummy_nop
};

#endif
Vadakkumpadath
I suggested this kind of thing already.
Artelius
I was using this kind of a thing already, and it is a good workaround. However, my application is time sensitive and call_some_function_dummy function will add unnecessary overhead.
vehomzzz
If your application is time sensitive you can use function pointer array instead of dummy function. Please see the updated answer.
Vadakkumpadath
"my application is time sensitive and call_some_function_dummy function will add unnecessary overhead": more overhead than the debugging stuff?
Max Lybbert