BUG: Split precompiled header flags into a separate per-global-generator flag map. This is needed because the flag mappings differ across VS IDE versions. This fixes bug#3512 for VS8 where as the previous fix only worked for VS7.
This commit is contained in:
parent
55603ea9eb
commit
fb38af53c0
|
@ -35,6 +35,7 @@ cmLocalGenerator *cmGlobalVisualStudio71Generator::CreateLocalGenerator()
|
|||
{
|
||||
cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator;
|
||||
lg->SetVersion71();
|
||||
lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
|
||||
lg->SetGlobalGenerator(this);
|
||||
return lg;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "cmMakefile.h"
|
||||
#include "cmake.h"
|
||||
|
||||
|
||||
cmGlobalVisualStudio7Generator::cmGlobalVisualStudio7Generator()
|
||||
{
|
||||
this->FindMakeProgramFile = "CMakeVS7FindMake.cmake";
|
||||
|
@ -138,7 +137,8 @@ std::string cmGlobalVisualStudio7Generator
|
|||
///! Create a local generator appropriate to this Global Generator
|
||||
cmLocalGenerator *cmGlobalVisualStudio7Generator::CreateLocalGenerator()
|
||||
{
|
||||
cmLocalGenerator *lg = new cmLocalVisualStudio7Generator;
|
||||
cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator;
|
||||
lg->SetExtraFlagTable(this->GetExtraFlagTableVS7());
|
||||
lg->SetGlobalGenerator(this);
|
||||
return lg;
|
||||
}
|
||||
|
@ -821,3 +821,24 @@ bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project,
|
|||
// default is to be part of the build
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static cmVS7FlagTable cmVS7ExtraFlagTable[] =
|
||||
{
|
||||
// Precompiled header and related options. Note that the
|
||||
// UsePrecompiledHeader entries are marked as "Continue" so that the
|
||||
// corresponding PrecompiledHeaderThrough entry can be found.
|
||||
{"UsePrecompiledHeader", "YX", "Automatically Generate", "2",
|
||||
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
|
||||
{"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
{"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3",
|
||||
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
|
||||
{"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
cmVS7FlagTable const* cmGlobalVisualStudio7Generator::GetExtraFlagTableVS7()
|
||||
{
|
||||
return cmVS7ExtraFlagTable;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "cmGlobalGenerator.h"
|
||||
|
||||
class cmTarget;
|
||||
struct cmVS7FlagTable;
|
||||
|
||||
/** \class cmGlobalVisualStudio7Generator
|
||||
* \brief Write a Unix makefiles.
|
||||
|
@ -97,6 +98,7 @@ public:
|
|||
virtual const char* GetCMakeCFGInitDirectory() { return "$(OutDir)"; }
|
||||
|
||||
protected:
|
||||
static cmVS7FlagTable const* GetExtraFlagTableVS7();
|
||||
virtual void OutputSLNFile(cmLocalGenerator* root,
|
||||
std::vector<cmLocalGenerator*>& generators);
|
||||
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
|
||||
|
|
|
@ -36,6 +36,7 @@ cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator()
|
|||
{
|
||||
cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator;
|
||||
lg->SetVersion8();
|
||||
lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
|
||||
lg->SetGlobalGenerator(this);
|
||||
return lg;
|
||||
}
|
||||
|
@ -245,3 +246,21 @@ cmGlobalVisualStudio8Generator
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static cmVS7FlagTable cmVS8ExtraFlagTable[] =
|
||||
{
|
||||
// Precompiled header and related options. Note that the
|
||||
// UsePrecompiledHeader entries are marked as "Continue" so that the
|
||||
// corresponding PrecompiledHeaderThrough entry can be found.
|
||||
{"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "2",
|
||||
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
|
||||
{"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
// There is no YX option in the VS8 IDE.
|
||||
{0,0,0,0,0}
|
||||
};
|
||||
cmVS7FlagTable const* cmGlobalVisualStudio8Generator::GetExtraFlagTableVS8()
|
||||
{
|
||||
return cmVS8ExtraFlagTable;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
virtual void Configure();
|
||||
virtual void Generate();
|
||||
protected:
|
||||
static cmVS7FlagTable const* GetExtraFlagTableVS8();
|
||||
virtual void AddPlatformDefinitions(cmMakefile* mf);
|
||||
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
|
||||
std::vector<cmLocalGenerator*>& generators);
|
||||
|
|
|
@ -33,6 +33,7 @@ cmLocalGenerator *cmGlobalVisualStudio8Win64Generator::CreateLocalGenerator()
|
|||
cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator;
|
||||
lg->SetVersion8();
|
||||
lg->SetPlatformName(this->PlatformName.c_str());
|
||||
lg->SetExtraFlagTable(this->GetExtraFlagTableVS8());
|
||||
lg->SetGlobalGenerator(this);
|
||||
return lg;
|
||||
}
|
||||
|
|
|
@ -28,11 +28,14 @@
|
|||
|
||||
#include <ctype.h> // for isspace
|
||||
|
||||
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator()
|
||||
{
|
||||
this->Version = 7;
|
||||
this->PlatformName = "Win32";
|
||||
this->ExtraFlagTable = 0;
|
||||
}
|
||||
|
||||
cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
|
||||
|
@ -255,26 +258,6 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(std::ostream& fout,
|
|||
fout << "\t</Configurations>\n";
|
||||
}
|
||||
|
||||
// This is a table mapping XML tag IDE names to command line options
|
||||
struct cmVS7FlagTable
|
||||
{
|
||||
const char* IDEName; // name used in the IDE xml file
|
||||
const char* commandFlag; // command line flag
|
||||
const char* comment; // comment
|
||||
const char* value; // string value
|
||||
unsigned int special; // flags for special handling requests
|
||||
enum
|
||||
{
|
||||
UserValue = (1<<0), // flag contains a user-specified value
|
||||
UserIgnored = (1<<1), // ignore any user value
|
||||
UserRequired = (1<<2), // match only when user value is non-empty
|
||||
Continue = (1<<3), // continue looking for matching entries
|
||||
|
||||
UserValueIgnored = UserValue | UserIgnored,
|
||||
UserValueRequired = UserValue | UserRequired
|
||||
};
|
||||
};
|
||||
|
||||
// fill the table here currently the comment field is not used for
|
||||
// anything other than documentation NOTE: Make sure the longer
|
||||
// commandFlag comes FIRST!
|
||||
|
@ -334,16 +317,10 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[] =
|
|||
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
|
||||
{"PrecompiledHeaderThrough", "Yc", "Precompiled Header Name", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
{"UsePrecompiledHeader", "YX", "Automatically Generate", "2",
|
||||
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
|
||||
{"PrecompiledHeaderThrough", "YX", "Precompiled Header Name", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
{"UsePrecompiledHeader", "Yu", "Use Precompiled Header", "3",
|
||||
cmVS7FlagTable::UserValueIgnored | cmVS7FlagTable::Continue},
|
||||
{"PrecompiledHeaderThrough", "Yu", "Precompiled Header Name", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
{"PrecompiledHeaderFile", "Fp", "Generated Precompiled Header", "",
|
||||
cmVS7FlagTable::UserValue},
|
||||
// The YX and Yu options are in a per-global-generator table because
|
||||
// their values differ based on the VS IDE version.
|
||||
{"ForcedIncludeFiles", "FI", "Forced include files", "",
|
||||
cmVS7FlagTable::UserValueRequired},
|
||||
|
||||
|
@ -395,7 +372,8 @@ public:
|
|||
Compiler,
|
||||
Linker
|
||||
};
|
||||
cmLocalVisualStudio7GeneratorOptions(Tool tool);
|
||||
cmLocalVisualStudio7GeneratorOptions(Tool tool,
|
||||
cmVS7FlagTable const* extraTable = 0);
|
||||
|
||||
// Store options from command line flags.
|
||||
void Parse(const char* flags);
|
||||
|
@ -441,7 +419,10 @@ private:
|
|||
|
||||
bool DoingDefine;
|
||||
cmVS7FlagTable const* FlagTable;
|
||||
cmVS7FlagTable const* ExtraFlagTable;
|
||||
void HandleFlag(const char* flag);
|
||||
bool CheckFlagTable(cmVS7FlagTable const* table, const char* flag,
|
||||
bool& flag_handled);
|
||||
};
|
||||
|
||||
void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
||||
|
@ -527,7 +508,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
std::string defineFlags = this->Makefile->GetDefineFlags();
|
||||
|
||||
// Construct a set of build options for this target.
|
||||
Options targetOptions(Options::Compiler);
|
||||
Options targetOptions(Options::Compiler, this->ExtraFlagTable);
|
||||
targetOptions.FixExceptionHandlingDefault();
|
||||
targetOptions.Parse(flags.c_str());
|
||||
targetOptions.Parse(defineFlags.c_str());
|
||||
|
@ -1204,7 +1185,7 @@ void cmLocalVisualStudio7Generator
|
|||
<< "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n";
|
||||
if(!compileFlags.empty())
|
||||
{
|
||||
Options fileOptions(Options::Compiler);
|
||||
Options fileOptions(Options::Compiler, this->ExtraFlagTable);
|
||||
fileOptions.Parse(compileFlags.c_str());
|
||||
fileOptions.OutputAdditionalOptions(fout, "\t\t\t\t\t", "\n");
|
||||
fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
|
||||
|
@ -1648,8 +1629,9 @@ std::string cmLocalVisualStudio7Generator
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
cmLocalVisualStudio7GeneratorOptions
|
||||
::cmLocalVisualStudio7GeneratorOptions(Tool tool):
|
||||
DoingDefine(false), FlagTable(0)
|
||||
::cmLocalVisualStudio7GeneratorOptions(Tool tool,
|
||||
cmVS7FlagTable const* extraTable):
|
||||
DoingDefine(false), FlagTable(0), ExtraFlagTable(extraTable)
|
||||
{
|
||||
// Choose the flag table for the requested tool.
|
||||
switch(tool)
|
||||
|
@ -1761,6 +1743,7 @@ void cmLocalVisualStudio7GeneratorOptions::HandleFlag(const char* flag)
|
|||
// Look for known arguments.
|
||||
if(flag[0] == '-' || flag[0] == '/')
|
||||
{
|
||||
// Look for preprocessor definitions.
|
||||
if(flag[1] == 'D')
|
||||
{
|
||||
if(flag[2] == '\0')
|
||||
|
@ -1775,60 +1758,24 @@ void cmLocalVisualStudio7GeneratorOptions::HandleFlag(const char* flag)
|
|||
}
|
||||
return;
|
||||
}
|
||||
else if(this->FlagTable)
|
||||
|
||||
// Look through the available flag tables.
|
||||
bool flag_handled = false;
|
||||
if(this->FlagTable &&
|
||||
this->CheckFlagTable(this->FlagTable, flag, flag_handled))
|
||||
{
|
||||
// Look for an entry in the flag table matching this flag.
|
||||
bool flag_handled = false;
|
||||
for(cmVS7FlagTable const* entry = this->FlagTable;
|
||||
entry->IDEName; ++entry)
|
||||
{
|
||||
bool entry_found = false;
|
||||
if(entry->special & cmVS7FlagTable::UserValue)
|
||||
{
|
||||
// This flag table entry accepts a user-specified value. If
|
||||
// the entry specifies UserRequired we must match only if a
|
||||
// non-empty value is given.
|
||||
int n = static_cast<int>(strlen(entry->commandFlag));
|
||||
if(strncmp(flag+1, entry->commandFlag, n) == 0 &&
|
||||
(!(entry->special & cmVS7FlagTable::UserRequired) ||
|
||||
static_cast<int>(strlen(flag+1)) > n))
|
||||
{
|
||||
if(entry->special & cmVS7FlagTable::UserIgnored)
|
||||
{
|
||||
// Ignore the user-specified value.
|
||||
this->FlagMap[entry->IDEName] = entry->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the user-specified value.
|
||||
this->FlagMap[entry->IDEName] = flag+1+n;
|
||||
}
|
||||
entry_found = true;
|
||||
}
|
||||
}
|
||||
else if(strcmp(flag+1, entry->commandFlag) == 0)
|
||||
{
|
||||
// This flag table entry provides a fixed value.
|
||||
this->FlagMap[entry->IDEName] = entry->value;
|
||||
entry_found = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(this->ExtraFlagTable &&
|
||||
this->CheckFlagTable(this->ExtraFlagTable, flag, flag_handled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the flag has been handled by an entry not requesting a
|
||||
// search continuation we are done.
|
||||
if(entry_found && !(entry->special & cmVS7FlagTable::Continue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the entry was found the flag has been handled.
|
||||
flag_handled = flag_handled || entry_found;
|
||||
}
|
||||
|
||||
// If any map entry handled the flag we are done.
|
||||
if(flag_handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// If any map entry handled the flag we are done.
|
||||
if(flag_handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1839,6 +1786,60 @@ void cmLocalVisualStudio7GeneratorOptions::HandleFlag(const char* flag)
|
|||
cmsysSystem_Shell_Flag_VSIDE);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
cmLocalVisualStudio7GeneratorOptions
|
||||
::CheckFlagTable(cmVS7FlagTable const* table, const char* flag,
|
||||
bool& flag_handled)
|
||||
{
|
||||
// Look for an entry in the flag table matching this flag.
|
||||
for(cmVS7FlagTable const* entry = table; entry->IDEName; ++entry)
|
||||
{
|
||||
bool entry_found = false;
|
||||
if(entry->special & cmVS7FlagTable::UserValue)
|
||||
{
|
||||
// This flag table entry accepts a user-specified value. If
|
||||
// the entry specifies UserRequired we must match only if a
|
||||
// non-empty value is given.
|
||||
int n = static_cast<int>(strlen(entry->commandFlag));
|
||||
if(strncmp(flag+1, entry->commandFlag, n) == 0 &&
|
||||
(!(entry->special & cmVS7FlagTable::UserRequired) ||
|
||||
static_cast<int>(strlen(flag+1)) > n))
|
||||
{
|
||||
if(entry->special & cmVS7FlagTable::UserIgnored)
|
||||
{
|
||||
// Ignore the user-specified value.
|
||||
this->FlagMap[entry->IDEName] = entry->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the user-specified value.
|
||||
this->FlagMap[entry->IDEName] = flag+1+n;
|
||||
}
|
||||
entry_found = true;
|
||||
}
|
||||
}
|
||||
else if(strcmp(flag+1, entry->commandFlag) == 0)
|
||||
{
|
||||
// This flag table entry provides a fixed value.
|
||||
this->FlagMap[entry->IDEName] = entry->value;
|
||||
entry_found = true;
|
||||
}
|
||||
|
||||
// If the flag has been handled by an entry not requesting a
|
||||
// search continuation we are done.
|
||||
if(entry_found && !(entry->special & cmVS7FlagTable::Continue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the entry was found the flag has been handled.
|
||||
flag_handled = flag_handled || entry_found;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmLocalVisualStudio7GeneratorOptions
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
// return the source name for the object file
|
||||
virtual std::string GetSourceObjectName(cmSourceFile& );
|
||||
|
||||
void SetExtraFlagTable(cmVS7FlagTable const* table)
|
||||
{ this->ExtraFlagTable = table; }
|
||||
private:
|
||||
typedef cmLocalVisualStudio7GeneratorOptions Options;
|
||||
void ReadAndStoreExternalGUID(const char* name,
|
||||
|
@ -124,11 +126,32 @@ private:
|
|||
const char *libName, std::vector<std::string> *configs);
|
||||
virtual std::string GetTargetDirectory(cmTarget&);
|
||||
|
||||
cmVS7FlagTable const* ExtraFlagTable;
|
||||
std::vector<std::string> CreatedProjectNames;
|
||||
std::string ModuleDefinitionFile;
|
||||
int Version;
|
||||
std::string PlatformName; // Win32 or x64
|
||||
};
|
||||
|
||||
// This is a table mapping XML tag IDE names to command line options
|
||||
struct cmVS7FlagTable
|
||||
{
|
||||
const char* IDEName; // name used in the IDE xml file
|
||||
const char* commandFlag; // command line flag
|
||||
const char* comment; // comment
|
||||
const char* value; // string value
|
||||
unsigned int special; // flags for special handling requests
|
||||
enum
|
||||
{
|
||||
UserValue = (1<<0), // flag contains a user-specified value
|
||||
UserIgnored = (1<<1), // ignore any user value
|
||||
UserRequired = (1<<2), // match only when user value is non-empty
|
||||
Continue = (1<<3), // continue looking for matching entries
|
||||
|
||||
UserValueIgnored = UserValue | UserIgnored,
|
||||
UserValueRequired = UserValue | UserRequired
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -14,9 +14,9 @@ ENDIF(CMAKE_CONFIGURATION_TYPES)
|
|||
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH)
|
||||
|
||||
# Choose between an explicit include path and using /I during
|
||||
# precompilation. The /I form is provided as an example. In practice
|
||||
# the include path form would be used.
|
||||
SET(PCH_USE_INCLUDE_DIR 1)
|
||||
# precompilation. The /I form is used to test that the PCH is
|
||||
# actually used. In practice the include path form would be used.
|
||||
SET(PCH_USE_INCLUDE_DIR 0)
|
||||
IF(PCH_USE_INCLUDE_DIR)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
ELSE(PCH_USE_INCLUDE_DIR)
|
||||
|
|
Loading…
Reference in New Issue