This issue was originally created at: 2010-08-25 15:51:12.
This issue was reported by: jpettiss.
jpettiss said at 2010-08-25 15:51:12
Compiling and linking in one step using Program() is painless and intuitive. Attempting to use a precompiled header to speed this up almost works flawlessly, but there are two hacks currently needed to make this work.
Firstly, if the source supplied to the Program() step contains the PCH source itself (typically StdAfx.cpp, but in my example to make it clear I used 'master' for the name of my precompiled header), then scons fails with message:
scons: *** Two environments with different actions were specified for the same target: src\master.obj
File "C:\bwaysource\active\fark\SConscript", line 20, in <module>
Removing the source file from the list of source given to Program() fixes this. If debugging symbols are turned on, however, a linker error is issued:
alpha.obj : error LNK2011: precompiled object not linked in; image may not run output\main.exe : fatal error LNK1120: 1 unresolved externals
scons: *** [output\main.exe] Error 1120
This is because the linker step contains all the object files except the object file associated with the PCH (here, master.obj).
So secondly, we need to tweak the LINKFLAGS to re-add that object:
jpettiss said at 2010-08-25 15:52:17 Created an attachment (id=790)
Simple repro with explanatory comments
garyo said at 2010-09-04 07:00:05
Hi Jason; thanks for the report. What's your recommended fix? Should SCons always automatically remove the PCH source from the compiler source list and re-add it to the link sources? If you have an idea for a patch that would work in the general case, please let us know.
jpettiss said at 2010-09-07 17:11:04
In practice it turns out there are slightly different tricks necessary to get PCH working with static libraries vs. programs. Boiling it down as far as I can, the difference looks like this:
This assumes that src/ contains all source, including a file master.h and master.cc which only includes master.h, and that all modules #include "master.h the first thing they do.
The -Yl flag seems necessary when building a library, to prevent any objects which don't refer to any symbols in the PCH from generating linker errors. I don't quite get that but it does the trick, documented here:
The addition of pch_obj to the source for Program doesn't seem necessary (or at least I haven't yet found a case where not having it caused a linker error). However, adding it certainly doesn't cause any problems.
So far the above works on all release configurations I can think of under VS2005 and VS2008.
I'm not sure what's easiest in terms of an internal fix; seems like the source node created/given to PCH needs to be stored somewhere, since the Program/StaticLibrary step only take .pch file.
But having PCH return a foursome might be a cleaner way to deal with things:
It could return the pch file, the pch object file, the source node, and the PCHSTOP name, such that the PCH argument to Library/Program would have all the information necessary to make this work regardless of the compiler version.
Conditional support for PCH would be a lot easier this way too, by just adding a dummy PCH builder which returns an empty list.
This issue was originally created at: 2010-08-25 15:51:12. This issue was reported by:
jpettiss
.Compiling and linking in one step using
Program()
is painless and intuitive. Attempting to use a precompiled header to speed this up almost works flawlessly, but there are two hacks currently needed to make this work.Firstly, if the source supplied to the Program() step contains the PCH source itself (typically
StdAfx.cpp
, but in my example to make it clear I used 'master' for the name of my precompiled header), then scons fails with message:Removing the source file from the list of source given to
Program()
fixes this. If debugging symbols are turned on, however, a linker error is issued:This is because the linker step contains all the object files except the object file associated with the PCH (here,
master.obj
).So secondly, we need to tweak the
LINKFLAGS
to re-add that object:According to http://msdn.microsoft.com/en-us/library/3ay26wa2%28VS.80%29.aspx [dead link], it's always required that this object file be included (but in fact it only fails when debugging symbols are enabled).
Simple repro with explanatory comments
Hi Jason; thanks for the report. What's your recommended fix? Should SCons always automatically remove the PCH source from the compiler source list and re-add it to the link sources? If you have an idea for a patch that would work in the general case, please let us know.
In practice it turns out there are slightly different tricks necessary to get PCH working with static libraries vs. programs. Boiling it down as far as I can, the difference looks like this:
This assumes that
src/
contains all source, including a filemaster.h
andmaster.cc
which only includesmaster.h
, and that all modules#include "master.h
the first thing they do.The
-Yl
flag seems necessary when building a library, to prevent any objects which don't refer to any symbols in the PCH from generating linker errors. I don't quite get that but it does the trick, documented here:http://msdn.microsoft.com/en-us/library/w6y1zk9f%28v=VS.71%29.aspx [dead link]
The addition of
pch_obj
to the source for Program doesn't seem necessary (or at least I haven't yet found a case where not having it caused a linker error). However, adding it certainly doesn't cause any problems.So far the above works on all release configurations I can think of under VS2005 and VS2008.
I'm not sure what's easiest in terms of an internal fix; seems like the source node created/given to PCH needs to be stored somewhere, since the Program/StaticLibrary step only take
.pch
file.But having PCH return a foursome might be a cleaner way to deal with things:
It could return the pch file, the pch object file, the source node, and the PCHSTOP name, such that the PCH argument to
Library
/Program
would have all the information necessary to make this work regardless of the compiler version.Conditional support for PCH would be a lot easier this way too, by just adding a dummy PCH builder which returns an empty list.
gregnoel said at 2010-09-27 17:35:55
Bug party triage.
Simple repro with explanatory comments