mirror of
https://github.com/reactos/CMake.git
synced 2024-12-14 23:29:57 +00:00
96afb12087
This converts the CMake license to a pure 3-clause OSI-approved BSD License. We drop the previous license clause requiring modified versions to be plainly marked. We also update the CMake copyright to cover the full development time range.
237 lines
7.7 KiB
C++
237 lines
7.7 KiB
C++
/*============================================================================
|
|
CMake - Cross Platform Makefile Generator
|
|
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
|
|
|
Distributed under the OSI-approved BSD License (the "License");
|
|
see accompanying file Copyright.txt for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the License for more information.
|
|
============================================================================*/
|
|
#include "cmLocalVisualStudioGenerator.h"
|
|
#include "cmGlobalGenerator.h"
|
|
#include "cmMakefile.h"
|
|
#include "cmSourceFile.h"
|
|
#include "cmSystemTools.h"
|
|
#include "windows.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator()
|
|
{
|
|
this->WindowsShell = true;
|
|
this->WindowsVSIDE = true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmsys::auto_ptr<cmCustomCommand>
|
|
cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
|
|
const char* config)
|
|
{
|
|
cmsys::auto_ptr<cmCustomCommand> pcc;
|
|
|
|
// If an executable exports symbols then VS wants to create an
|
|
// import library but forgets to create the output directory.
|
|
if(target.GetType() != cmTarget::EXECUTABLE) { return pcc; }
|
|
std::string outDir = target.GetDirectory(config, false);
|
|
std::string impDir = target.GetDirectory(config, true);
|
|
if(impDir == outDir) { return pcc; }
|
|
|
|
// Add a pre-build event to create the directory.
|
|
cmCustomCommandLine command;
|
|
command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"));
|
|
command.push_back("-E");
|
|
command.push_back("make_directory");
|
|
command.push_back(impDir);
|
|
std::vector<std::string> no_output;
|
|
std::vector<std::string> no_depends;
|
|
cmCustomCommandLines commands;
|
|
commands.push_back(command);
|
|
pcc.reset(new cmCustomCommand(no_output, no_depends, commands, 0, 0));
|
|
pcc->SetEscapeOldStyle(false);
|
|
pcc->SetEscapeAllowMakeVars(true);
|
|
return pcc;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool cmLocalVisualStudioGenerator::SourceFileCompiles(const cmSourceFile* sf)
|
|
{
|
|
// Identify the language of the source file.
|
|
if(const char* lang = this->GetSourceFileLanguage(*sf))
|
|
{
|
|
// Check whether this source will actually be compiled.
|
|
return (!sf->GetCustomCommand() &&
|
|
!sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
|
|
!sf->GetPropertyAsBool("EXTERNAL_OBJECT"));
|
|
}
|
|
else
|
|
{
|
|
// Unknown source file language. Assume it will not be compiled.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmLocalVisualStudioGenerator::CountObjectNames(
|
|
const std::vector<cmSourceGroup>& groups,
|
|
std::map<cmStdString, int>& counts)
|
|
{
|
|
for(unsigned int i = 0; i < groups.size(); ++i)
|
|
{
|
|
cmSourceGroup sg = groups[i];
|
|
std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
|
|
for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
|
|
s != srcs.end(); ++s)
|
|
{
|
|
const cmSourceFile* sf = *s;
|
|
if(this->SourceFileCompiles(sf))
|
|
{
|
|
std::string objectName = cmSystemTools::LowerCase(
|
|
cmSystemTools::GetFilenameWithoutLastExtension(
|
|
sf->GetFullPath()));
|
|
objectName += ".obj";
|
|
counts[objectName] += 1;
|
|
}
|
|
}
|
|
this->CountObjectNames(sg.GetGroupChildren(), counts);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmLocalVisualStudioGenerator::InsertNeedObjectNames(
|
|
const std::vector<cmSourceGroup>& groups,
|
|
std::map<cmStdString, int>& count)
|
|
{
|
|
for(unsigned int i = 0; i < groups.size(); ++i)
|
|
{
|
|
cmSourceGroup sg = groups[i];
|
|
std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
|
|
for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
|
|
s != srcs.end(); ++s)
|
|
{
|
|
const cmSourceFile* sf = *s;
|
|
if(this->SourceFileCompiles(sf))
|
|
{
|
|
std::string objectName = cmSystemTools::LowerCase(
|
|
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
|
|
objectName += ".obj";
|
|
if(count[objectName] > 1)
|
|
{
|
|
this->NeedObjectName.insert(sf);
|
|
}
|
|
}
|
|
}
|
|
this->InsertNeedObjectNames(sg.GetGroupChildren(), count);
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmLocalVisualStudioGenerator::ComputeObjectNameRequirements
|
|
(std::vector<cmSourceGroup> const& sourceGroups)
|
|
{
|
|
// Clear the current set of requirements.
|
|
this->NeedObjectName.clear();
|
|
|
|
// Count the number of object files with each name. Note that
|
|
// windows file names are not case sensitive.
|
|
std::map<cmStdString, int> objectNameCounts;
|
|
this->CountObjectNames(sourceGroups, objectNameCounts);
|
|
|
|
// For all source files producing duplicate names we need unique
|
|
// object name computation.
|
|
this->InsertNeedObjectNames(sourceGroups, objectNameCounts);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
std::string
|
|
cmLocalVisualStudioGenerator
|
|
::ConstructScript(const cmCustomCommandLines& commandLines,
|
|
const char* workingDirectory,
|
|
const char* configName,
|
|
bool escapeOldStyle,
|
|
bool escapeAllowMakeVars,
|
|
const char* newline_text)
|
|
{
|
|
// Avoid leading or trailing newlines.
|
|
const char* newline = "";
|
|
|
|
// Store the script in a string.
|
|
std::string script;
|
|
if(workingDirectory)
|
|
{
|
|
// Change the working directory.
|
|
script += newline;
|
|
newline = newline_text;
|
|
script += "cd ";
|
|
script += this->Convert(workingDirectory, START_OUTPUT, SHELL);
|
|
|
|
// Change the working drive.
|
|
if(workingDirectory[0] && workingDirectory[1] == ':')
|
|
{
|
|
script += newline;
|
|
newline = newline_text;
|
|
script += workingDirectory[0];
|
|
script += workingDirectory[1];
|
|
}
|
|
}
|
|
// for visual studio IDE add extra stuff to the PATH
|
|
// if CMAKE_MSVCIDE_RUN_PATH is set.
|
|
if(this->Makefile->GetDefinition("MSVC_IDE"))
|
|
{
|
|
const char* extraPath =
|
|
this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
|
|
if(extraPath)
|
|
{
|
|
script += newline;
|
|
newline = newline_text;
|
|
script += "set PATH=";
|
|
script += extraPath;
|
|
script += ";%PATH%";
|
|
}
|
|
}
|
|
// Write each command on a single line.
|
|
for(cmCustomCommandLines::const_iterator cl = commandLines.begin();
|
|
cl != commandLines.end(); ++cl)
|
|
{
|
|
// Start a new line.
|
|
script += newline;
|
|
newline = newline_text;
|
|
|
|
// Start with the command name.
|
|
const cmCustomCommandLine& commandLine = *cl;
|
|
std::string commandName = this->GetRealLocation(commandLine[0].c_str(),
|
|
configName);
|
|
if(!workingDirectory)
|
|
{
|
|
script += this->Convert(commandName.c_str(),START_OUTPUT,SHELL);
|
|
}
|
|
else
|
|
{
|
|
script += this->Convert(commandName.c_str(),NONE,SHELL);
|
|
}
|
|
|
|
// Add the arguments.
|
|
for(unsigned int j=1;j < commandLine.size(); ++j)
|
|
{
|
|
script += " ";
|
|
if(escapeOldStyle)
|
|
{
|
|
script += this->EscapeForShellOldStyle(commandLine[j].c_str());
|
|
}
|
|
else
|
|
{
|
|
script += this->EscapeForShell(commandLine[j].c_str(),
|
|
escapeAllowMakeVars);
|
|
}
|
|
}
|
|
}
|
|
return script;
|
|
}
|
|
|