Skip to content

PCH source file rebuilt every time when certain filenames are used #2249

Open
@bdbaddog

Description

@bdbaddog

This issue was originally created at: 2008-11-01 23:58:39.
This issue was reported by: jchristian.

jchristian said at 2008-11-01 23:58:39

Scons Version: Using "vs_revamp" branch build off of the 1.1.0 release. I suspect this problem happens on the official 1.1.0 release, but I haven't checked it.

Compiler: VS2008

Defect Summary: In attempting to use precompiled headers in building a Windows project, I ran into a fairly obscure bug. Apparently, if the filename specified as the source file for the PCH generation begins with the letter 'c' or 'C', the build regenerates the PCH file every time the build is run...even if no files have changed. If I change that filename to begin with another letter, it works. Note that originally my PCH source file was called "CorePCH.cpp". In trying things, I found it could be shortened to just "C.cpp" and produce the problem.

Expected Behavior: On the second build, it should just return with an "up to date" status.

Below is my directory structure and the files needed to reproduce the issue. Note that once you get this all setup, you can make it work successfully by changing the filename C.cpp in the SConscript to just PCH.cpp or XCorePCH.cpp.

Let me know if you have questions.

Directory structure:

project
    |
    +--SConstruct
    |
    +--include
    |    |
    |    +-- core
    |         |
    |         +-- CorePCH.hpp
    |             Hello.hpp
    |
    +-- lib
         |
         +-- core
              |
              +-- CorePCH.cpp
                  Hello.cpp
                  SConscript 

SConscript:

import glob

# get all the build variables we need
Import("env", "buildroot", "project", "mode", "debugcflags", "releasecflags")
staticlibenv = env.Clone()

builddir = buildroot + "/" + project  # holds the build directory for this
project
targetpath = builddir  # holds the path to the executable in the build directory

# append the user's additional compile flags
# assume debugcflags and releasecflags are defined
if mode == "debug":
    staticlibenv.Append(CPPFLAGS=debugcflags)
else:
    staticlibenv.Append(CPPFLAGS=releasecflags)


# get source file list
srclst = map(lambda x: builddir + "/static/" + x, glob.glob("*.cpp"))

# specify the build directory
staticlibenv.BuildDir(builddir + "/static", ".", duplicate=0)

staticlibenv2 = staticlibenv.Clone()
staticlibenv2["PCHSTOP"] = "core/CorePCH.hpp"
# pch.cpp is beside this SConscript
staticlibenv2["PCH"] = staticlibenv2.PCH(builddir + "/static/C.cpp")[0]
print("here 0")
print(staticlibenv2["PCH"])
print("here 1")
additionalcflags = ["-Yl__xge_pch_symbol"]
staticlibenv2.Append(CPPFLAGS=additionalcflags)
staticlib = staticlibenv2.StaticLibrary(targetpath + "/static/core", source=srclst)

SConstruct:

# get the mode flag from the command line
# default to 'release' if the user didn't specify
mode = ARGUMENTS.get("mode", "debug")  # holds current mode
platform = ARGUMENTS.get("platform", "win32")  # holds current platform

# check if the user has been naughty: only 'debug' or 'release' allowed
if not (mode in ["debug", "release"]):
    print("Error: expected 'debug' or 'release', found: " + mymode)
    Exit(1)

# check if the user has been naughty: only 'win32' or 'xbox' allowed
if not (platform in ["win32", "xbox"]):
    print("Error: expected 'win32' or 'release', found: " + platform)
    Exit(1)


# tell the user what we're doing
print("**** Compiling in " + mode + " mode...")

debugcflags = [  # extra compile flags for debug
    "-Od",
    "-MDd",
    "-Ob0",
    "-Z7",
    "-W4",
    "-EHsc",
    "-GR",
    "-D_DEBUG",
    "-DUSE_PCH",
]
releasecflags = [  # extra compile flags for release
    "-O2",
    "-MD",
    "-Ob2",
    "-EHsc",
    "-GR",
    "-DNDEBUG",
    "-DUSE_PCH",
]

env = Environment()

env.Append(CPPPATH=["#include", "#ext/boost-1.34.1"])

if mode == "debug":
    env.Append(LINKFLAGS="/DEBUG")

buildroot = "#build/" + mode  # holds the root of the build directory tree

# make sure the sconscripts can get to the variables
Export("env", "mode", "platform", "debugcflags", "releasecflags")

# put all .sconsign files in one place
env.SConsignFile()

# specify the sconscript for myprogram
project = "lib/core"
SConscript(project + "/SConscript", exports=["buildroot", "project"])

CorePCH.hpp:

#ifndef CORE_PCH_HPP
#define CORE_PCH_HPP
 
#ifdef USE_PCH
#include <string>
#include <iostream>
#include "core/Hello.hpp"
#endif
 
#endif // CORE_PCH_HPP

CorePCH.cpp or C.cpp:

#include "core/CorePCH.hpp"

Hello.hpp:

#ifndef HELLO_HPP
#define HELLO_HPP
 
#ifndef USE_PCH
#include <string>
#endif
 
class Hello
{
    public:
       Hello(const std::string& msg);
       ~Hello();
       void sayIt();
       
   private:
      std::string m_msg; 
};
#endif // HELLO_HPP

Hello.cpp:

#include "core/CorePCH.hpp"
#ifndef USE_PCH
#include "core/Hello.hpp"
#include <iostream>
#endif
 
Hello::Hello(const std::string& msg):m_msg(msg)
{
}
 
Hello::~Hello()
{
}
 
void Hello::sayIt()
{
    std::cout << m_msg << std::endl;
}

jchristian said at 2008-11-02 00:08:53

I made this a P2 because even though it is obscure, it is hella hard to track down what is going on. The workaround is to simply use another filename but this isn't apparent until many hours have been wasted. As well, I suspect the fix will be trivial and from my experience P3 and P4 defects tend to get put off practically forever.

jchristian said at 2008-11-04 00:39:53

Created an attachment (id=531)
Zip file that creates the dir structure described in the defect

jchristian said at 2008-11-04 00:49:32

Upon further investigation I have found that the filenames A.cpp thru H.cpp do not work. I have confirmed that I.cpp thru Q.cpp work. And also X.cpp. Other filenames were not tested because I got tired of doing it. To test a different filename, simply rename C.cpp in the lib/core directory and then update the SConscript file in that same directory to use that filename.

My suspicion is that the dependencies are not being generated or kept because of some defect in parsing or concatenating the filename.

jchristian said at 2008-11-04 00:55:43

Hopefully this can be fixed for 1.2

gregnoel said at 2008-12-04 17:41:09

1.2 is frozen; issues that didn't make it into 1.2 are moved to 1.3.

stevenknight said at 2008-12-06 11:22:53

This issue erroneously had a target milestone put on it right away, so it never got discussed and assigned to someone specific. Consequently, it's been languishing in a 1.[23] + issues@scons bucket that no one actually looks at. Change the target milestone to -unspecified- so we can discuss this at the next Bug Party and get it prioritized appropriately.

gregnoel said at 2008-12-24 06:41:53

Bug party triage. Steven suggests that it might be an interaction with the heuristics for determining the drive letter, but otherwise nobody has a clue. Assign to Steven for research as a penalty for suggesting a possibility.

Next time let us assign the milestone and priority. If it doesn't pass through our process, it'll get lost as this one did.

jchristian said at 2008-12-24 12:26:00

Sorry about that, I'll do that in the future. This was my first issue submitted and I wasn't sure what to put on some of the fields :O

stevenknight said at 2009-11-10 18:00:19

stevenknight => issues@scons

gregnoel said at 2010-01-20 02:20:51

Bug party triage. This area has been heavily revamped. Bill to research and see if the problem still happens.

John, can you try your test case with the newest checkpoint (published yesterday) and see if it's been fixed? Add a note to this issue and let us (well, Bill, to be precise) if you still see the problem. Tks.

gregnoel said at 2010-07-21 16:58:11

Bug party triage. Bump this issue to P1 so it will be reviewed at next bug party.

jchristian attached testpch.zip at 2008-11-04 00:39:53.

Zip file that creates the dir structure described in the defect

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions