Jump to content

  • Log In with Google      Sign In   
  • Create Account


Force project files to inlude a header


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 Monkeynuts   Members   -  Reputation: 126

Like
0Likes
Like

Posted 16 December 2013 - 01:14 PM

Hi,

 

I have a project with a config.h file that controls several things in my source. I want to make sure that all my files include it. Sometimes I forget to include it in new files, which means that things that were supposed to be conditionally compiled get compiled when they shouldn't and vice-versa, and that creates all kinds of problems. Sometimes it takes a while to trace the problem back to the fact that I forgot the include.

 

Is there any way to make sure that all my files include a certain header file? My code gets compiled by gcc, clang and visual c++, and I'd relly prefer a cross-compiler and build system solution to this.

 

 



Sponsor:

#2 fastcall22   Crossbones+   -  Reputation: 4032

Like
2Likes
Like

Posted 16 December 2013 - 01:39 PM

I don't know about the others, but in Visual Studio, you can use the "force include file" option in the project properties under C/C++ > Advanced.
c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#3 Monkeynuts   Members   -  Reputation: 126

Like
0Likes
Like

Posted 16 December 2013 - 01:47 PM

Thanks! However, I really do need a cross-compiler solution.



#4 fastcall22   Crossbones+   -  Reputation: 4032

Like
2Likes
Like

Posted 16 December 2013 - 01:51 PM

According to the documentation for clang and gcc, it looks like you would need -include (or /FI if using clang-cl).

Edited by fastcall22, 16 December 2013 - 01:54 PM.

c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#5 Monkeynuts   Members   -  Reputation: 126

Like
0Likes
Like

Posted 16 December 2013 - 01:55 PM

Seems to be what I need! You've provided me with a solution for all three compilers now, that's great. Thanks!



#6 SeanMiddleditch   Members   -  Reputation: 4094

Like
6Likes
Like

Posted 16 December 2013 - 05:08 PM

Sometimes I forget to include it in new files, which means that things that were supposed to be conditionally compiled get compiled when they shouldn't and vice-versa, and that creates all kinds of problems

While the answers you have received were quite correct, I think you'll find with more experience that the correct solution is to simply make it so you can't even use features you don't have the right header for.

A further simple approach though would be to use explicit numeric values to enable/disable features and then enable warnings for undefined macro usage (-Wundef in GCC-like compilers and /w14668 in VC++), and then use value tests instead of ifdef or if defined():
 
//config.h
#define FEATURE 1
#define DISABLED_FEATURE 0

// somecode.cpp
#include "config.h"

#if FEATURE
stuff
#endif

#if OTHER_FEATURE
stuff that is disabled
#endif
The advantage here is that the compiler will (with those compiler flags) emit a diagnostic that FEATURE and OTHER_FEATURE are undefined if you try to test them without including config.h first.

A better technique is to abstract one level further. Use higher-level macros like THING_THAT_USES_FEATURE(stuff) which is defined in some header that itself includes config.h. An easy example is an assert library:
 
// config.h
#define ENABLE_ASSERTS 1

// asserts.h
#if ENABLE_ASSERTS
#define ASSERT(...) assert_stuff_here
#else
#define ASSERT(...)
#endif

// somecode.cpp
#include "asserts.h"

ASSERT(something)
As you can see in that example, there is no opportunity to remember or not config.h in order to use the assert library. If you include the header necessary to use the asserts at all, you're implicitly pulling in config.h, too.

The gist is that you don't use config headers. Make the config something that is passed to the compiler in your build system. This is trivial in every build system I've ever seen. Now there's no additional burden on the programmer after configuring the build. Every third-party library I've used that uses config headers for these kinds of things (a UNIX norm, sadly) is a pain in the ass to integrate into more complicated needs (like the many separate build configurations common in game development).

About the only thing I use forced includes for are precompiled headers (otherwise people tend to write all kinds of C++ code that accidentally requires that the precompiled header includes something they need which is unfortunate since the PCH is a build optimization and neither it nor its contents should be a hard dependency of any code).

#7 Monkeynuts   Members   -  Reputation: 126

Like
0Likes
Like

Posted 17 December 2013 - 03:49 PM

I'm actually using defines passed to the build system right now to configure my builds. I was going to migrate to a config file instead, to have all defines in a common place (together with nice comments and explanations). However, now that you mention it, that will probably be more of a headache when building for different platforms.

 

I like the second approach (and I've seen this in use, but never realized that it will actually help me by making sure I get compile time errors when appropriate - that's what happens when you just read something and don't use it yourself : )).

 

Thanks for the explanation and for expanding my views on this.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS