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

View File

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

View File

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

View File

@ -769,6 +769,11 @@ void cmMSDotNETGenerator::WriteConfiguration(std::ostream& fout,
<< "\t\t\t\tInlineFunctionExpansion=\"1\"\n" << "\t\t\t\tInlineFunctionExpansion=\"1\"\n"
<< "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS"; << "\t\t\t\tPreprocessorDefinitions=\"WIN32,NDEBUG,_WINDOWS";
} }
if(target.GetType() == cmTarget::SHARED_LIBRARY
|| target.GetType() == cmTarget::MODULE_LIBRARY)
{
fout << "," << libName << "_EXPORTS";
}
this->OutputDefineFlags(fout); this->OutputDefineFlags(fout);
fout << "\"\n"; fout << "\"\n";
if(m_Makefile->IsOn("CMAKE_CXX_USE_RTTI")) if(m_Makefile->IsOn("CMAKE_CXX_USE_RTTI"))
@ -801,14 +806,41 @@ void cmMSDotNETGenerator::OutputBuildTool(std::ostream& fout,
{ {
case cmTarget::STATIC_LIBRARY: 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" fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLibrarianTool\"\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; break;
} }
case cmTarget::SHARED_LIBRARY: case cmTarget::SHARED_LIBRARY:
case cmTarget::MODULE_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; break;
case cmTarget::EXECUTABLE: case cmTarget::EXECUTABLE:
case cmTarget::WIN32_EXECUTABLE: case cmTarget::WIN32_EXECUTABLE:
@ -843,9 +875,6 @@ void cmMSDotNETGenerator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tStackReserveSize=\"" fout << "\t\t\t\tStackReserveSize=\""
<< m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"/>\n"; << m_Makefile->GetDefinition("CMAKE_CXX_STACK_SIZE") << "\"/>\n";
break; break;
fout << "\t\t\t\tSubSystem=\"2\"\n";
case cmTarget::UTILITY: case cmTarget::UTILITY:
break; break;
} }
@ -961,7 +990,7 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
std::string source = i->GetFullPath(); std::string source = i->GetFullPath();
cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(), cmSourceGroup& sourceGroup = m_Makefile->FindSourceGroup(source.c_str(),
sourceGroups); sourceGroups);
sourceGroup.AddSource(source.c_str()); sourceGroup.AddSource(source.c_str(), &(*i));
} }
// add any custom rules to the source groups // add any custom rules to the source groups
@ -1017,8 +1046,12 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
buildRules.begin(); cc != buildRules.end(); ++ cc) buildRules.begin(); cc != buildRules.end(); ++ cc)
{ {
std::string source = cc->first; 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) if (source != libName || target.GetType() == cmTarget::UTILITY)
{ {
fout << "\t\t\t<File\n"; fout << "\t\t\t<File\n";
@ -1034,7 +1067,21 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
source.c_str()); source.c_str());
this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(), this->WriteCustomRule(fout, source.c_str(), totalCommandStr.c_str(),
totalCommand.m_Depends, 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"; fout << "\t\t\t</File>\n";
} }
@ -1054,10 +1101,11 @@ void cmMSDotNETGenerator::WriteVCProjFile(std::ostream& fout,
void cmMSDotNETGenerator::WriteCustomRule(std::ostream& fout, void cmMSDotNETGenerator::WriteCustomRule(std::ostream& fout,
const char* source, const char* source,
const char* command, const char* command,
const std::set<std::string>& depends, const std::set<std::string>& depends,
const std::set<std::string>& outputs) const std::set<std::string>& outputs,
const char* compileFlags)
{ {
std::string cmd = command; std::string cmd = command;
cmSystemTools::ReplaceString(cmd, "\"", "&quot;"); 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<FileConfiguration\n";
fout << "\t\t\t\t\tName=\"" << *i << "|Win32\">\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" fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"VCCustomBuildTool\"\n" << "\t\t\t\t\tName=\"VCCustomBuildTool\"\n"
<< "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n" << "\t\t\t\t\tCommandLine=\"" << cmd << "\n\"\n"

View File

@ -110,7 +110,8 @@ private:
const char* source, const char* source,
const char* command, const char* command,
const std::set<std::string>& depends, 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, void OutputTargetRules(std::ostream& fout,
const cmTarget &target, const cmTarget &target,

View File

@ -107,10 +107,14 @@ public:
const std::vector<std::string> &GetDepends() const {return m_Depends;} const std::vector<std::string> &GetDepends() const {return m_Depends;}
std::vector<std::string> &GetDepends() {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: private:
bool m_AbstractClass; bool m_AbstractClass;
bool m_WrapExclude; bool m_WrapExclude;
bool m_HeaderFileOnly; bool m_HeaderFileOnly;
std::string m_CompileFlags;
std::string m_FullPath; std::string m_FullPath;
std::string m_SourceName; std::string m_SourceName;
std::string m_SourceExtension; 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. * 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); BuildRules::iterator s = m_BuildRules.find(name);
if(s == m_BuildRules.end()) if(s == m_BuildRules.end())
{ {
SourceAndCommands sc;
sc.m_SourceFile = sf;
// The source was not found. Add it with no commands. // The source was not found. Add it with no commands.
m_BuildRules[name]; m_BuildRules[name] = sc;
return; return;
} }
} }
@ -75,7 +77,8 @@ void cmSourceGroup::AddCustomCommand(const cmCustomCommand &cmd)
if(s == m_BuildRules.end()) if(s == m_BuildRules.end())
{ {
// The source was not found. Add it with this command. // 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_Command = cmd.GetCommand();
cmdFiles.m_Arguments = cmd.GetArguments(); cmdFiles.m_Arguments = cmd.GetArguments();
cmdFiles.m_Depends.insert(cmd.GetDepends().begin(),cmd.GetDepends().end()); 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. // 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); Commands::iterator c = commands.find(commandAndArgs);
if(c == commands.end()) if(c == commands.end())
{ {
@ -113,8 +116,8 @@ void cmSourceGroup::Print() const
i != m_BuildRules.end(); ++i) i != m_BuildRules.end(); ++i)
{ {
std::cout << "BuildRule: " << i->first.c_str() << "\n"; std::cout << "BuildRule: " << i->first.c_str() << "\n";
for(Commands::const_iterator j = i->second.begin(); for(Commands::const_iterator j = i->second.m_Commands.begin();
j != i->second.end(); ++j) j != i->second.m_Commands.end(); ++j)
{ {
std::cout << "FullCommand: " << j->first.c_str() << "\n"; std::cout << "FullCommand: " << j->first.c_str() << "\n";
std::cout << "Command: " << j->second.m_Command.c_str() << "\n"; std::cout << "Command: " << j->second.m_Command.c_str() << "\n";

View File

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

View File

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