ENH: add file specific compile flags

This commit is contained in:
Bill Hoffman 2002-03-04 14:14:41 -05:00
parent 42c56a7cc7
commit 076aafe79a
11 changed files with 250 additions and 34 deletions

View File

@ -65,6 +65,7 @@
#include "cmSetCommand.cxx"
#include "cmSiteNameCommand.cxx"
#include "cmSourceFilesCommand.cxx"
#include "cmSourceFilesFlagsCommand.cxx"
#include "cmSourceFilesRemoveCommand.cxx"
#include "cmSourceGroupCommand.cxx"
#include "cmSubdirCommand.cxx"
@ -130,6 +131,7 @@ void GetPredefinedCommands(std::list<cmCommand*>& commands)
commands.push_back(new cmSetCommand);
commands.push_back(new cmSiteNameCommand);
commands.push_back(new cmSourceFilesCommand);
commands.push_back(new cmSourceFilesFlagsCommand);
commands.push_back(new cmSourceFilesRemoveCommand);
commands.push_back(new cmSourceGroupCommand);
commands.push_back(new cmSubdirCommand);

View File

@ -210,7 +210,7 @@ void cmDSPWriter::WriteDSPFile(std::ostream& fout,
std::string source = i->GetFullPath();
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
sourceGroups);
sourceGroup.AddSource(source.c_str());
sourceGroup.AddSource(source.c_str(), &(*i));
}
// add any custom rules to the source groups
@ -262,8 +262,12 @@ void cmDSPWriter::WriteDSPFile(std::ostream& fout,
buildRules.begin(); cc != buildRules.end(); ++ cc)
{
std::string source = cc->first;
const cmSourceGroup::Commands& commands = cc->second;
const cmSourceGroup::Commands& commands = cc->second.m_Commands;
const char* compileFlags = 0;
if(cc->second.m_SourceFile)
{
compileFlags = cc->second.m_SourceFile->GetCompileFlags();
}
if (source != libName || target.GetType() == cmTarget::UTILITY)
{
fout << "# Begin Source File\n\n";
@ -280,7 +284,24 @@ void cmDSPWriter::WriteDSPFile(std::ostream& fout,
source.c_str());
this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(),
totalCommand.m_Depends,
totalCommand.m_Outputs);
totalCommand.m_Outputs, compileFlags);
}
else if(compileFlags)
{
for(std::vector<std::string>::iterator i
= m_Configurations.begin(); i != m_Configurations.end(); ++i)
{
if (i == m_Configurations.begin())
{
fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl;
}
else
{
fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl;
}
fout << "\n# ADD CPP " << compileFlags << "\n\n";
}
fout << "!ENDIF\n\n";
}
fout << "# End Source File\n";
}
@ -299,10 +320,12 @@ void cmDSPWriter::WriteDSPFile(std::ostream& fout,
void cmDSPWriter::WriteCustomRule(std::ostream& fout,
const char* source,
const char* command,
const std::set<std::string>& depends,
const std::set<std::string>& outputs)
const char* source,
const char* command,
const std::set<std::string>& depends,
const std::set<std::string>& outputs,
const char* flags
)
{
std::vector<std::string>::iterator i;
for(i = m_Configurations.begin(); i != m_Configurations.end(); ++i)
@ -315,7 +338,10 @@ void cmDSPWriter::WriteCustomRule(std::ostream& fout,
{
fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl;
}
if(flags)
{
fout << "\n# ADD CPP " << flags << "\n\n";
}
// Write out the dependencies for the rule.
fout << "USERDEP__HACK=";
for(std::set<std::string>::const_iterator d = depends.begin();

View File

@ -79,7 +79,8 @@ private:
const char* source,
const char* command,
const std::set<std::string>& depends,
const std::set<std::string>& outputs);
const std::set<std::string>& outputs,
const char* flags);
std::string CreateTargetRules(const cmTarget &target,
const char *libName);

View File

@ -769,6 +769,11 @@ void cmMSDotNETGenerator::WriteConfiguration(std::ostream& fout,
<< "\t\t\t\tInlineFunctionExpansion=\"1\"\n"
<< "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";
}
if(target.GetType() == cmTarget::SHARED_LIBRARY
|| target.GetType() == cmTarget::MODULE_LIBRARY)
{
fout << "," << libName << "_EXPORTS";
}
this->OutputDefineFlags(fout);
fout << "\"\n";
if(m_Makefile->IsOn("CMAKE_CXX_USE_RTTI"))
@ -801,14 +806,41 @@ void cmMSDotNETGenerator::OutputBuildTool(std::ostream& fout,
{
case cmTarget::STATIC_LIBRARY:
{
std::string libpath = m_LibraryOutputPath + "$(OutDir)/" + libName + ".lib";
std::string libpath = m_LibraryOutputPath +
"$(OutDir)/" + libName + ".lib";
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLibrarianTool\"\n"
<< "\t\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPath(libpath.c_str()) << ".\"/>\n";
<< "\t\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPath(libpath.c_str()) << ".\"/>\n";
break;
}
case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_LIBRARY:
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLinkerTool\"\n"
<< "\t\t\t\tAdditionalOptions=\"/MACHINE:I386\"\n"
<< "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib ";
this->OutputLibraries(fout, configName, libName, target);
fout << "\"\n";
fout << "\t\t\t\tOutputFile=\""
<< m_ExecutableOutputPath << configName << "/"
<< libName << ".dll\"\n";
fout << "\t\t\t\tLinkIncremental=\"1\"\n";
fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n";
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, configName, libName, target);
fout << "\"\n";
fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath
<< "$(OutDir)\\" << libName << ".pdb\"\n";
if(strcmp(configName, "Debug") == 0)
{
fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n";
}
fout << "\t\t\t\tStackReserveSize=\""
<< m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"\n";
fout << "\t\t\t\tImportLibrary=\""
<< m_ExecutableOutputPath << configName << "/"
<< libName << ".lib\"/>\n";
break;
case cmTarget::EXECUTABLE:
case cmTarget::WIN32_EXECUTABLE:
@ -843,9 +875,6 @@ void cmMSDotNETGenerator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tStackReserveSize=\""
<< m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"/>\n";
break;
fout << "\t\t\t\tSubSystem=\"2\"\n";
case cmTarget::UTILITY:
break;
}
@ -961,7 +990,7 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
std::string source = i->GetFullPath();
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
sourceGroups);
sourceGroup.AddSource(source.c_str());
sourceGroup.AddSource(source.c_str(), &(*i));
}
// add any custom rules to the source groups
@ -1017,8 +1046,12 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
buildRules.begin(); cc != buildRules.end(); ++ cc)
{
std::string source = cc->first;
const cmSourceGroup::Commands& commands = cc->second;
const cmSourceGroup::Commands& commands = cc->second.m_Commands;
const char* compileFlags = 0;
if(cc->second.m_SourceFile)
{
compileFlags = cc->second.m_SourceFile->GetCompileFlags();
}
if (source != libName || target.GetType() == cmTarget::UTILITY)
{
fout << "\t\t\t<File\n";
@ -1034,7 +1067,21 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
source.c_str());
this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(),
totalCommand.m_Depends,
totalCommand.m_Outputs);
totalCommand.m_Outputs, compileFlags);
}
else if(compileFlags)
{
for(std::vector<std::string>::iterator i
= m_Configurations.begin(); i != m_Configurations.end(); ++i)
{
fout << "\t\t\t\t<FileConfiguration\n"
<< "\t\t\t\t\tName=\"" << *i << "|Win32\">\n"
<< "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
<< "\t\t\t\t\tAdditionalOptions=\""
<< compileFlags << "\"/>\n"
<< "\t\t\t\t</FileConfiguration>\n";
}
}
fout << "\t\t\t</File>\n";
}
@ -1054,10 +1101,11 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
void cmMSDotNETGenerator::WriteCustomRule(std::ostream& fout,
const char* source,
const char* command,
const std::set<std::string>& depends,
const std::set<std::string>& outputs)
const char* source,
const char* command,
const std::set<std::string>& depends,
const std::set<std::string>& outputs,
const char* compileFlags)
{
std::string cmd = command;
cmSystemTools::ReplaceString(cmd, "\"", "&quot;");
@ -1066,6 +1114,13 @@ void cmMSDotNETGenerator::WriteCustomRule(std::ostream& fout,
{
fout << "\t\t\t\t<FileConfiguration\n";
fout << "\t\t\t\t\tName=\"" << *i << "|Win32\">\n";
if(compileFlags)
{
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"VCCLCompilerTool\"\n"
<< "\t\t\t\t\tAdditionalOptions=\""
<< compileFlags << "\"/>\n";
}
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"
<< "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n"

View File

@ -110,7 +110,8 @@ private:
const char* source,
const char* command,
const std::set<std::string>& depends,
const std::set<std::string>& outputs);
const std::set<std::string>& outputs,
const char* extraFlags);
void OutputTargetRules(std::ostream& fout,
const cmTarget &target,

View File

@ -107,10 +107,14 @@ public:
const std::vector<std::string> &GetDepends() const {return m_Depends;}
std::vector<std::string> &GetDepends() {return m_Depends;}
///! Set/Get per file compiler flags
void SetCompileFlags(const char* f) { m_CompileFlags = f;}
const char* GetCompileFlags() const { return m_CompileFlags.size() ? m_CompileFlags.c_str(): 0; }
private:
bool m_AbstractClass;
bool m_WrapExclude;
bool m_HeaderFileOnly;
std::string m_CompileFlags;
std::string m_FullPath;
std::string m_SourceName;
std::string m_SourceExtension;

View File

@ -0,0 +1,49 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmSourceFilesFlagsCommand.h"
// cmSourceFilesFlagsCommand
bool cmSourceFilesFlagsCommand::InitialPass(std::vector<std::string> const&
args)
{
if(args.size() < 2 )
{
this->SetError("called with incorrect number of arguments");
return false;
}
cmMakefile::SourceMap &Classes = m_Makefile->GetSources();
std::vector<std::string>::const_iterator j = args.begin();
std::string flags = *j;
++j;
for(;j != args.end(); ++j)
{
for(cmMakefile::SourceMap::iterator l = Classes.begin();
l != Classes.end(); l++)
{
for(std::vector<cmSourceFile>::iterator i = l->second.begin();
i != l->second.end(); i++)
{
if(i->GetSourceName() == (*j))
{
i->SetCompileFlags(flags.c_str());
}
}
}
}
return true;
}

View File

@ -0,0 +1,64 @@
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Insight Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmSourceFilesFlagsCommand_h
#define cmSourceFilesFlagsCommand_h
#include "cmStandardIncludes.h"
#include "cmCommand.h"
class cmSourceFilesFlagsCommand : public cmCommand
{
public:
virtual cmCommand* Clone()
{
return new cmSourceFilesFlagsCommand;
}
/**
* This is called when the command is first encountered in
* the input file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "SOURCE_FILES_FLAGS";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Set compile flags for a specific list of files.";
}
/**
* Longer documentation.
*/
virtual const char* GetFullDocumentation()
{
return
"SOURCE_FILES_FLAGS(flags file1 file2 ..)";
}
cmTypeMacro(cmSourceFilesFlagsCommand, cmCommand);
};
#endif

View File

@ -50,13 +50,15 @@ bool cmSourceGroup::Matches(const char* name)
/**
* Add a source to the group that the compiler will know how to build.
*/
void cmSourceGroup::AddSource(const char* name)
void cmSourceGroup::AddSource(const char* name, const cmSourceFile* sf)
{
BuildRules::iterator s = m_BuildRules.find(name);
if(s == m_BuildRules.end())
{
SourceAndCommands sc;
sc.m_SourceFile = sf;
// The source was not found. Add it with no commands.
m_BuildRules[name];
m_BuildRules[name] = sc;
return;
}
}
@ -75,7 +77,8 @@ void cmSourceGroup::AddCustomCommand(const cmCustomCommand &cmd)
if(s == m_BuildRules.end())
{
// The source was not found. Add it with this command.
CommandFiles& cmdFiles = m_BuildRules[cmd.GetSourceName()][commandAndArgs];
CommandFiles& cmdFiles =
m_BuildRules[cmd.GetSourceName()].m_Commands[commandAndArgs];
cmdFiles.m_Command = cmd.GetCommand();
cmdFiles.m_Arguments = cmd.GetArguments();
cmdFiles.m_Depends.insert(cmd.GetDepends().begin(),cmd.GetDepends().end());
@ -84,7 +87,7 @@ void cmSourceGroup::AddCustomCommand(const cmCustomCommand &cmd)
}
// The source already exists. See if the command exists.
Commands& commands = s->second;
Commands& commands = s->second.m_Commands;
Commands::iterator c = commands.find(commandAndArgs);
if(c == commands.end())
{
@ -113,8 +116,8 @@ void cmSourceGroup::Print() const
i != m_BuildRules.end(); ++i)
{
std::cout << "BuildRule: " << i->first.c_str() << "\n";
for(Commands::const_iterator j = i->second.begin();
j != i->second.end(); ++j)
for(Commands::const_iterator j = i->second.m_Commands.begin();
j != i->second.m_Commands.end(); ++j)
{
std::cout << "FullCommand: " << j->first.c_str() << "\n";
std::cout << "Command: " << j->second.m_Command.c_str() << "\n";

View File

@ -20,7 +20,7 @@
#include "cmStandardIncludes.h"
#include "cmRegularExpression.h"
#include "cmCustomCommand.h"
class cmSourceFile;
/** \class cmSourceGroup
* \brief Hold a group of sources as specified by a SOURCE_GROUP command.
@ -54,15 +54,21 @@ public:
*/
typedef std::map<cmStdString, CommandFiles> Commands;
struct SourceAndCommands
{
SourceAndCommands(): m_SourceFile(0) {}
const cmSourceFile* m_SourceFile;
Commands m_Commands;
};
/**
* Map from source to command map.
*/
typedef std::map<cmStdString, Commands> BuildRules;
typedef std::map<cmStdString, SourceAndCommands> BuildRules;
bool Matches(const char* name);
void SetGroupRegex(const char* regex)
{ m_GroupRegex.compile(regex); }
void AddSource(const char* name);
void AddSource(const char* name, const cmSourceFile*);
void AddCustomCommand(const cmCustomCommand &cmd);
const char* GetName() const
{ return m_Name.c_str(); }

View File

@ -1360,7 +1360,7 @@ void cmUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
buildRules.begin(); cc != buildRules.end(); ++ cc)
{
std::string source = cc->first;
const cmSourceGroup::Commands& commands = cc->second;
const cmSourceGroup::Commands& commands = cc->second.m_Commands;
// Loop through every command generating code from the current source.
for(cmSourceGroup::Commands::const_iterator c = commands.begin();
c != commands.end(); ++c)
@ -1918,6 +1918,11 @@ void cmUnixMakefileGenerator::OutputSourceObjectBuildRules(std::ostream& fout)
// Only output a rule for each .o once.
if(rules.find(shortNameWithExt) == rules.end())
{
if(source->GetCompileFlags())
{
exportsDef += source->GetCompileFlags();
exportsDef += " ";
}
this->OutputBuildObjectFromSource(fout,
shortName.c_str(),
*source,