Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Compilers which produce minimum #include set

40 views
Skip to first unread message

Rick C. Hodgin

unread,
Jul 5, 2018, 2:25:50 PM7/5/18
to
Are there any existing compilers with a feature to write back out a
minimum set of #include references used by the application being
compiled?

If I #include <windows.h> for example, it includes a tremendous amount
of things I may not use in my app. If I only use 50 things, is there
a way in an existing compiler to get a minimum use set of those tokens
or objects and write out a header file that could be used in its place,
for example, so that the huge amount of extra unused header information
is not compiled?

--
Rick C. Hodgin

David Brown

unread,
Jul 5, 2018, 2:43:40 PM7/5/18
to
Here are a few links to suggestions - there is no need for me to copy
out the answers. But the tools I have seen will only look at the actual
#include lines in your code. So if you have "#include <windows.h>" and
use anything that comes from there, it will be marked as used. You
would have to first list all the sub-includes in <windows.h> to see
which of them are used or not.


<https://stackoverflow.com/questions/614794/c-c-detecting-superfluous-includes>


<http://www.includator.com/projects/includator/wiki/Find_Unused_Includes_Details>

<https://news.ycombinator.com/item?id=10958186>

Rick C. Hodgin

unread,
Jul 5, 2018, 2:48:20 PM7/5/18
to
Good to see. Thank you.

--
Rick C. Hodgin

Bart

unread,
Jul 5, 2018, 2:58:34 PM7/5/18
to
I would say that that was quite difficult to do.

And I'm not sure how well it would work in practice. For a start, you
have to process the full set of headers once to create the minimised
header.

But then that's only good for compiling exactly the same program; how
often that useful? If that is the case, then just use the last object
file created. And if the program /has/ changed, then that minimised
header will be out of date as new code will reference new stuff, while
other stuff is no longer needed.

Such a header will anyway be the result of one 'rendering' of a header;
the next one may produce different results because there has been a
subtle change in the environment.

And for something like windows.h, that may involve 650 nested #includes,
of I think some 150 unique headers (for mingw's windows.h I think that
is). If one item was needed in each header, would there still be 650
#includes, but there are now 150 minimised header files? What names will
they have, as they can't clash with the originals?

Anyway I believe this is just scratching surface of the likely problems.

Depending on what you are trying to achieve, perhaps try using or
adapting a much smaller windows.h from another compiler. (Eg. lccwin's
windows.h is 20K lines in 3 unique files, compared to MS' 200K lines in
100 files. Mine is 1.4K lines but there's lots missing...)

--
bart

Rick C. Hodgin

unread,
Jul 5, 2018, 3:23:22 PM7/5/18
to
On 7/5/2018 2:58 PM, Bart wrote:
> On 05/07/2018 19:25, Rick C. Hodgin wrote:
>> Are there any existing compilers with a feature to write back out a
>> minimum set of #include references used by the application being
>> compiled?
>>
>> If I #include <windows.h> for example, it includes a tremendous amount
>> of things I may not use in my app.  If I only use 50 things, is there
>> a way in an existing compiler to get a minimum use set of those tokens
>> or objects and write out a header file that could be used in its place,
>> for example, so that the huge amount of extra unused header information
>> is not compiled?
>
> I would say that that was quite difficult to do.

I think it would depend on how you parse #include files.

For each thing that's defined in header processing, you add a
"touchCount" variable to it, and each time it is referenced by
something outside of the header files themselves, that value
is incremented. You maintain a chain of things that have some
dependencies on other things, so that when one is touched, the
entire cascade of related things are also included. And in
some cases you can replace constants with their actual values
to remove those token names, etc.

In the end, you generate an output file which has been built and
established sufficiently to allow compilation of the thing without
the full compilation headers.

> And I'm not sure how well it would work in practice. For a start, you have to
> process the full set of headers once to create the minimised header.

Correct.

> But then that's only good for compiling exactly the same program; how often
> that useful? If that is the case, then just use the last object file created.
> And if the program /has/ changed, then that minimised header will be out of
> date as new code will reference new stuff, while other stuff is no longer
> needed.
>
> Such a header will anyway be the result of one 'rendering' of a header; the
> next one may produce different results because there has been a subtle change
> in the environment.

Correct.

> And for something like windows.h, that may involve 650 nested #includes, of I
> think some 150 unique headers (for mingw's windows.h I think that is). If one
> item was needed in each header, would there still be 650 #includes, but there
> are now 150 minimised header files? What names will they have, as they can't
> clash with the originals?

I'm thinking if you're compiling file.c, then it would create something
like file_mheader.h as an output, which documents only those features of
the entire compilation that are used.

It would allow a minimum backup that would compile as-is, allowing a
snapshot of time for a particular version without having to rely on
ever-changing headers over time.

One instance we had in our office was an application that's been in
use literally since the 2007 timeframe. It has been debugged, and
working well. A need came up to extend its abilities to incorporate
some new features with one of our servers, and the logic involved in
processing what our servers generate. It wasn't really any new needs
from Windows, just a recompilation of our own logic in the same base
Windows framework for the GUI.

The program was last compiled using WinXP and Visual Studio 2005 in 2007.
It had several dependencies which were no longer supported as they were,
and we had to tweak little things here and there to address changes made
in Vista, Windows 7, Windows 8, and now Windows 10.

Note: These issues were due to changes in the Visual Studio #include
files. Things that compiled in VS2005 did not compile in VS2015
or VS2017 without tweaks.

It didn't take too long (30 minutes), but if we had the minimal header
for compilation, it would have compiled as it was without any changes,
and we could've focused on the change in logic we needed.

And if we needed to add things to that version, and we had our summary
minimized header file, we could manually add the handful of things we
need from the true header locations.

> Anyway I believe this is just scratching surface of the likely problems.
>
> Depending on what you are trying to achieve, perhaps try using or adapting a
> much smaller windows.h from another compiler. (Eg. lccwin's windows.h is 20K
> lines in 3 unique files, compared to MS' 200K lines in 100 files. Mine is
> 1.4K lines but there's lots missing...)

I would like the compiler to generate the minimum output as much for
documentation and historic snapshots of versions as much anything else.
I've just never seen the ability anywhere.

--
Rick C. Hodgin

Manfred

unread,
Jul 6, 2018, 7:06:30 AM7/6/18
to
On 7/5/2018 8:58 PM, Bart wrote:
>
> I would say that that was quite difficult to do.
In fact it is not how <windows.h> is supposed to be used.

>
> And I'm not sure how well it would work in practice. For a start, you
> have to process the full set of headers once to create the minimised
> header.
>
> But then that's only good for compiling exactly the same program; how
> often that useful? If that is the case, then just use the last object
> file created. And if the program /has/ changed, then that minimised
> header will be out of date as new code will reference new stuff, while
> other stuff is no longer needed.
>
> Such a header will anyway be the result of one 'rendering' of a header;
> the next one may produce different results because there has been a
> subtle change in the environment.
>
It is much better to use the #define's that are indicated in <windows.h>
#define WIN32_LEAN_AND_MEAN will result in a minimal set, otherwise
macros like NOGDI will suppress the related items (GDI functionality in
this case)

bitrex

unread,
Jul 7, 2018, 1:16:12 AM7/7/18
to
What's the problem you're trying to ameliorate? Surely the compiler
isn't adding random dead code to the binary at any reasonable
optimization level. Is it excessive compile times? There are probably
easier ways to reduce compile times than the solution you suggest

Kenny McCormack

unread,
Jul 7, 2018, 5:52:43 AM7/7/18
to
In article <n0Y%C.292070$go7.2...@fx08.iad>,
This is typical of Rick's posting style. He will ask whether a certain
thing is possible (in one of many different phrasings - but the bottom
line is always that; phrasing it differently is part of his game) without
any indication of what the actual problem is. This inevitably causes all
the regs (the help-givers) to kick into overdrive trying to figure out what
he is actually talking about.

That said, ... It turns out that in this instance he did actually give his
use case. If you (by "you", I mean "bitrex") carefully re-read the thread,
you'll find Rick's description of the actual problem - which is very OS
(Windows) and tool-chain (having, basically, to do with needing to compile
old code on a new version of MS's tool-chain - i.e., Visual Studio)
specific.

--
The randomly chosen signature file that would have appeared here is more than 4
lines long. As such, it violates one or more Usenet RFCs. In order to remain
in compliance with said RFCs, the actual sig can be found at the following URL:
http://user.xmission.com/~gazelle/Sigs/CLCtopics

Rick C. Hodgin

unread,
Jul 7, 2018, 7:05:41 AM7/7/18
to
As Kenny said, it is to produce something that takes a snapshot of a
given working compilation at an instant in time for documentation
purposes. By having that exact copy / version of the full source code
necessary to compile the thing, a version can be documented which meets
the needs of the compile at the time.

I think once you get to each little milestone, you shouldn't need to
carry the full heaping pile of everything required to make your compiler
work, but only those things which are needed for your app. Then, on
more major milestones include everything.

--
Rick C. Hodgin

0 new messages