views:

391

answers:

1

We have a Makefile which runs on a Windows 2003 machine and we are using mingw32-make for it. Since the Makefile has many include paths, it exceeds the buffer size of 8K that the cmd can handle [Ref - http://support.microsoft.com/kb/830473/EN-US/due to which the compilation results in "input line too long" issue.

I wanted to know the following -

  1. What would be the best way to optimize the Makefile as I have already removed unwanted compiler switches, include paths etc.

  2. Is there any way we can put all the INCLUDE paths in one .txt file and import it in the Makefile.I could not find any mingw32 documentation for the same.

Any other inputs/hints/reference links are most welcome.

Thanks,
-HJSblogger

+1  A: 

One approach we took (this wasn't because we ran out of command-line space, just because we wanted a cleaner build system) was to have each "module" do its build in passes.

So, for example, say you have 3 modules, A, B and C.

Your control makefile simply calls each modules makefile with the same target.

Then we set the targets to be a consistent clean, header, lib and exec.

So, the control makefile was something like:

modules=A B C
clean:
    for i in $modules:
        ( cd $i ; make clean ; cd .. )
header:
    for i in $modules:
        ( cd $i ; make header ; cd .. )
lib:
    for i in $modules:
        ( cd $i ; make lib ; cd .. )
exec:
    for i in $modules:
        ( cd $i ; make exec ; cd .. )

Every module that had header files needed by other modules copied those header files into a central location during the header phase. Then, during the lib or exec phase, each module only had to use that central location to locate all of its headers. This also restricted modules to only using those headers that were published to the central location by other modules.

Similarly, every module that created a library needed by the exec phase, copied that library to a central location. This greatly minimized the -I (include directory) and -L (library directory) clauses in the build commands.

Using that scheme, you could rebuild the entire thing just by executing make clean header lib exec at the top level (or leave off the clean for a proper make build, taking into account the dependencies).

That's one way to get around your problem, but I'm actually wondering how you're exceeding the limit. 8K, even at 25 characters per path, would require about 300 distinct include paths. Is your hierarchy really that voluminous?

Update 1:

If you're looking for a quick'n'dirty way to get it working without changing the makefile "architecture", you write a script which, given a list of directories, will copy all header files from those directories to a central location.

Then run that as the first step in all your rules and modify the include statements in your compile lines to just reference that location rather than the large list. You could even do the copy in stages (e.g., 20 directories at a time x 20 times could handle 400 directories in total).

This gives you the same effect as my proposed solution with smaller changes to the makefiles.

Update 2:

One other solution, as you stated in your comments, was to alias a path.

You should be able to do that with subst.exe such as:

> subst x: "c:\Documents and Settings\Pax\My Documents\Not my directory"
> dir x:
  Volume in drive X has no label.
  Volume Serial Number is 8AA3-703A

  Directory of X:\

  08/09/2009  10:12 AM    <DIR>          .
  08/09/2009  10:12 AM    <DIR>          ..
  24/08/2009  01:54 PM             6,409 p0rn_sites.txt
  09/07/2008  02:49 PM    <DIR>          downloaded_p0rn
  : : :
  09/07/2008  02:52 PM    <DIR>          other_suspect_stuff
                 3 File(s)         18,520 bytes
                18 Dir(s)  63,840,849,920 bytes free

> subst x: /d
> dir x:
  The system cannot find the path specified.
paxdiablo
Pax, Thanks for the answer. Yes, the build is quite voluminous and has many include paths :)To be honest, the focus now is just to make the system run without any blockage.Thanks,-HJSBlogger
hjsblogger
@hjsblogger, if you're looking for a quick'n'dirty way to get it working, write a script which, given a list of directories, will copy all header files from those directories to a central location. Then run that as the first step in all your rules and modify the include statements in your compile lines to just reference that location rather than the large list. You could even do the copy in stages (e.g., 20 directories at a time x 20 times could handle 400 directories in total).
paxdiablo
@Pax: Thanks for the snippet, would definitely try to get a hold on this one and see if it works. In the meanwhile,I was also looking into if we can do an ALIAS for a path eg.ALIAS of C:\Inc_Folder\src\.. to X: so that all my INC paths would start from X:\ resulting in less usage of the cmd buffer.I redirected the cmd output to a file and found that out of 8K, close to 3K is coming because of the big starting path from where every component starts.What's your opinion on the same.I am still googling and checking if it's possible.I would also try to parallely look into your solution as well.
hjsblogger
@hjsblogger, I think the command you're looking for is subst - check the updates to the answer for details.
paxdiablo
@Pax: It is not yet solved since Alias or subst did not work in my case. Hence, now I am just building the files(.o) file by file rather than clubbing them component by component. Till now it is going fine.
hjsblogger
Why didn't subst work? It's pretty well tied in with the OS so should work fine. If you'd like, I could help you out there.
paxdiablo
@Pax - The problem is now solved, I reduced the size of the include paths from 8K to 4K. Now I am building file by file and not component by component.Thanks for your support, I would close the question now !!!-hjsblogger
hjsblogger
@hjs, the idea is not to close the question, it's to leave it here in case someone else strikes the same problem later. Closing it will result in the information just disappearing. A better idea would be to accept the answer (if it indeed was the reason you solved the problem) and just leave it alone.
paxdiablo