Merge topic 'object-library'
93d5509
Merge branch 'ninja-object-library' into object-library821037c
Merge branch 'xcode-object-library' into object-libraryeb24c99
Merge branch 'object-library' into xcode-object-library63d1be8
Xcode: Honor $<TARGET_OBJECTS:...> source expressions020ba38
Merge branch 'object-library' into xcode-object-librarye8ea615
Build object library targets in Xcode8045e17
Pre-compute object file names before Xcode generation247a132
Allow txt files as ExtraSources in object library targetsb063599
Add a default source group for object files.be01f3b
Xcode: Re-factor some existing methods into "FromPath" variants2693dbe
Merge branch 'object-library' into ninja-object-library51997cb
Ninja: Honor $<TARGET_OBJECTS:...> source expressions23ec258
Merge branch 'object-library' into ninja-object-library61124de
Build object library targets in Ninjaf5b06cd
Pre-compute object file names before Ninja generationa2514f1
Simplify cmNinjaTargetGenerator using cmGeneratorTarget ...
This commit is contained in:
commit
31c0bc0219
|
@ -185,6 +185,8 @@ SET(SRCS
|
|||
cmGeneratedFileStream.cxx
|
||||
cmGeneratorExpression.cxx
|
||||
cmGeneratorExpression.h
|
||||
cmGeneratorTarget.cxx
|
||||
cmGeneratorTarget.h
|
||||
cmGlobalGenerator.cxx
|
||||
cmGlobalGenerator.h
|
||||
cmGlobalUnixMakefileGenerator3.cxx
|
||||
|
|
|
@ -64,6 +64,12 @@ bool cmAddLibraryCommand
|
|||
type = cmTarget::MODULE_LIBRARY;
|
||||
haveSpecifiedType = true;
|
||||
}
|
||||
else if(libType == "OBJECT")
|
||||
{
|
||||
++s;
|
||||
type = cmTarget::OBJECT_LIBRARY;
|
||||
haveSpecifiedType = true;
|
||||
}
|
||||
else if(libType == "UNKNOWN")
|
||||
{
|
||||
++s;
|
||||
|
@ -118,6 +124,14 @@ bool cmAddLibraryCommand
|
|||
this->SetError("called with IMPORTED argument but no library type.");
|
||||
return false;
|
||||
}
|
||||
if(type == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
this->Makefile->IssueMessage(
|
||||
cmake::FATAL_ERROR,
|
||||
"The OBJECT library type may not be used for IMPORTED libraries."
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure the target does not already exist.
|
||||
if(this->Makefile->FindTargetToUse(libName.c_str()))
|
||||
|
|
|
@ -112,6 +112,26 @@ public:
|
|||
"(and its per-configuration version IMPORTED_LOCATION_<CONFIG>) "
|
||||
"which specifies the location of the main library file on disk. "
|
||||
"See documentation of the IMPORTED_* properties for more information."
|
||||
"\n"
|
||||
"The signature\n"
|
||||
" add_library(<name> OBJECT <src>...)\n"
|
||||
"creates a special \"object library\" target. "
|
||||
"An object library compiles source files but does not archive or link "
|
||||
"their object files into a library. "
|
||||
"Instead other targets created by add_library or add_executable may "
|
||||
"reference the objects using an expression of the form "
|
||||
"$<TARGET_OBJECTS:objlib> as a source, where \"objlib\" is the "
|
||||
"object library name. "
|
||||
"For example:\n"
|
||||
" add_library(... $<TARGET_OBJECTS:objlib> ...)\n"
|
||||
" add_executable(... $<TARGET_OBJECTS:objlib> ...)\n"
|
||||
"will include objlib's object files in a library and an executable "
|
||||
"along with those compiled from their own sources. "
|
||||
"Object libraries may contain only sources (and headers) that compile "
|
||||
"to object files. "
|
||||
"They may contain custom commands generating such sources, but not "
|
||||
"PRE_BUILD, PRE_LINK, or POST_BUILD commands. "
|
||||
"Object libraries cannot be imported, exported, installed, or linked."
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -633,6 +633,19 @@ cmTarget* cmComputeLinkDepends::FindTargetToLink(int depender_index,
|
|||
tgt = 0;
|
||||
}
|
||||
|
||||
if(tgt && tgt->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << this->Target->GetName() << "\" links to "
|
||||
"OBJECT library \"" << tgt->GetName() << "\" but this is not "
|
||||
"allowed. "
|
||||
"One may link only to STATIC or SHARED libraries, or to executables "
|
||||
"with the ENABLE_EXPORTS property set.";
|
||||
this->CMakeInstance->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||
this->Target->GetBacktrace());
|
||||
tgt = 0;
|
||||
}
|
||||
|
||||
// Return the target found, if any.
|
||||
return tgt;
|
||||
}
|
||||
|
|
|
@ -124,6 +124,14 @@ bool cmExportCommand
|
|||
{
|
||||
targets.push_back(target);
|
||||
}
|
||||
else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "given OBJECT library \"" << *currentTarget
|
||||
<< "\" which may not be exported.";
|
||||
this->SetError(e.str().c_str());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2012 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 "cmGeneratorTarget.h"
|
||||
|
||||
#include "cmTarget.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmSourceFile.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
|
||||
{
|
||||
this->Makefile = this->Target->GetMakefile();
|
||||
this->LocalGenerator = this->Makefile->GetLocalGenerator();
|
||||
this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator();
|
||||
this->ClassifySources();
|
||||
this->LookupObjectLibraries();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorTarget::ClassifySources()
|
||||
{
|
||||
bool isObjLib = this->Target->GetType() == cmTarget::OBJECT_LIBRARY;
|
||||
std::vector<cmSourceFile*> badObjLib;
|
||||
std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
|
||||
si != sources.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *si;
|
||||
cmTarget::SourceFileFlags tsFlags =
|
||||
this->Target->GetTargetSourceFileFlags(sf);
|
||||
if(sf->GetCustomCommand())
|
||||
{
|
||||
this->CustomCommands.push_back(sf);
|
||||
}
|
||||
else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
|
||||
{
|
||||
this->OSXContent.push_back(sf);
|
||||
if(isObjLib) { badObjLib.push_back(sf); }
|
||||
}
|
||||
else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
||||
{
|
||||
this->HeaderSources.push_back(sf);
|
||||
}
|
||||
else if(sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
||||
{
|
||||
this->ExternalObjects.push_back(sf);
|
||||
if(isObjLib) { badObjLib.push_back(sf); }
|
||||
}
|
||||
else if(cmSystemTools::LowerCase(sf->GetExtension()) == "def")
|
||||
{
|
||||
this->ModuleDefinitionFile = sf->GetFullPath();
|
||||
if(isObjLib) { badObjLib.push_back(sf); }
|
||||
}
|
||||
else if(this->GlobalGenerator->IgnoreFile(sf->GetExtension().c_str()))
|
||||
{
|
||||
// We only get here if a source file is not an external object
|
||||
// and has an extension that is listed as an ignored file type.
|
||||
// No message or diagnosis should be given.
|
||||
}
|
||||
else if(sf->GetLanguage())
|
||||
{
|
||||
this->ObjectSources.push_back(sf);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ExtraSources.push_back(sf);
|
||||
if(isObjLib && cmSystemTools::LowerCase(sf->GetExtension()) != "txt")
|
||||
{
|
||||
badObjLib.push_back(sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!badObjLib.empty())
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "OBJECT library \"" << this->Target->GetName() << "\" contains:\n";
|
||||
for(std::vector<cmSourceFile*>::iterator i = badObjLib.begin();
|
||||
i != badObjLib.end(); ++i)
|
||||
{
|
||||
e << " " << (*i)->GetLocation().GetName() << "\n";
|
||||
}
|
||||
e << "but may contain only headers and sources that compile.";
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||
this->Target->GetBacktrace());
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorTarget::LookupObjectLibraries()
|
||||
{
|
||||
std::vector<std::string> const& objLibs =
|
||||
this->Target->GetObjectLibraries();
|
||||
for(std::vector<std::string>::const_iterator oli = objLibs.begin();
|
||||
oli != objLibs.end(); ++oli)
|
||||
{
|
||||
std::string const& objLibName = *oli;
|
||||
if(cmTarget* objLib = this->Makefile->FindTargetToUse(objLibName.c_str()))
|
||||
{
|
||||
if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
if(this->Target->GetType() != cmTarget::EXECUTABLE &&
|
||||
this->Target->GetType() != cmTarget::STATIC_LIBRARY &&
|
||||
this->Target->GetType() != cmTarget::SHARED_LIBRARY &&
|
||||
this->Target->GetType() != cmTarget::MODULE_LIBRARY)
|
||||
{
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR,
|
||||
"Only executables and non-OBJECT libraries may "
|
||||
"reference target objects.",
|
||||
this->Target->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
this->Target->AddUtility(objLib->GetName());
|
||||
this->ObjectLibraries.push_back(objLib);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Objects of target \"" << objLibName
|
||||
<< "\" referenced but is not an OBJECT library.";
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||
this->Target->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Objects of target \"" << objLibName
|
||||
<< "\" referenced but no such target exists.";
|
||||
this->GlobalGenerator->GetCMakeInstance()
|
||||
->IssueMessage(cmake::FATAL_ERROR, e.str(),
|
||||
this->Target->GetBacktrace());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGeneratorTarget::UseObjectLibraries(std::vector<std::string>& objs)
|
||||
{
|
||||
for(std::vector<cmTarget*>::const_iterator
|
||||
ti = this->ObjectLibraries.begin();
|
||||
ti != this->ObjectLibraries.end(); ++ti)
|
||||
{
|
||||
cmTarget* objLib = *ti;
|
||||
cmGeneratorTarget* ogt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(objLib);
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = ogt->ObjectSources.begin();
|
||||
si != ogt->ObjectSources.end(); ++si)
|
||||
{
|
||||
std::string obj = ogt->ObjectDirectory;
|
||||
obj += ogt->Objects[*si];
|
||||
objs.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*============================================================================
|
||||
CMake - Cross Platform Makefile Generator
|
||||
Copyright 2000-2012 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.
|
||||
============================================================================*/
|
||||
#ifndef cmGeneratorTarget_h
|
||||
#define cmGeneratorTarget_h
|
||||
|
||||
#include "cmStandardIncludes.h"
|
||||
|
||||
class cmCustomCommand;
|
||||
class cmGlobalGenerator;
|
||||
class cmLocalGenerator;
|
||||
class cmMakefile;
|
||||
class cmSourceFile;
|
||||
class cmTarget;
|
||||
|
||||
class cmGeneratorTarget
|
||||
{
|
||||
public:
|
||||
cmGeneratorTarget(cmTarget*);
|
||||
|
||||
cmTarget* Target;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalGenerator* LocalGenerator;
|
||||
cmGlobalGenerator* GlobalGenerator;
|
||||
|
||||
/** Sources classified by purpose. */
|
||||
std::vector<cmSourceFile*> CustomCommands;
|
||||
std::vector<cmSourceFile*> ExtraSources;
|
||||
std::vector<cmSourceFile*> HeaderSources;
|
||||
std::vector<cmSourceFile*> ObjectSources;
|
||||
std::vector<cmSourceFile*> ExternalObjects;
|
||||
std::vector<cmSourceFile*> OSXContent;
|
||||
std::string ModuleDefinitionFile;
|
||||
|
||||
std::map<cmSourceFile const*, std::string> Objects;
|
||||
std::set<cmSourceFile const*> ExplicitObjectName;
|
||||
|
||||
/** Full path with trailing slash to the top-level directory
|
||||
holding object files for this target. Includes the build
|
||||
time config name placeholder if needed for the generator. */
|
||||
std::string ObjectDirectory;
|
||||
|
||||
std::vector<cmTarget*> ObjectLibraries;
|
||||
|
||||
void UseObjectLibraries(std::vector<std::string>& objs);
|
||||
|
||||
private:
|
||||
void ClassifySources();
|
||||
void LookupObjectLibraries();
|
||||
|
||||
cmGeneratorTarget(cmGeneratorTarget const&);
|
||||
void operator=(cmGeneratorTarget const&);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,6 +24,7 @@
|
|||
#include "cmExportInstallFileGenerator.h"
|
||||
#include "cmComputeTargetDepends.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
|
||||
#include <cmsys/Directory.hxx>
|
||||
|
||||
|
@ -74,6 +75,7 @@ cmGlobalGenerator::~cmGlobalGenerator()
|
|||
delete this->ExtraGenerator;
|
||||
}
|
||||
|
||||
this->ClearGeneratorTargets();
|
||||
this->ClearExportSets();
|
||||
}
|
||||
|
||||
|
@ -807,6 +809,7 @@ bool cmGlobalGenerator::IsDependedOn(const char* project,
|
|||
void cmGlobalGenerator::Configure()
|
||||
{
|
||||
this->FirstTimeProgress = 0.0f;
|
||||
this->ClearGeneratorTargets();
|
||||
this->ClearExportSets();
|
||||
// Delete any existing cmLocalGenerators
|
||||
unsigned int i;
|
||||
|
@ -947,6 +950,9 @@ void cmGlobalGenerator::Generate()
|
|||
this->LocalGenerators[i]->GenerateTargetManifest();
|
||||
}
|
||||
|
||||
// Create per-target generator information.
|
||||
this->CreateGeneratorTargets();
|
||||
|
||||
// Compute the inter-target dependencies.
|
||||
if(!this->ComputeTargetDepends())
|
||||
{
|
||||
|
@ -1056,6 +1062,55 @@ void cmGlobalGenerator::CreateAutomocTargets()
|
|||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::CreateGeneratorTargets()
|
||||
{
|
||||
// Construct per-target generator information.
|
||||
for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
|
||||
{
|
||||
cmTargets& targets =
|
||||
this->LocalGenerators[i]->GetMakefile()->GetTargets();
|
||||
for(cmTargets::iterator ti = targets.begin();
|
||||
ti != targets.end(); ++ti)
|
||||
{
|
||||
cmTarget* t = &ti->second;
|
||||
cmGeneratorTarget* gt = new cmGeneratorTarget(t);
|
||||
this->GeneratorTargets[t] = gt;
|
||||
this->ComputeTargetObjects(gt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::ClearGeneratorTargets()
|
||||
{
|
||||
for(GeneratorTargetsType::iterator i = this->GeneratorTargets.begin();
|
||||
i != this->GeneratorTargets.end(); ++i)
|
||||
{
|
||||
delete i->second;
|
||||
}
|
||||
this->GeneratorTargets.clear();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmGeneratorTarget* cmGlobalGenerator::GetGeneratorTarget(cmTarget* t) const
|
||||
{
|
||||
GeneratorTargetsType::const_iterator ti = this->GeneratorTargets.find(t);
|
||||
if(ti == this->GeneratorTargets.end())
|
||||
{
|
||||
this->CMakeInstance->IssueMessage(
|
||||
cmake::INTERNAL_ERROR, "Missing cmGeneratorTarget instance!",
|
||||
cmListFileBacktrace());
|
||||
return 0;
|
||||
}
|
||||
return ti->second;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::ComputeTargetObjects(cmGeneratorTarget*) const
|
||||
{
|
||||
// Implemented in generator subclasses that need this.
|
||||
}
|
||||
|
||||
void cmGlobalGenerator::CheckLocalGenerators()
|
||||
{
|
||||
|
@ -1714,7 +1769,7 @@ void cmGlobalGenerator::SetCMakeInstance(cmake* cm)
|
|||
void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
|
||||
{
|
||||
cmMakefile* mf = this->LocalGenerators[0]->GetMakefile();
|
||||
const char* cmakeCfgIntDir = this->GetCMakeCFGInitDirectory();
|
||||
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
|
||||
const char* cmakeCommand = mf->GetRequiredDefinition("CMAKE_COMMAND");
|
||||
|
||||
// CPack
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "cmTargetDepend.h" // For cmTargetDependSet
|
||||
#include "cmSystemTools.h" // for cmSystemTools::OutputOption
|
||||
class cmake;
|
||||
class cmGeneratorTarget;
|
||||
class cmMakefile;
|
||||
class cmLocalGenerator;
|
||||
class cmExternalMakefileProjectGenerator;
|
||||
|
@ -183,7 +184,7 @@ public:
|
|||
const char* GetLanguageOutputExtension(cmSourceFile const&);
|
||||
|
||||
///! What is the configurations directory variable called?
|
||||
virtual const char* GetCMakeCFGInitDirectory() { return "."; }
|
||||
virtual const char* GetCMakeCFGIntDir() const { return "."; }
|
||||
|
||||
/** Get whether the generator should use a script for link commands. */
|
||||
bool GetUseLinkScript() const { return this->UseLinkScript; }
|
||||
|
@ -251,6 +252,9 @@ public:
|
|||
// via a target_link_libraries or add_dependencies
|
||||
TargetDependSet const& GetTargetDirectDepends(cmTarget & target);
|
||||
|
||||
/** Get per-target generator information. */
|
||||
cmGeneratorTarget* GetGeneratorTarget(cmTarget*) const;
|
||||
|
||||
const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap()
|
||||
const {return this->ProjectMap;}
|
||||
|
||||
|
@ -370,6 +374,13 @@ private:
|
|||
typedef std::map<cmTarget *, TargetDependSet> TargetDependMap;
|
||||
TargetDependMap TargetDependencies;
|
||||
|
||||
// Per-target generator information.
|
||||
typedef std::map<cmTarget*, cmGeneratorTarget*> GeneratorTargetsType;
|
||||
GeneratorTargetsType GeneratorTargets;
|
||||
void CreateGeneratorTargets();
|
||||
void ClearGeneratorTargets();
|
||||
virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||
|
||||
// Cache directory content and target files to be built.
|
||||
struct DirectoryContent: public std::set<cmStdString>
|
||||
{
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "cmLocalNinjaGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmVersion.h"
|
||||
|
||||
const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
|
||||
|
@ -499,6 +500,34 @@ bool cmGlobalNinjaGenerator::HasRule(const std::string &name)
|
|||
return (rule != this->Rules.end());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Private virtual overrides
|
||||
|
||||
// TODO: Refactor to combine with cmGlobalUnixMakefileGenerator3 impl.
|
||||
void cmGlobalNinjaGenerator::ComputeTargetObjects(cmGeneratorTarget* gt) const
|
||||
{
|
||||
cmTarget* target = gt->Target;
|
||||
|
||||
// Compute full path to object file directory for this target.
|
||||
std::string dir_max;
|
||||
dir_max += gt->Makefile->GetCurrentOutputDirectory();
|
||||
dir_max += "/";
|
||||
dir_max += gt->LocalGenerator->GetTargetDirectory(*target);
|
||||
dir_max += "/";
|
||||
gt->ObjectDirectory = dir_max;
|
||||
|
||||
// Compute the name of each object file.
|
||||
for(std::vector<cmSourceFile*>::iterator
|
||||
si = gt->ObjectSources.begin();
|
||||
si != gt->ObjectSources.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *si;
|
||||
std::string objectName = gt->LocalGenerator
|
||||
->GetObjectFileNameWithoutTarget(*sf, dir_max);
|
||||
gt->Objects[sf] = objectName;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Private methods
|
||||
|
||||
|
@ -635,6 +664,7 @@ cmGlobalNinjaGenerator
|
|||
target->GetFullPath(configName).c_str()));
|
||||
break;
|
||||
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
case cmTarget::UTILITY: {
|
||||
std::string path = ng->ConvertToNinjaPath(
|
||||
target->GetMakefile()->GetStartOutputDirectory());
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
class cmLocalGenerator;
|
||||
class cmGeneratedFileStream;
|
||||
class cmGeneratorTarget;
|
||||
|
||||
/**
|
||||
* \class cmGlobalNinjaGenerator
|
||||
|
@ -235,6 +236,11 @@ protected:
|
|||
/// @see cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
|
||||
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
|
||||
|
||||
private:
|
||||
|
||||
/// @see cmGlobalGenerator::ComputeTargetObjects
|
||||
virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||
|
||||
private:
|
||||
// In order to access the AddDependencyToAll() functions and co.
|
||||
friend class cmLocalNinjaGenerator;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
|
||||
cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
|
||||
{
|
||||
|
@ -70,6 +71,38 @@ void cmGlobalUnixMakefileGenerator3
|
|||
"default make target. A \"make install\" target is also provided.";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmGlobalUnixMakefileGenerator3
|
||||
::ComputeTargetObjects(cmGeneratorTarget* gt) const
|
||||
{
|
||||
cmTarget* target = gt->Target;
|
||||
cmLocalUnixMakefileGenerator3* lg =
|
||||
static_cast<cmLocalUnixMakefileGenerator3*>(gt->LocalGenerator);
|
||||
|
||||
// Compute full path to object file directory for this target.
|
||||
std::string dir_max;
|
||||
dir_max += gt->Makefile->GetCurrentOutputDirectory();
|
||||
dir_max += "/";
|
||||
dir_max += gt->LocalGenerator->GetTargetDirectory(*target);
|
||||
dir_max += "/";
|
||||
gt->ObjectDirectory = dir_max;
|
||||
|
||||
// Compute the name of each object file.
|
||||
for(std::vector<cmSourceFile*>::iterator
|
||||
si = gt->ObjectSources.begin();
|
||||
si != gt->ObjectSources.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *si;
|
||||
bool hasSourceExtension = true;
|
||||
std::string objectName = gt->LocalGenerator
|
||||
->GetObjectFileNameWithoutTarget(*sf, dir_max,
|
||||
&hasSourceExtension);
|
||||
gt->Objects[sf] = objectName;
|
||||
lg->AddLocalObjectFile(target, sf, objectName, hasSourceExtension);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string EscapeJSON(const std::string& s) {
|
||||
std::string result;
|
||||
|
@ -378,6 +411,7 @@ void cmGlobalUnixMakefileGenerator3
|
|||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::UTILITY))
|
||||
{
|
||||
std::string tname = lg->GetRelativeTargetDirectory(l->second);
|
||||
|
@ -413,6 +447,7 @@ cmGlobalUnixMakefileGenerator3
|
|||
(l->second.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::MODULE_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
|
||||
(l->second.GetType() == cmTarget::UTILITY))
|
||||
{
|
||||
// Add this to the list of depends rules in this directory.
|
||||
|
@ -587,6 +622,7 @@ cmGlobalUnixMakefileGenerator3
|
|||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::UTILITY)))
|
||||
{
|
||||
// Add a rule to build the target by name.
|
||||
|
@ -673,6 +709,7 @@ cmGlobalUnixMakefileGenerator3
|
|||
|| (t->second.GetType() == cmTarget::STATIC_LIBRARY)
|
||||
|| (t->second.GetType() == cmTarget::SHARED_LIBRARY)
|
||||
|| (t->second.GetType() == cmTarget::MODULE_LIBRARY)
|
||||
|| (t->second.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
|| (t->second.GetType() == cmTarget::UTILITY)))
|
||||
{
|
||||
std::string makefileName;
|
||||
|
@ -982,6 +1019,7 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule
|
|||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::GLOBAL_TARGET) ||
|
||||
(t->second.GetType() == cmTarget::UTILITY))
|
||||
{
|
||||
|
|
|
@ -182,6 +182,8 @@ protected:
|
|||
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
|
||||
|
||||
cmGeneratedFileStream *CommandDatabase;
|
||||
private:
|
||||
virtual void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
* Studio?
|
||||
*/
|
||||
virtual std::string GetUserMacrosRegKeyBase();
|
||||
virtual const char* GetCMakeCFGInitDirectory()
|
||||
virtual const char* GetCMakeCFGIntDir() const
|
||||
{ return "$(Configuration)";}
|
||||
bool Find64BitTools(cmMakefile* mf);
|
||||
protected:
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
std::string& dir);
|
||||
|
||||
///! What is the configurations directory variable called?
|
||||
virtual const char* GetCMakeCFGInitDirectory() { return "$(IntDir)"; }
|
||||
virtual const char* GetCMakeCFGIntDir() const { return "$(IntDir)"; }
|
||||
|
||||
protected:
|
||||
virtual const char* GetIDEVersion() { return "6.0"; }
|
||||
|
|
|
@ -87,7 +87,7 @@ public:
|
|||
std::string& dir);
|
||||
|
||||
///! What is the configurations directory variable called?
|
||||
virtual const char* GetCMakeCFGInitDirectory() { return "$(OutDir)"; }
|
||||
virtual const char* GetCMakeCFGIntDir() const { return "$(OutDir)"; }
|
||||
|
||||
/** Return true if the target project file should have the option
|
||||
LinkLibraryDependencies and link to .sln dependencies. */
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#include "cmGlobalVisualStudioGenerator.h"
|
||||
|
||||
#include "cmCallVisualStudioMacro.h"
|
||||
#include "cmLocalGenerator.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmLocalVisualStudioGenerator.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmTarget.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -97,6 +99,64 @@ void cmGlobalVisualStudioGenerator::Generate()
|
|||
this->cmGlobalGenerator::Generate();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmGlobalVisualStudioGenerator
|
||||
::ComputeTargetObjects(cmGeneratorTarget* gt) const
|
||||
{
|
||||
cmLocalVisualStudioGenerator* lg =
|
||||
static_cast<cmLocalVisualStudioGenerator*>(gt->LocalGenerator);
|
||||
std::string dir_max = lg->ComputeLongestObjectDirectory(*gt->Target);
|
||||
|
||||
// Count the number of object files with each name. Note that
|
||||
// windows file names are not case sensitive.
|
||||
std::map<cmStdString, int> counts;
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = gt->ObjectSources.begin();
|
||||
si != gt->ObjectSources.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *si;
|
||||
std::string objectNameLower = cmSystemTools::LowerCase(
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
|
||||
objectNameLower += ".obj";
|
||||
counts[objectNameLower] += 1;
|
||||
}
|
||||
|
||||
// For all source files producing duplicate names we need unique
|
||||
// object name computation.
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = gt->ObjectSources.begin();
|
||||
si != gt->ObjectSources.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *si;
|
||||
std::string objectName =
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
|
||||
objectName += ".obj";
|
||||
if(counts[cmSystemTools::LowerCase(objectName)] > 1)
|
||||
{
|
||||
gt->ExplicitObjectName.insert(sf);
|
||||
objectName = lg->GetObjectFileNameWithoutTarget(*sf, dir_max);
|
||||
}
|
||||
gt->Objects[sf] = objectName;
|
||||
}
|
||||
|
||||
std::string dir = gt->Makefile->GetCurrentOutputDirectory();
|
||||
dir += "/";
|
||||
std::string tgtDir = lg->GetTargetDirectory(*gt->Target);
|
||||
if(!tgtDir.empty())
|
||||
{
|
||||
dir += tgtDir;
|
||||
dir += "/";
|
||||
}
|
||||
const char* cd = this->GetCMakeCFGIntDir();
|
||||
if(cd && *cd)
|
||||
{
|
||||
dir += cd;
|
||||
dir += "/";
|
||||
}
|
||||
gt->ObjectDirectory = dir;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
|
||||
const std::string& regKeyBase,
|
||||
|
@ -314,6 +374,12 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
|
|||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool VSLinkable(cmTarget* t)
|
||||
{
|
||||
return t->IsLinkable() || t->GetType() == cmTarget::OBJECT_LIBRARY;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
|
||||
{
|
||||
|
@ -398,7 +464,7 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
|
|||
di != utilDepends.end(); ++di)
|
||||
{
|
||||
cmTarget* dep = *di;
|
||||
if(allowLinkable || !dep->IsLinkable() || linked.count(dep))
|
||||
if(allowLinkable || !VSLinkable(dep) || linked.count(dep))
|
||||
{
|
||||
// Direct dependency allowed.
|
||||
vsTargetDepend.insert(dep->GetName());
|
||||
|
|
|
@ -97,6 +97,8 @@ protected:
|
|||
typedef std::map<cmTarget*, cmStdString> UtilityDependsMap;
|
||||
UtilityDependsMap UtilityDepends;
|
||||
private:
|
||||
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||
|
||||
void FollowLinkDepends(cmTarget* target, std::set<cmTarget*>& linked);
|
||||
|
||||
class TargetSetMap: public std::map<cmTarget*, TargetSet> {};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmCustomCommandGenerator.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
|
||||
#include <cmsys/auto_ptr.hxx>
|
||||
|
||||
|
@ -303,6 +304,10 @@ void cmGlobalXCodeGenerator::Generate()
|
|||
}
|
||||
this->ForceLinkerLanguages();
|
||||
this->cmGlobalGenerator::Generate();
|
||||
if(cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
|
||||
{
|
||||
cmLocalGenerator* root = it->second[0];
|
||||
|
@ -417,6 +422,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root,
|
|||
// this will make sure that when the next target is built
|
||||
// things are up-to-date
|
||||
if((target.GetType() == cmTarget::EXECUTABLE ||
|
||||
// Nope - no post-build for OBJECT_LIRBRARY
|
||||
// target.GetType() == cmTarget::OBJECT_LIBRARY ||
|
||||
target.GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
target.GetType() == cmTarget::MODULE_LIBRARY))
|
||||
|
@ -570,14 +577,42 @@ cmXCodeObject* cmGlobalXCodeGenerator
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmStdString GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
|
||||
cmStdString
|
||||
GetGroupMapKeyFromPath(cmTarget& cmtarget, const std::string& fullpath)
|
||||
{
|
||||
cmStdString key(cmtarget.GetName());
|
||||
key += "-";
|
||||
key += sf->GetFullPath();
|
||||
key += fullpath;
|
||||
return key;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmStdString
|
||||
GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf)
|
||||
{
|
||||
return GetGroupMapKeyFromPath(cmtarget, sf->GetFullPath());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmXCodeObject*
|
||||
cmGlobalXCodeGenerator::CreateXCodeSourceFileFromPath(
|
||||
const std::string &fullpath,
|
||||
cmTarget& cmtarget,
|
||||
const std::string &lang)
|
||||
{
|
||||
// Using a map and the full path guarantees that we will always get the same
|
||||
// fileRef object for any given full path.
|
||||
//
|
||||
cmXCodeObject* fileRef =
|
||||
this->CreateXCodeFileReferenceFromPath(fullpath, cmtarget, lang);
|
||||
|
||||
cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
|
||||
buildFile->SetComment(fileRef->GetComment());
|
||||
buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
|
||||
|
||||
return buildFile;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmXCodeObject*
|
||||
cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
|
||||
|
@ -612,14 +647,16 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
|
|||
flags += flagsBuild.GetString();
|
||||
}
|
||||
|
||||
// Using a map and the full path guarantees that we will always get the same
|
||||
// fileRef object for any given full path.
|
||||
//
|
||||
cmXCodeObject* fileRef = this->CreateXCodeFileReference(sf, cmtarget);
|
||||
const char* lang =
|
||||
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
|
||||
if (!lang)
|
||||
{
|
||||
lang = "";
|
||||
}
|
||||
|
||||
cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile);
|
||||
buildFile->SetComment(fileRef->GetComment());
|
||||
buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef));
|
||||
cmXCodeObject* buildFile =
|
||||
this->CreateXCodeSourceFileFromPath(sf->GetFullPath(), cmtarget, lang);
|
||||
cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
|
||||
|
||||
cmXCodeObject* settings =
|
||||
this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
|
||||
|
@ -671,36 +708,12 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmXCodeObject*
|
||||
cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
|
||||
cmTarget& cmtarget)
|
||||
std::string
|
||||
GetSourcecodeValueFromFileExtension(const std::string& _ext,
|
||||
const std::string& lang)
|
||||
{
|
||||
std::string fname = sf->GetFullPath();
|
||||
cmXCodeObject* fileRef = this->FileRefs[fname];
|
||||
if(!fileRef)
|
||||
{
|
||||
fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
|
||||
std::string comment = fname;
|
||||
//comment += " in ";
|
||||
//std::string gname = group->GetObject("name")->GetString();
|
||||
//comment += gname.substr(1, gname.size()-2);
|
||||
fileRef->SetComment(fname.c_str());
|
||||
this->FileRefs[fname] = fileRef;
|
||||
}
|
||||
cmStdString key = GetGroupMapKey(cmtarget, sf);
|
||||
cmXCodeObject* group = this->GroupMap[key];
|
||||
cmXCodeObject* children = group->GetObject("children");
|
||||
if (!children->HasObject(fileRef))
|
||||
{
|
||||
children->AddObject(fileRef);
|
||||
}
|
||||
fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
|
||||
|
||||
const char* lang =
|
||||
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
|
||||
std::string ext = cmSystemTools::LowerCase(_ext);
|
||||
std::string sourcecode = "sourcecode";
|
||||
std::string ext = sf->GetExtension();
|
||||
ext = cmSystemTools::LowerCase(ext);
|
||||
|
||||
if(ext == "o")
|
||||
{
|
||||
|
@ -735,18 +748,6 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
|
|||
{
|
||||
sourcecode += ".cpp.h";
|
||||
}
|
||||
else if(lang && strcmp(lang, "CXX") == 0)
|
||||
{
|
||||
sourcecode += ".cpp.cpp";
|
||||
}
|
||||
else if(lang && strcmp(lang, "C") == 0)
|
||||
{
|
||||
sourcecode += ".c.c";
|
||||
}
|
||||
else if(lang && strcmp(lang, "Fortran") == 0)
|
||||
{
|
||||
sourcecode += ".fortran.f90";
|
||||
}
|
||||
else if(ext == "png" || ext == "gif" || ext == "jpg")
|
||||
{
|
||||
sourcecode = "image";
|
||||
|
@ -755,6 +756,18 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
|
|||
{
|
||||
sourcecode += ".text";
|
||||
}
|
||||
else if(lang == "CXX")
|
||||
{
|
||||
sourcecode += ".cpp.cpp";
|
||||
}
|
||||
else if(lang == "C")
|
||||
{
|
||||
sourcecode += ".c.c";
|
||||
}
|
||||
else if(lang == "Fortran")
|
||||
{
|
||||
sourcecode += ".fortran.f90";
|
||||
}
|
||||
//else
|
||||
// {
|
||||
// // Already specialized above or we leave sourcecode == "sourcecode"
|
||||
|
@ -763,11 +776,51 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
|
|||
// // valid lastKnownFileType value.
|
||||
// }
|
||||
|
||||
return sourcecode;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmXCodeObject*
|
||||
cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
|
||||
const std::string &fullpath,
|
||||
cmTarget& cmtarget,
|
||||
const std::string &lang)
|
||||
{
|
||||
std::string fname = fullpath;
|
||||
cmXCodeObject* fileRef = this->FileRefs[fname];
|
||||
if(!fileRef)
|
||||
{
|
||||
fileRef = this->CreateObject(cmXCodeObject::PBXFileReference);
|
||||
std::string comment = fname;
|
||||
fileRef->SetComment(fname.c_str());
|
||||
this->FileRefs[fname] = fileRef;
|
||||
}
|
||||
cmStdString key = GetGroupMapKeyFromPath(cmtarget, fullpath);
|
||||
cmXCodeObject* group = this->GroupMap[key];
|
||||
cmXCodeObject* children = group->GetObject("children");
|
||||
if (!children->HasObject(fileRef))
|
||||
{
|
||||
children->AddObject(fileRef);
|
||||
}
|
||||
fileRef->AddAttribute("fileEncoding", this->CreateString("4"));
|
||||
|
||||
// Compute the extension.
|
||||
std::string ext;
|
||||
std::string realExt =
|
||||
cmSystemTools::GetFilenameLastExtension(fullpath);
|
||||
if(!realExt.empty())
|
||||
{
|
||||
// Extension without the leading '.'.
|
||||
ext = realExt.substr(1);
|
||||
}
|
||||
|
||||
std::string sourcecode = GetSourcecodeValueFromFileExtension(ext, lang);
|
||||
|
||||
fileRef->AddAttribute("lastKnownFileType",
|
||||
this->CreateString(sourcecode.c_str()));
|
||||
|
||||
// Store the file path relative to the top of the source tree.
|
||||
std::string path = this->RelativeToSource(sf->GetFullPath().c_str());
|
||||
std::string path = this->RelativeToSource(fullpath.c_str());
|
||||
std::string name = cmSystemTools::GetFilenameName(path.c_str());
|
||||
const char* sourceTree = (cmSystemTools::FileIsFullPath(path.c_str())?
|
||||
"<absolute>" : "SOURCE_ROOT");
|
||||
|
@ -781,6 +834,22 @@ cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
|
|||
return fileRef;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmXCodeObject*
|
||||
cmGlobalXCodeGenerator::CreateXCodeFileReference(cmSourceFile* sf,
|
||||
cmTarget& cmtarget)
|
||||
{
|
||||
const char* lang =
|
||||
this->CurrentLocalGenerator->GetSourceFileLanguage(*sf);
|
||||
if (!lang)
|
||||
{
|
||||
lang = "";
|
||||
}
|
||||
|
||||
return this->CreateXCodeFileReferenceFromPath(
|
||||
sf->GetFullPath(), cmtarget, lang);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname)
|
||||
{
|
||||
|
@ -889,6 +958,20 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
|
|||
}
|
||||
}
|
||||
|
||||
// Add object library contents as external objects. (Equivalent to
|
||||
// the externalObjFiles above, except each one is not a cmSourceFile
|
||||
// within the target.)
|
||||
std::vector<std::string> objs;
|
||||
this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
std::string obj = *oi;
|
||||
cmXCodeObject* xsf =
|
||||
this->CreateXCodeSourceFileFromPath(obj, cmtarget, "");
|
||||
externalObjFiles.push_back(xsf);
|
||||
}
|
||||
|
||||
// some build phases only apply to bundles and/or frameworks
|
||||
bool isFrameworkTarget = cmtarget.IsFrameworkOnApple();
|
||||
bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE");
|
||||
|
@ -1494,7 +1577,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
std::string defFlags;
|
||||
bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(target.GetType() == cmTarget::MODULE_LIBRARY));
|
||||
bool binary = ((target.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
bool binary = ((target.GetType() == cmTarget::OBJECT_LIBRARY) ||
|
||||
(target.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(target.GetType() == cmTarget::EXECUTABLE) ||
|
||||
shared);
|
||||
|
||||
|
@ -1581,7 +1665,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
}
|
||||
|
||||
const char* linkFlagsProp = "LINK_FLAGS";
|
||||
if(target.GetType() == cmTarget::STATIC_LIBRARY)
|
||||
if(target.GetType() == cmTarget::OBJECT_LIBRARY ||
|
||||
target.GetType() == cmTarget::STATIC_LIBRARY)
|
||||
{
|
||||
linkFlagsProp = "STATIC_LIBRARY_FLAGS";
|
||||
}
|
||||
|
@ -1635,11 +1720,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
std::string pnprefix;
|
||||
std::string pnbase;
|
||||
std::string pnsuffix;
|
||||
target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
|
||||
|
||||
// Store the product name for all target types.
|
||||
buildSettings->AddAttribute("PRODUCT_NAME",
|
||||
this->CreateString(pnbase.c_str()));
|
||||
target.GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
|
||||
|
||||
// Set attributes to specify the proper name for the target.
|
||||
std::string pndir = this->CurrentMakefile->GetCurrentOutputDirectory();
|
||||
|
@ -1663,17 +1745,44 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||
this->CreateString(pndir.c_str()));
|
||||
pndir = target.GetDirectory(configName);
|
||||
}
|
||||
|
||||
buildSettings->AddAttribute("EXECUTABLE_PREFIX",
|
||||
this->CreateString(pnprefix.c_str()));
|
||||
buildSettings->AddAttribute("EXECUTABLE_SUFFIX",
|
||||
this->CreateString(pnsuffix.c_str()));
|
||||
}
|
||||
else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
pnprefix = "lib";
|
||||
pnbase = target.GetName();
|
||||
pnsuffix = ".a";
|
||||
|
||||
if(this->XcodeVersion >= 21)
|
||||
{
|
||||
std::string pncdir = this->GetObjectsNormalDirectory(
|
||||
this->CurrentProject, configName, &target);
|
||||
buildSettings->AddAttribute("CONFIGURATION_BUILD_DIR",
|
||||
this->CreateString(pncdir.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
buildSettings->AddAttribute("OBJROOT",
|
||||
this->CreateString(pndir.c_str()));
|
||||
pndir = this->GetObjectsNormalDirectory(
|
||||
this->CurrentProject, configName, &target);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the product name for all target types.
|
||||
buildSettings->AddAttribute("PRODUCT_NAME",
|
||||
this->CreateString(pnbase.c_str()));
|
||||
buildSettings->AddAttribute("SYMROOT",
|
||||
this->CreateString(pndir.c_str()));
|
||||
|
||||
// Handle settings for each target type.
|
||||
switch(target.GetType())
|
||||
{
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
{
|
||||
buildSettings->AddAttribute("LIBRARY_STYLE",
|
||||
|
@ -2177,6 +2286,7 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(cmTarget& cmtarget)
|
|||
{
|
||||
switch(cmtarget.GetType())
|
||||
{
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
return "archive.ar";
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
|
@ -2200,6 +2310,7 @@ const char* cmGlobalXCodeGenerator::GetTargetProductType(cmTarget& cmtarget)
|
|||
{
|
||||
switch(cmtarget.GetType())
|
||||
{
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
return "com.apple.product-type.library.static";
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
|
@ -2257,7 +2368,17 @@ cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
|
|||
{
|
||||
fileRef->AddAttribute("explicitFileType", this->CreateString(fileType));
|
||||
}
|
||||
std::string fullName = cmtarget.GetFullName(defConfig.c_str());
|
||||
std::string fullName;
|
||||
if(cmtarget.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
fullName = "lib";
|
||||
fullName += cmtarget.GetName();
|
||||
fullName += ".a";
|
||||
}
|
||||
else
|
||||
{
|
||||
fullName = cmtarget.GetFullName(defConfig.c_str());
|
||||
}
|
||||
fileRef->AddAttribute("path", this->CreateString(fullName.c_str()));
|
||||
fileRef->AddAttribute("refType", this->CreateString("0"));
|
||||
fileRef->AddAttribute("sourceTree",
|
||||
|
@ -2462,7 +2583,8 @@ void cmGlobalXCodeGenerator
|
|||
}
|
||||
|
||||
// Skip link information for static libraries.
|
||||
if(cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
|
||||
if(cmtarget->GetType() == cmTarget::OBJECT_LIBRARY ||
|
||||
cmtarget->GetType() == cmTarget::STATIC_LIBRARY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2610,6 +2732,7 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
|
|||
|
||||
std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles();
|
||||
|
||||
// Put cmSourceFile instances in proper groups:
|
||||
for(std::vector<cmSourceFile*>::const_iterator s = classes.begin();
|
||||
s != classes.end(); s++)
|
||||
{
|
||||
|
@ -2623,6 +2746,21 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
|
|||
cmStdString key = GetGroupMapKey(cmtarget, sf);
|
||||
this->GroupMap[key] = pbxgroup;
|
||||
}
|
||||
|
||||
// Put OBJECT_LIBRARY objects in proper groups:
|
||||
std::vector<std::string> objs;
|
||||
this->GetGeneratorTarget(&cmtarget)->UseObjectLibraries(objs);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
std::string const& source = *oi;
|
||||
cmSourceGroup& sourceGroup =
|
||||
mf->FindSourceGroup(source.c_str(), sourceGroups);
|
||||
cmXCodeObject* pbxgroup =
|
||||
this->CreateOrGetPBXGroup(cmtarget, &sourceGroup);
|
||||
cmStdString key = GetGroupMapKeyFromPath(cmtarget, source);
|
||||
this->GroupMap[key] = pbxgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3054,6 +3192,26 @@ void cmGlobalXCodeGenerator
|
|||
this->RootObject->AddAttribute("targets", allTargets);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmGlobalXCodeGenerator::GetObjectsNormalDirectory(
|
||||
const std::string &projName,
|
||||
const std::string &configName,
|
||||
const cmTarget *t) const
|
||||
{
|
||||
std::string dir =
|
||||
t->GetMakefile()->GetCurrentOutputDirectory();
|
||||
dir += "/";
|
||||
dir += projName;
|
||||
dir += ".build/";
|
||||
dir += configName;
|
||||
dir += "/";
|
||||
dir += t->GetName();
|
||||
dir += ".build/Objects-normal/";
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
|
||||
|
@ -3123,6 +3281,8 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
|
|||
cmTarget* t =target->GetTarget();
|
||||
|
||||
if(t->GetType() == cmTarget::EXECUTABLE ||
|
||||
// Nope - no post-build for OBJECT_LIRBRARY
|
||||
// t->GetType() == cmTarget::OBJECT_LIBRARY ||
|
||||
t->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
t->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
t->GetType() == cmTarget::MODULE_LIBRARY)
|
||||
|
@ -3178,15 +3338,8 @@ cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
|
|||
// then remove those exectuables as well
|
||||
if(this->Architectures.size() > 1)
|
||||
{
|
||||
std::string universal =
|
||||
t->GetMakefile()->GetCurrentOutputDirectory();
|
||||
universal += "/";
|
||||
universal += this->CurrentProject;
|
||||
universal += ".build/";
|
||||
universal += configName;
|
||||
universal += "/";
|
||||
universal += t->GetName();
|
||||
universal += ".build/Objects-normal/";
|
||||
std::string universal = this->GetObjectsNormalDirectory(
|
||||
this->CurrentProject, configName, t);
|
||||
for( std::vector<std::string>::iterator arch =
|
||||
this->Architectures.begin();
|
||||
arch != this->Architectures.end(); ++arch)
|
||||
|
@ -3292,7 +3445,7 @@ cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* cmGlobalXCodeGenerator::GetCMakeCFGInitDirectory()
|
||||
const char* cmGlobalXCodeGenerator::GetCMakeCFGIntDir() const
|
||||
{
|
||||
return this->XcodeVersion >= 21 ?
|
||||
"$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" : ".";
|
||||
|
@ -3545,3 +3698,51 @@ bool cmGlobalXCodeGenerator::IsMultiConfig()
|
|||
// Newer Xcode versions are multi config:
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmGlobalXCodeGenerator
|
||||
::ComputeTargetObjects(cmGeneratorTarget* gt) const
|
||||
{
|
||||
// Count the number of object files with each name. Warn about duplicate
|
||||
// names since Xcode names them uniquely automatically with a numeric suffix
|
||||
// to avoid exact duplicate file names. Note that Mac file names are not
|
||||
// typically case sensitive, hence the LowerCase.
|
||||
std::map<cmStdString, int> counts;
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = gt->ObjectSources.begin();
|
||||
si != gt->ObjectSources.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *si;
|
||||
std::string objectName =
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
|
||||
objectName += ".o";
|
||||
|
||||
std::string objectNameLower = cmSystemTools::LowerCase(objectName);
|
||||
counts[objectNameLower] += 1;
|
||||
if (2 == counts[objectNameLower])
|
||||
{
|
||||
// TODO: emit warning about duplicate name?
|
||||
}
|
||||
|
||||
gt->Objects[sf] = objectName;
|
||||
}
|
||||
|
||||
const char* configName = this->GetCMakeCFGIntDir();
|
||||
std::string dir = this->GetObjectsNormalDirectory(
|
||||
this->CurrentProject, configName, gt->Target);
|
||||
if(this->XcodeVersion >= 21)
|
||||
{
|
||||
dir += "$(CURRENT_ARCH)/";
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __ppc__
|
||||
dir += "ppc/";
|
||||
#endif
|
||||
#ifdef __i386
|
||||
dir += "i386/";
|
||||
#endif
|
||||
}
|
||||
gt->ObjectDirectory = dir;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
std::string& dir);
|
||||
|
||||
///! What is the configurations directory variable called?
|
||||
virtual const char* GetCMakeCFGInitDirectory();
|
||||
virtual const char* GetCMakeCFGIntDir() const;
|
||||
|
||||
void SetCurrentLocalGenerator(cmLocalGenerator*);
|
||||
|
||||
|
@ -153,6 +153,12 @@ private:
|
|||
std::vector<cmLocalGenerator*>& generators);
|
||||
void WriteXCodePBXProj(std::ostream& fout, cmLocalGenerator* root,
|
||||
std::vector<cmLocalGenerator*>& generators);
|
||||
cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string &fullpath,
|
||||
cmTarget& cmtarget,
|
||||
const std::string &lang);
|
||||
cmXCodeObject* CreateXCodeSourceFileFromPath(const std::string &fullpath,
|
||||
cmTarget& cmtarget,
|
||||
const std::string &lang);
|
||||
cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
|
||||
cmTarget& cmtarget);
|
||||
cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen,
|
||||
|
@ -200,6 +206,13 @@ protected:
|
|||
std::vector<cmXCodeObject*> XCodeObjects;
|
||||
cmXCodeObject* RootObject;
|
||||
private:
|
||||
void ComputeTargetObjects(cmGeneratorTarget* gt) const;
|
||||
|
||||
std::string GetObjectsNormalDirectory(
|
||||
const std::string &projName,
|
||||
const std::string &configName,
|
||||
const cmTarget *t) const;
|
||||
|
||||
void addObject(cmXCodeObject *obj);
|
||||
std::string PostBuildMakeTarget(std::string const& tName,
|
||||
std::string const& configName);
|
||||
|
|
|
@ -357,7 +357,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
if(target->GetType() != cmTarget::EXECUTABLE &&
|
||||
target->GetType() != cmTarget::STATIC_LIBRARY &&
|
||||
target->GetType() != cmTarget::SHARED_LIBRARY &&
|
||||
target->GetType() != cmTarget::MODULE_LIBRARY)
|
||||
target->GetType() != cmTarget::MODULE_LIBRARY &&
|
||||
target->GetType() != cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "TARGETS given target \"" << (*targetIt)
|
||||
|
@ -365,6 +366,14 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
|
|||
this->SetError(e.str().c_str());
|
||||
return false;
|
||||
}
|
||||
else if(target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "TARGETS given OBJECT library \"" << (*targetIt)
|
||||
<< "\" which may not be installed.";
|
||||
this->SetError(e.str().c_str());
|
||||
return false;
|
||||
}
|
||||
// Store the target in the list to be installed.
|
||||
targets.push_back(target);
|
||||
}
|
||||
|
|
|
@ -90,6 +90,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
|
|||
case cmTarget::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break;
|
||||
case cmTarget::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break;
|
||||
case cmTarget::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break;
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
case cmTarget::UTILITY:
|
||||
case cmTarget::GLOBAL_TARGET:
|
||||
case cmTarget::UNKNOWN_LIBRARY:
|
||||
|
|
|
@ -1914,6 +1914,10 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
|
|||
case cmTarget::UNKNOWN_LIBRARY:
|
||||
dep = target->GetLocation(config);
|
||||
return true;
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
// An object library has no single file on which to depend.
|
||||
// This was listed to get the target-level dependency.
|
||||
return false;
|
||||
case cmTarget::UTILITY:
|
||||
case cmTarget::GLOBAL_TARGET:
|
||||
// A utility target has no file on which to depend. This was listed
|
||||
|
|
|
@ -117,37 +117,6 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
|
|||
return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
|
||||
}
|
||||
|
||||
// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
|
||||
std::string
|
||||
cmLocalNinjaGenerator
|
||||
::GetObjectFileName(const cmTarget& target,
|
||||
const cmSourceFile& source)
|
||||
{
|
||||
// Make sure we never hit this old case.
|
||||
if(source.GetProperty("MACOSX_PACKAGE_LOCATION"))
|
||||
{
|
||||
std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: ";
|
||||
msg += source.GetFullPath();
|
||||
this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
|
||||
msg.c_str());
|
||||
}
|
||||
|
||||
// Start with the target directory.
|
||||
std::string obj = this->GetTargetDirectory(target);
|
||||
obj += "/";
|
||||
|
||||
// Get the object file name without the target directory.
|
||||
std::string dir_max;
|
||||
dir_max += this->Makefile->GetCurrentOutputDirectory();
|
||||
dir_max += "/";
|
||||
dir_max += obj;
|
||||
std::string objectName =
|
||||
this->GetObjectFileNameWithoutTarget(source, dir_max, 0);
|
||||
// Append the object name to the target directory.
|
||||
obj += objectName;
|
||||
return obj;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Virtual protected methods.
|
||||
|
||||
|
|
|
@ -59,9 +59,6 @@ public:
|
|||
const char* GetConfigName() const
|
||||
{ return this->ConfigName.c_str(); }
|
||||
|
||||
std::string GetObjectFileName(const cmTarget& target,
|
||||
const cmSourceFile& source);
|
||||
|
||||
/// @return whether we are processing the top CMakeLists.txt file.
|
||||
bool isRootMakefile() const;
|
||||
|
||||
|
|
|
@ -358,6 +358,7 @@ void cmLocalUnixMakefileGenerator3
|
|||
(t->second.GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::MODULE_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::OBJECT_LIBRARY) ||
|
||||
(t->second.GetType() == cmTarget::UTILITY))
|
||||
{
|
||||
emitted.insert(t->second.GetName());
|
||||
|
@ -2008,45 +2009,6 @@ void cmLocalUnixMakefileGenerator3
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmLocalUnixMakefileGenerator3
|
||||
::GetObjectFileName(cmTarget& target,
|
||||
const cmSourceFile& source,
|
||||
std::string* nameWithoutTargetDir,
|
||||
bool* hasSourceExtension)
|
||||
{
|
||||
// Make sure we never hit this old case.
|
||||
if(source.GetProperty("MACOSX_PACKAGE_LOCATION"))
|
||||
{
|
||||
std::string msg = "MACOSX_PACKAGE_LOCATION set on source file: ";
|
||||
msg += source.GetFullPath();
|
||||
this->GetMakefile()->IssueMessage(cmake::INTERNAL_ERROR,
|
||||
msg.c_str());
|
||||
}
|
||||
|
||||
// Start with the target directory.
|
||||
std::string obj = this->GetTargetDirectory(target);
|
||||
obj += "/";
|
||||
|
||||
// Get the object file name without the target directory.
|
||||
std::string dir_max;
|
||||
dir_max += this->Makefile->GetCurrentOutputDirectory();
|
||||
dir_max += "/";
|
||||
dir_max += obj;
|
||||
std::string objectName =
|
||||
this->GetObjectFileNameWithoutTarget(source, dir_max,
|
||||
hasSourceExtension);
|
||||
if(nameWithoutTargetDir)
|
||||
{
|
||||
*nameWithoutTargetDir = objectName;
|
||||
}
|
||||
|
||||
// Append the object name to the target directory.
|
||||
obj += objectName;
|
||||
return obj;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmLocalUnixMakefileGenerator3::WriteDisclaimer(std::ostream& os)
|
||||
{
|
||||
|
|
|
@ -284,11 +284,6 @@ protected:
|
|||
cmTarget& target,
|
||||
const std::vector<std::string>& objects);
|
||||
|
||||
std::string GetObjectFileName(cmTarget& target,
|
||||
const cmSourceFile& source,
|
||||
std::string* nameWithoutTargetDir = 0,
|
||||
bool* hasSourceExtension = 0);
|
||||
|
||||
void AppendRuleDepend(std::vector<std::string>& depends,
|
||||
const char* ruleFileName);
|
||||
void AppendRuleDepends(std::vector<std::string>& depends,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "cmSystemTools.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmCacheManager.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmake.h"
|
||||
|
||||
#include "cmComputeLinkInformation.h"
|
||||
|
@ -126,6 +127,7 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
|
|||
switch(l->second.GetType())
|
||||
{
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
this->SetBuildType(STATIC_LIBRARY, l->first.c_str(), l->second);
|
||||
break;
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
|
@ -336,9 +338,6 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
|
|||
}
|
||||
}
|
||||
|
||||
// Compute which sources need unique object computation.
|
||||
this->ComputeObjectNameRequirements(classes);
|
||||
|
||||
// Write the DSP file's header.
|
||||
this->WriteDSPHeader(fout, libName, target, sourceGroups);
|
||||
|
||||
|
@ -358,6 +357,8 @@ void cmLocalVisualStudio6Generator
|
|||
::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
|
||||
std::ostream &fout, const char *libName)
|
||||
{
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
const std::vector<const cmSourceFile *> &sourceFiles =
|
||||
sg->GetSourceFiles();
|
||||
// If the group is empty, don't write it at all.
|
||||
|
@ -374,28 +375,6 @@ void cmLocalVisualStudio6Generator
|
|||
this->WriteDSPBeginGroup(fout, name.c_str(), "");
|
||||
}
|
||||
|
||||
// Compute the maximum length configuration name.
|
||||
std::string config_max;
|
||||
for(std::vector<std::string>::iterator i = this->Configurations.begin();
|
||||
i != this->Configurations.end(); ++i)
|
||||
{
|
||||
// Strip the subdirectory name out of the configuration name.
|
||||
std::string config = this->GetConfigName(*i);
|
||||
if(config.size() > config_max.size())
|
||||
{
|
||||
config_max = config;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the maximum length full path to the intermediate
|
||||
// files directory for any configuration. This is used to construct
|
||||
// object file names that do not produce paths that are too long.
|
||||
std::string dir_max;
|
||||
dir_max += this->Makefile->GetCurrentOutputDirectory();
|
||||
dir_max += "/";
|
||||
dir_max += config_max;
|
||||
dir_max += "/";
|
||||
|
||||
// Loop through each source in the source group.
|
||||
for(std::vector<const cmSourceFile *>::const_iterator sf =
|
||||
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
|
||||
|
@ -406,11 +385,9 @@ void cmLocalVisualStudio6Generator
|
|||
std::string compileFlags;
|
||||
std::vector<std::string> depends;
|
||||
std::string objectNameDir;
|
||||
if(this->NeedObjectName.find(*sf) != this->NeedObjectName.end())
|
||||
if(gt->ExplicitObjectName.find(*sf) != gt->ExplicitObjectName.end())
|
||||
{
|
||||
objectNameDir =
|
||||
cmSystemTools::GetFilenamePath(
|
||||
this->GetObjectFileNameWithoutTarget(*(*sf), dir_max));
|
||||
objectNameDir = cmSystemTools::GetFilenamePath(gt->Objects[*sf]);
|
||||
}
|
||||
|
||||
// Add per-source file flags.
|
||||
|
@ -1264,8 +1241,18 @@ void cmLocalVisualStudio6Generator
|
|||
outputNameMinSizeRel = target.GetFullName("MinSizeRel");
|
||||
outputNameRelWithDebInfo = target.GetFullName("RelWithDebInfo");
|
||||
}
|
||||
else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
outputName = target.GetName();
|
||||
outputName += ".lib";
|
||||
outputNameDebug = outputName;
|
||||
outputNameRelease = outputName;
|
||||
outputNameMinSizeRel = outputName;
|
||||
outputNameRelWithDebInfo = outputName;
|
||||
}
|
||||
|
||||
// Compute the output directory for the target.
|
||||
std::string outputDirOld;
|
||||
std::string outputDirDebug;
|
||||
std::string outputDirRelease;
|
||||
std::string outputDirMinSizeRel;
|
||||
|
@ -1275,6 +1262,11 @@ void cmLocalVisualStudio6Generator
|
|||
target.GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
target.GetType() == cmTarget::MODULE_LIBRARY)
|
||||
{
|
||||
#ifdef CM_USE_OLD_VS6
|
||||
outputDirOld =
|
||||
removeQuotes(this->ConvertToOptionallyRelativeOutputPath
|
||||
(target.GetDirectory().c_str()));
|
||||
#endif
|
||||
outputDirDebug =
|
||||
removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
|
||||
target.GetDirectory("Debug").c_str()));
|
||||
|
@ -1288,6 +1280,14 @@ void cmLocalVisualStudio6Generator
|
|||
removeQuotes(this->ConvertToOptionallyRelativeOutputPath(
|
||||
target.GetDirectory("RelWithDebInfo").c_str()));
|
||||
}
|
||||
else if(target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
std::string outputDir = cmake::GetCMakeFilesDirectoryPostSlash();
|
||||
outputDirDebug = outputDir + "Debug";
|
||||
outputDirRelease = outputDir + "Release";
|
||||
outputDirMinSizeRel = outputDir + "MinSizeRel";
|
||||
outputDirRelWithDebInfo = outputDir + "RelWithDebInfo";
|
||||
}
|
||||
|
||||
// Compute the proper link information for the target.
|
||||
std::string optionsDebug;
|
||||
|
@ -1428,6 +1428,16 @@ void cmLocalVisualStudio6Generator
|
|||
staticLibOptionsRelWithDebInfo += " ";
|
||||
staticLibOptionsRelWithDebInfo = libflagsRelWithDebInfo;
|
||||
}
|
||||
std::string objects;
|
||||
this->OutputObjects(target, "LIB", objects);
|
||||
if(!objects.empty())
|
||||
{
|
||||
objects = "\n" + objects;
|
||||
staticLibOptionsDebug += objects;
|
||||
staticLibOptionsRelease += objects;
|
||||
staticLibOptionsMinSizeRel += objects;
|
||||
staticLibOptionsRelWithDebInfo += objects;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the export symbol definition for shared library objects.
|
||||
|
@ -1456,7 +1466,8 @@ void cmLocalVisualStudio6Generator
|
|||
libnameExports.c_str());
|
||||
cmSystemTools::ReplaceString(line, "CMAKE_MFC_FLAG",
|
||||
mfcFlag);
|
||||
if(target.GetType() == cmTarget::STATIC_LIBRARY )
|
||||
if(target.GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmSystemTools::ReplaceString(line, "CM_STATIC_LIB_ARGS_DEBUG",
|
||||
staticLibOptionsDebug.c_str());
|
||||
|
@ -1555,7 +1566,7 @@ void cmLocalVisualStudio6Generator
|
|||
(exePath.c_str())).c_str());
|
||||
#endif
|
||||
|
||||
if(targetBuilds)
|
||||
if(targetBuilds || target.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_DEBUG",
|
||||
outputDirDebug.c_str());
|
||||
|
@ -1565,13 +1576,11 @@ void cmLocalVisualStudio6Generator
|
|||
outputDirMinSizeRel.c_str());
|
||||
cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY_RELWITHDEBINFO",
|
||||
outputDirRelWithDebInfo.c_str());
|
||||
#ifdef CM_USE_OLD_VS6
|
||||
std::string outPath = target.GetDirectory();
|
||||
cmSystemTools::ReplaceString
|
||||
(line, "OUTPUT_DIRECTORY",
|
||||
removeQuotes(this->ConvertToOptionallyRelativeOutputPath
|
||||
(outPath.c_str())).c_str());
|
||||
#endif
|
||||
if(!outputDirOld.empty())
|
||||
{
|
||||
cmSystemTools::ReplaceString(line, "OUTPUT_DIRECTORY",
|
||||
outputDirOld.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
cmSystemTools::ReplaceString(line,
|
||||
|
@ -1588,7 +1597,7 @@ void cmLocalVisualStudio6Generator
|
|||
std::string flagsDebug = " ";
|
||||
std::string flagsDebugRel = " ";
|
||||
if(target.GetType() >= cmTarget::EXECUTABLE &&
|
||||
target.GetType() <= cmTarget::MODULE_LIBRARY)
|
||||
target.GetType() <= cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
const char* linkLanguage = target.GetLinkerLanguage();
|
||||
if(!linkLanguage)
|
||||
|
@ -1743,6 +1752,8 @@ void cmLocalVisualStudio6Generator
|
|||
ItemVector const& linkLibs = cli.GetItems();
|
||||
std::vector<std::string> const& linkDirs = cli.GetDirectories();
|
||||
|
||||
this->OutputObjects(target, "LINK", options);
|
||||
|
||||
// Build the link options code.
|
||||
for(std::vector<std::string>::const_iterator d = linkDirs.begin();
|
||||
d != linkDirs.end(); ++d)
|
||||
|
@ -1787,6 +1798,28 @@ void cmLocalVisualStudio6Generator
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmLocalVisualStudio6Generator
|
||||
::OutputObjects(cmTarget& target, const char* tool,
|
||||
std::string& options)
|
||||
{
|
||||
// VS 6 does not support per-config source locations so we
|
||||
// list object library content on the link line instead.
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
std::vector<std::string> objs;
|
||||
gt->UseObjectLibraries(objs);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
options += "# ADD ";
|
||||
options += tool;
|
||||
options += "32 ";
|
||||
options += this->ConvertToOptionallyRelativeOutputPath(oi->c_str());
|
||||
options += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
cmLocalVisualStudio6Generator
|
||||
::GetTargetDirectory(cmTarget const&) const
|
||||
|
@ -1795,6 +1828,36 @@ cmLocalVisualStudio6Generator
|
|||
return "";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmLocalVisualStudio6Generator
|
||||
::ComputeLongestObjectDirectory(cmTarget&) const
|
||||
{
|
||||
// Compute the maximum length configuration name.
|
||||
std::string config_max;
|
||||
for(std::vector<std::string>::const_iterator
|
||||
i = this->Configurations.begin();
|
||||
i != this->Configurations.end(); ++i)
|
||||
{
|
||||
// Strip the subdirectory name out of the configuration name.
|
||||
std::string config = this->GetConfigName(*i);
|
||||
if(config.size() > config_max.size())
|
||||
{
|
||||
config_max = config;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the maximum length full path to the intermediate
|
||||
// files directory for any configuration. This is used to construct
|
||||
// object file names that do not produce paths that are too long.
|
||||
std::string dir_max;
|
||||
dir_max += this->Makefile->GetCurrentOutputDirectory();
|
||||
dir_max += "/";
|
||||
dir_max += config_max;
|
||||
dir_max += "/";
|
||||
return dir_max;
|
||||
}
|
||||
|
||||
std::string
|
||||
cmLocalVisualStudio6Generator
|
||||
::GetConfigName(std::string const& configuration) const
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
void SetBuildType(BuildType, const char* libName, cmTarget&);
|
||||
|
||||
virtual std::string GetTargetDirectory(cmTarget const& target) const;
|
||||
virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
|
||||
private:
|
||||
std::string DSPHeaderTemplate;
|
||||
std::string DSPFooterTemplate;
|
||||
|
@ -86,6 +87,8 @@ private:
|
|||
void ComputeLinkOptions(cmTarget& target, const char* configName,
|
||||
const std::string extraOptions,
|
||||
std::string& options);
|
||||
void OutputObjects(cmTarget& target, const char* tool,
|
||||
std::string& options);
|
||||
std::string GetTargetIncludeOptions(cmTarget &target);
|
||||
std::vector<std::string> Configurations;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "cmSystemTools.h"
|
||||
#include "cmSourceFile.h"
|
||||
#include "cmCacheManager.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmake.h"
|
||||
|
||||
#include "cmComputeLinkInformation.h"
|
||||
|
@ -38,6 +39,7 @@ public:
|
|||
LocalGenerator(e) {}
|
||||
typedef cmComputeLinkInformation::ItemVector ItemVector;
|
||||
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
|
||||
void OutputObjects(std::ostream& fout, cmTarget* t, const char* isep = 0);
|
||||
private:
|
||||
cmLocalVisualStudio7Generator* LocalGenerator;
|
||||
};
|
||||
|
@ -641,6 +643,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
|
|||
bool targetBuilds = true;
|
||||
switch(target.GetType())
|
||||
{
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
targetBuilds = false; // TODO: PDB for object library?
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
projectType = "typeStaticLibrary";
|
||||
configType = "4";
|
||||
|
@ -1000,6 +1004,22 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||
}
|
||||
switch(target.GetType())
|
||||
{
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
{
|
||||
std::string libpath = this->GetTargetDirectory(target);
|
||||
libpath += "/";
|
||||
libpath += configName;
|
||||
libpath += "/";
|
||||
libpath += target.GetName();
|
||||
libpath += ".lib";
|
||||
const char* tool =
|
||||
this->FortranProject? "VFLibrarianTool":"VCLibrarianTool";
|
||||
fout << "\t\t\t<Tool\n"
|
||||
<< "\t\t\t\tName=\"" << tool << "\"\n";
|
||||
fout << "\t\t\t\tOutputFile=\""
|
||||
<< this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
|
||||
break;
|
||||
}
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
{
|
||||
std::string targetNameFull = target.GetFullName(configName);
|
||||
|
@ -1014,6 +1034,15 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||
fout << "\t\t\t<Tool\n"
|
||||
<< "\t\t\t\tName=\"" << tool << "\"\n";
|
||||
|
||||
if(this->GetVersion() < VS8)
|
||||
{
|
||||
cmOStringStream libdeps;
|
||||
this->Internal->OutputObjects(libdeps, &target);
|
||||
if(!libdeps.str().empty())
|
||||
{
|
||||
fout << "\t\t\t\tAdditionalDependencies=\"" << libdeps.str() << "\"\n";
|
||||
}
|
||||
}
|
||||
std::string libflags;
|
||||
if(const char* flags = target.GetProperty("STATIC_LIBRARY_FLAGS"))
|
||||
{
|
||||
|
@ -1074,8 +1103,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||
// Use the NOINHERIT macro to avoid getting VS project default
|
||||
// libraries which may be set by the user to something bad.
|
||||
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
|
||||
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
|
||||
<< " ";
|
||||
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
|
||||
if(this->GetVersion() < VS8)
|
||||
{
|
||||
this->Internal->OutputObjects(fout, &target, " ");
|
||||
}
|
||||
fout << " ";
|
||||
this->Internal->OutputLibraries(fout, cli.GetItems());
|
||||
fout << "\"\n";
|
||||
temp = target.GetDirectory(configName);
|
||||
|
@ -1155,8 +1188,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||
// Use the NOINHERIT macro to avoid getting VS project default
|
||||
// libraries which may be set by the user to something bad.
|
||||
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
|
||||
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
|
||||
<< " ";
|
||||
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str());
|
||||
if(this->GetVersion() < VS8)
|
||||
{
|
||||
this->Internal->OutputObjects(fout, &target, " ");
|
||||
}
|
||||
fout << " ";
|
||||
this->Internal->OutputLibraries(fout, cli.GetItems());
|
||||
fout << "\"\n";
|
||||
temp = target.GetDirectory(configName);
|
||||
|
@ -1242,6 +1279,30 @@ cmLocalVisualStudio7GeneratorInternals
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmLocalVisualStudio7GeneratorInternals
|
||||
::OutputObjects(std::ostream& fout, cmTarget* t, const char* isep)
|
||||
{
|
||||
// VS < 8 does not support per-config source locations so we
|
||||
// list object library content on the link line instead.
|
||||
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
|
||||
cmGeneratorTarget* gt =
|
||||
lg->GetGlobalGenerator()->GetGeneratorTarget(t);
|
||||
std::vector<std::string> objs;
|
||||
gt->UseObjectLibraries(objs);
|
||||
const char* sep = isep? isep : "";
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
std::string rel = lg->Convert(oi->c_str(),
|
||||
cmLocalGenerator::START_OUTPUT,
|
||||
cmLocalGenerator::UNCHANGED);
|
||||
fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
|
||||
sep = " ";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmLocalVisualStudio7Generator
|
||||
|
@ -1310,9 +1371,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
|||
sourceGroup.AssignSource(*i);
|
||||
}
|
||||
|
||||
// Compute which sources need unique object computation.
|
||||
this->ComputeObjectNameRequirements(classes);
|
||||
|
||||
// open the project
|
||||
this->WriteProjectStart(fout, libName, target, sourceGroups);
|
||||
// write the configuration information
|
||||
|
@ -1328,7 +1386,27 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
|||
this->WriteGroup(&sg, target, fout, libName, configs);
|
||||
}
|
||||
|
||||
//}
|
||||
if(this->GetVersion() >= VS8)
|
||||
{
|
||||
// VS >= 8 support per-config source locations so we
|
||||
// list object library content as external objects.
|
||||
cmGeneratorTarget* gt =
|
||||
this->GlobalGenerator->GetGeneratorTarget(&target);
|
||||
std::vector<std::string> objs;
|
||||
gt->UseObjectLibraries(objs);
|
||||
if(!objs.empty())
|
||||
{
|
||||
// TODO: Separate sub-filter for each object library used?
|
||||
fout << "\t\t<Filter Name=\"Object Libraries\">\n";
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
std::string o = this->ConvertToXMLOutputPathSingle(oi->c_str());
|
||||
fout << "\t\t\t<File RelativePath=\"" << o << "\" />\n";
|
||||
}
|
||||
fout << "\t\t</Filter>\n";
|
||||
}
|
||||
}
|
||||
|
||||
fout << "\t</Files>\n";
|
||||
|
||||
|
@ -1352,8 +1430,7 @@ public:
|
|||
cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
|
||||
cmTarget& target,
|
||||
cmSourceFile const& sf,
|
||||
std::vector<std::string>* configs,
|
||||
std::string const& dir_max);
|
||||
std::vector<std::string>* configs);
|
||||
std::map<cmStdString, cmLVS7GFileConfig> FileConfigMap;
|
||||
};
|
||||
|
||||
|
@ -1361,13 +1438,14 @@ cmLocalVisualStudio7GeneratorFCInfo
|
|||
::cmLocalVisualStudio7GeneratorFCInfo(cmLocalVisualStudio7Generator* lg,
|
||||
cmTarget& target,
|
||||
cmSourceFile const& sf,
|
||||
std::vector<std::string>* configs,
|
||||
std::string const& dir_max)
|
||||
std::vector<std::string>* configs)
|
||||
{
|
||||
cmGeneratorTarget* gt =
|
||||
lg->GetGlobalGenerator()->GetGeneratorTarget(&target);
|
||||
std::string objectName;
|
||||
if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end())
|
||||
if(gt->ExplicitObjectName.find(&sf) != gt->ExplicitObjectName.end())
|
||||
{
|
||||
objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max);
|
||||
objectName = gt->Objects[&sf];
|
||||
}
|
||||
|
||||
// Compute per-source, per-config information.
|
||||
|
@ -1478,11 +1556,11 @@ cmLocalVisualStudio7GeneratorFCInfo
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void cmLocalVisualStudio7Generator
|
||||
::ComputeMaxDirectoryLength(std::string& maxdir,
|
||||
cmTarget& target)
|
||||
{
|
||||
//----------------------------------------------------------------------------
|
||||
std::string
|
||||
cmLocalVisualStudio7Generator
|
||||
::ComputeLongestObjectDirectory(cmTarget& target) const
|
||||
{
|
||||
std::vector<std::string> *configs =
|
||||
static_cast<cmGlobalVisualStudio7Generator *>
|
||||
(this->GlobalGenerator)->GetConfigurations();
|
||||
|
@ -1507,7 +1585,7 @@ void cmLocalVisualStudio7Generator
|
|||
dir_max += "/";
|
||||
dir_max += config_max;
|
||||
dir_max += "/";
|
||||
maxdir = dir_max;
|
||||
return dir_max;
|
||||
}
|
||||
|
||||
void cmLocalVisualStudio7Generator
|
||||
|
@ -1530,19 +1608,13 @@ void cmLocalVisualStudio7Generator
|
|||
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
|
||||
}
|
||||
|
||||
// Compute the maximum length full path to the intermediate
|
||||
// files directory for any configuration. This is used to construct
|
||||
// object file names that do not produce paths that are too long.
|
||||
std::string dir_max;
|
||||
this->ComputeMaxDirectoryLength(dir_max, target);
|
||||
|
||||
// Loop through each source in the source group.
|
||||
std::string objectName;
|
||||
for(std::vector<const cmSourceFile *>::const_iterator sf =
|
||||
sourceFiles.begin(); sf != sourceFiles.end(); ++sf)
|
||||
{
|
||||
std::string source = (*sf)->GetFullPath();
|
||||
FCInfo fcinfo(this, target, *(*sf), configs, dir_max);
|
||||
FCInfo fcinfo(this, target, *(*sf), configs);
|
||||
|
||||
if (source != libName || target.GetType() == cmTarget::UTILITY ||
|
||||
target.GetType() == cmTarget::GLOBAL_TARGET )
|
||||
|
|
|
@ -60,11 +60,7 @@ public:
|
|||
virtual std::string GetTargetDirectory(cmTarget const&) const;
|
||||
cmSourceFile* CreateVCProjBuildRule();
|
||||
void WriteStampFiles();
|
||||
// Compute the maximum length full path to the intermediate
|
||||
// files directory for any configuration. This is used to construct
|
||||
// object file names that do not produce paths that are too long.
|
||||
void ComputeMaxDirectoryLength(std::string& maxdir,
|
||||
cmTarget& target);
|
||||
virtual std::string ComputeLongestObjectDirectory(cmTarget&) const;
|
||||
|
||||
virtual void ReadAndStoreExternalGUID(const char* name,
|
||||
const char* path);
|
||||
|
|
|
@ -64,69 +64,6 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmTarget& target,
|
|||
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::ComputeObjectNameRequirements(
|
||||
std::vector<cmSourceFile*> const& sources
|
||||
)
|
||||
{
|
||||
// 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> counts;
|
||||
for(std::vector<cmSourceFile*>::const_iterator s = sources.begin();
|
||||
s != sources.end(); ++s)
|
||||
{
|
||||
const cmSourceFile* sf = *s;
|
||||
if(this->SourceFileCompiles(sf))
|
||||
{
|
||||
std::string objectName = cmSystemTools::LowerCase(
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(
|
||||
sf->GetFullPath()));
|
||||
objectName += ".obj";
|
||||
counts[objectName] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// For all source files producing duplicate names we need unique
|
||||
// object name computation.
|
||||
for(std::vector<cmSourceFile*>::const_iterator s = sources.begin();
|
||||
s != sources.end(); ++s)
|
||||
{
|
||||
const cmSourceFile* sf = *s;
|
||||
if(this->SourceFileCompiles(sf))
|
||||
{
|
||||
std::string objectName = cmSystemTools::LowerCase(
|
||||
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
|
||||
objectName += ".obj";
|
||||
if(counts[objectName] > 1)
|
||||
{
|
||||
this->NeedObjectName.insert(sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char* cmLocalVisualStudioGenerator::ReportErrorLabel() const
|
||||
{
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
/** Version of Visual Studio. */
|
||||
VSVersion GetVersion() const { return this->Version; }
|
||||
|
||||
virtual std::string ComputeLongestObjectDirectory(cmTarget&) const = 0;
|
||||
|
||||
protected:
|
||||
virtual const char* ReportErrorLabel() const;
|
||||
virtual bool CustomCommandUseLocal() const { return false; }
|
||||
|
@ -64,12 +66,6 @@ protected:
|
|||
cmsys::auto_ptr<cmCustomCommand>
|
||||
MaybeCreateImplibDir(cmTarget& target, const char* config, bool isFortran);
|
||||
|
||||
// Safe object file name generation.
|
||||
void ComputeObjectNameRequirements(std::vector<cmSourceFile*> const&);
|
||||
bool SourceFileCompiles(const cmSourceFile* sf);
|
||||
std::set<const cmSourceFile*> NeedObjectName;
|
||||
friend class cmVisualStudio10TargetGenerator;
|
||||
|
||||
VSVersion Version;
|
||||
};
|
||||
|
||||
|
|
|
@ -782,6 +782,7 @@ void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg)
|
|||
"\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$");
|
||||
this->AddSourceGroup("CMake Rules", "\\.rule$");
|
||||
this->AddSourceGroup("Resources", "\\.plist$");
|
||||
this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$");
|
||||
#endif
|
||||
|
||||
this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused();
|
||||
|
@ -853,6 +854,14 @@ cmMakefile::AddCustomCommandToTarget(const char* target,
|
|||
cmTargets::iterator ti = this->Targets.find(target);
|
||||
if(ti != this->Targets.end())
|
||||
{
|
||||
if(ti->second.GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Target \"" << target << "\" is an OBJECT library "
|
||||
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
|
||||
this->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
return;
|
||||
}
|
||||
// Add the command to the appropriate build step for the target.
|
||||
std::vector<std::string> no_output;
|
||||
cmCustomCommand cc(this, no_output, depends,
|
||||
|
@ -945,7 +954,7 @@ cmMakefile::AddCustomCommandToOutput(const std::vector<std::string>& outputs,
|
|||
outName += ".rule";
|
||||
const char* dir =
|
||||
this->LocalGenerator->GetGlobalGenerator()->
|
||||
GetCMakeCFGInitDirectory();
|
||||
GetCMakeCFGIntDir();
|
||||
if(dir && dir[0] == '$')
|
||||
{
|
||||
cmSystemTools::ReplaceString(outName, dir,
|
||||
|
@ -1912,8 +1921,11 @@ cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
|
|||
// wrong type ? default to STATIC
|
||||
if ( (type != cmTarget::STATIC_LIBRARY)
|
||||
&& (type != cmTarget::SHARED_LIBRARY)
|
||||
&& (type != cmTarget::MODULE_LIBRARY))
|
||||
&& (type != cmTarget::MODULE_LIBRARY)
|
||||
&& (type != cmTarget::OBJECT_LIBRARY))
|
||||
{
|
||||
this->IssueMessage(cmake::INTERNAL_ERROR,
|
||||
"cmMakefile::AddLibrary given invalid target type.");
|
||||
type = cmTarget::STATIC_LIBRARY;
|
||||
}
|
||||
|
||||
|
@ -2865,7 +2877,7 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const & lang,
|
|||
{
|
||||
this->AddDefinition("CMAKE_CFG_INTDIR",
|
||||
this->LocalGenerator->GetGlobalGenerator()
|
||||
->GetCMakeCFGInitDirectory());
|
||||
->GetCMakeCFGIntDir());
|
||||
this->LocalGenerator->GetGlobalGenerator()->EnableLanguage(lang, this,
|
||||
optional);
|
||||
}
|
||||
|
|
|
@ -101,6 +101,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
|
|||
this->WriteModuleLibraryRules(true);
|
||||
}
|
||||
break;
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
this->WriteObjectLibraryRules();
|
||||
break;
|
||||
default:
|
||||
// If language is not known, this is an error.
|
||||
cmSystemTools::Error("Unknown Library Type");
|
||||
|
@ -121,6 +124,29 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
|
|||
this->CloseFileStreams();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
|
||||
{
|
||||
std::vector<std::string> commands;
|
||||
std::vector<std::string> depends;
|
||||
|
||||
// Add post-build rules.
|
||||
this->LocalGenerator->
|
||||
AppendCustomCommands(commands, this->Target->GetPostBuildCommands(),
|
||||
this->Target);
|
||||
|
||||
// Depend on the object files.
|
||||
this->AppendObjectDepends(depends);
|
||||
|
||||
// Write the rule.
|
||||
this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
|
||||
this->Target->GetName(),
|
||||
depends, commands, true);
|
||||
|
||||
// Write the main driver rule to build everything in this target.
|
||||
this->WriteTargetDriverRule(this->Target->GetName(), false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
virtual void WriteRuleFiles();
|
||||
|
||||
protected:
|
||||
void WriteObjectLibraryRules();
|
||||
void WriteStaticLibraryRules();
|
||||
void WriteSharedLibraryRules(bool relink);
|
||||
void WriteModuleLibraryRules(bool relink);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
============================================================================*/
|
||||
#include "cmMakefileTargetGenerator.h"
|
||||
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGlobalGenerator.h"
|
||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||
|
@ -42,6 +43,7 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
|
|||
this->GlobalGenerator =
|
||||
static_cast<cmGlobalUnixMakefileGenerator3*>(
|
||||
this->LocalGenerator->GetGlobalGenerator());
|
||||
this->GeneratorTarget = this->GlobalGenerator->GetGeneratorTarget(target);
|
||||
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
|
||||
this->NoRuleMessages = false;
|
||||
if(const char* ruleStatus = cm->GetProperty("RULE_MESSAGES"))
|
||||
|
@ -63,6 +65,7 @@ cmMakefileTargetGenerator::New(cmTarget *tgt)
|
|||
case cmTarget::STATIC_LIBRARY:
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
result = new cmMakefileLibraryTargetGenerator(tgt);
|
||||
break;
|
||||
case cmTarget::UTILITY:
|
||||
|
@ -131,58 +134,49 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
|
|||
|
||||
// First generate the object rule files. Save a list of all object
|
||||
// files for this target.
|
||||
const std::vector<cmSourceFile*>& sources = this->Target->GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
|
||||
source != sources.end(); ++source)
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->CustomCommands.begin();
|
||||
si != this->GeneratorTarget->CustomCommands.end(); ++si)
|
||||
{
|
||||
cmTarget::SourceFileFlags tsFlags =
|
||||
this->Target->GetTargetSourceFileFlags(*source);
|
||||
if(cmCustomCommand* cc = (*source)->GetCustomCommand())
|
||||
cmCustomCommand const* cc = (*si)->GetCustomCommand();
|
||||
this->GenerateCustomRuleFile(*cc);
|
||||
if (clean)
|
||||
{
|
||||
this->GenerateCustomRuleFile(*cc);
|
||||
if (clean)
|
||||
const std::vector<std::string>& outputs = cc->GetOutputs();
|
||||
for(std::vector<std::string>::const_iterator o = outputs.begin();
|
||||
o != outputs.end(); ++o)
|
||||
{
|
||||
const std::vector<std::string>& outputs = cc->GetOutputs();
|
||||
for(std::vector<std::string>::const_iterator o = outputs.begin();
|
||||
o != outputs.end(); ++o)
|
||||
{
|
||||
this->CleanFiles.push_back
|
||||
(this->Convert(o->c_str(),
|
||||
cmLocalGenerator::START_OUTPUT,
|
||||
cmLocalGenerator::UNCHANGED));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
|
||||
{
|
||||
this->WriteMacOSXContentRules(*(*source), tsFlags.MacFolder);
|
||||
}
|
||||
else if(!(*source)->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
||||
{
|
||||
if(!this->GlobalGenerator->IgnoreFile
|
||||
((*source)->GetExtension().c_str()))
|
||||
{
|
||||
// Generate this object file's rule file.
|
||||
this->WriteObjectRuleFiles(*(*source));
|
||||
}
|
||||
else if((*source)->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
||||
{
|
||||
// This is an external object file. Just add it.
|
||||
this->ExternalObjects.push_back((*source)->GetFullPath());
|
||||
}
|
||||
else if(cmSystemTools::UpperCase((*source)->GetExtension()) == "DEF")
|
||||
{
|
||||
this->ModuleDefinitionFile = (*source)->GetFullPath();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We only get here if a source file is not an external object
|
||||
// and has an extension that is listed as an ignored file type
|
||||
// for this language. No message or diagnosis should be
|
||||
// given.
|
||||
this->CleanFiles.push_back
|
||||
(this->Convert(o->c_str(),
|
||||
cmLocalGenerator::START_OUTPUT,
|
||||
cmLocalGenerator::UNCHANGED));
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->OSXContent.begin();
|
||||
si != this->GeneratorTarget->OSXContent.end(); ++si)
|
||||
{
|
||||
cmTarget::SourceFileFlags tsFlags =
|
||||
this->Target->GetTargetSourceFileFlags(*si);
|
||||
this->WriteMacOSXContentRules(**si, tsFlags.MacFolder);
|
||||
}
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->ExternalObjects.begin();
|
||||
si != this->GeneratorTarget->ExternalObjects.end(); ++si)
|
||||
{
|
||||
this->ExternalObjects.push_back((*si)->GetFullPath());
|
||||
}
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->ObjectSources.begin();
|
||||
si != this->GeneratorTarget->ObjectSources.end(); ++si)
|
||||
{
|
||||
// Generate this object file's rule file.
|
||||
this->WriteObjectRuleFiles(**si);
|
||||
}
|
||||
|
||||
// Add object library contents as external objects.
|
||||
this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
|
||||
}
|
||||
|
||||
|
||||
|
@ -428,12 +422,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
|
|||
}
|
||||
|
||||
// Get the full path name of the object file.
|
||||
bool hasSourceExtension;
|
||||
std::string objNoTargetDir;
|
||||
std::string obj =
|
||||
this->LocalGenerator->GetObjectFileName(*this->Target, source,
|
||||
&objNoTargetDir,
|
||||
&hasSourceExtension);
|
||||
std::string const& objectName = this->GeneratorTarget->Objects[&source];
|
||||
std::string obj = this->LocalGenerator->GetTargetDirectory(*this->Target);
|
||||
obj += "/";
|
||||
obj += objectName;
|
||||
|
||||
// Avoid generating duplicate rules.
|
||||
if(this->ObjectFiles.find(obj) == this->ObjectFiles.end())
|
||||
|
@ -487,10 +479,6 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(cmSourceFile& source)
|
|||
AddImplicitDepends(*this->Target, lang,
|
||||
objFullPath.c_str(),
|
||||
srcFullPath.c_str());
|
||||
|
||||
// add this to the list of objects for this local generator
|
||||
this->LocalGenerator->AddLocalObjectFile(
|
||||
this->Target, &source, objNoTargetDir, hasSourceExtension);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1612,7 +1600,7 @@ void cmMakefileTargetGenerator
|
|||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefileTargetGenerator
|
||||
::AppendLinkDepends(std::vector<std::string>& depends)
|
||||
::AppendObjectDepends(std::vector<std::string>& depends)
|
||||
{
|
||||
// Add dependencies on the compiled object files.
|
||||
std::string relPath = this->LocalGenerator->GetHomeRelativeOutputPath();
|
||||
|
@ -1625,19 +1613,6 @@ void cmMakefileTargetGenerator
|
|||
depends.push_back(objTarget);
|
||||
}
|
||||
|
||||
// Add dependencies on targets that must be built first.
|
||||
this->AppendTargetDepends(depends);
|
||||
|
||||
// Add a dependency on the rule file itself.
|
||||
this->LocalGenerator->AppendRuleDepend(depends,
|
||||
this->BuildFileNameFull.c_str());
|
||||
|
||||
// Add a dependency on the link definitions file, if any.
|
||||
if(!this->ModuleDefinitionFile.empty())
|
||||
{
|
||||
depends.push_back(this->ModuleDefinitionFile);
|
||||
}
|
||||
|
||||
// Add dependencies on the external object files.
|
||||
for(std::vector<std::string>::const_iterator obj
|
||||
= this->ExternalObjects.begin();
|
||||
|
@ -1646,6 +1621,26 @@ void cmMakefileTargetGenerator
|
|||
depends.push_back(*obj);
|
||||
}
|
||||
|
||||
// Add a dependency on the rule file itself.
|
||||
this->LocalGenerator->AppendRuleDepend(depends,
|
||||
this->BuildFileNameFull.c_str());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefileTargetGenerator
|
||||
::AppendLinkDepends(std::vector<std::string>& depends)
|
||||
{
|
||||
this->AppendObjectDepends(depends);
|
||||
|
||||
// Add dependencies on targets that must be built first.
|
||||
this->AppendTargetDepends(depends);
|
||||
|
||||
// Add a dependency on the link definitions file, if any.
|
||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
{
|
||||
depends.push_back(this->GeneratorTarget->ModuleDefinitionFile);
|
||||
}
|
||||
|
||||
// Add user-specified dependencies.
|
||||
if(const char* linkDepends =
|
||||
this->Target->GetProperty("LINK_DEPENDS"))
|
||||
|
@ -1971,7 +1966,7 @@ void cmMakefileTargetGenerator::AddFortranFlags(std::string& flags)
|
|||
//----------------------------------------------------------------------------
|
||||
void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
||||
{
|
||||
if(this->ModuleDefinitionFile.empty())
|
||||
if(this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1988,7 +1983,7 @@ void cmMakefileTargetGenerator::AddModuleDefinitionFlag(std::string& flags)
|
|||
// vs6's "cl -link" pass it to the linker.
|
||||
std::string flag = defFileFlag;
|
||||
flag += (this->LocalGenerator->ConvertToLinkReference(
|
||||
this->ModuleDefinitionFile.c_str()));
|
||||
this->GeneratorTarget->ModuleDefinitionFile.c_str()));
|
||||
this->LocalGenerator->AppendFlags(flags, flag.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
class cmCustomCommand;
|
||||
class cmDependInformation;
|
||||
class cmDepends;
|
||||
class cmGeneratorTarget;
|
||||
class cmGeneratedFileStream;
|
||||
class cmGlobalUnixMakefileGenerator3;
|
||||
class cmLocalUnixMakefileGenerator3;
|
||||
|
@ -117,6 +118,9 @@ protected:
|
|||
// append intertarget dependencies
|
||||
void AppendTargetDepends(std::vector<std::string>& depends);
|
||||
|
||||
// Append object file dependencies.
|
||||
void AppendObjectDepends(std::vector<std::string>& depends);
|
||||
|
||||
// Append link rule dependencies (objects, etc.).
|
||||
void AppendLinkDepends(std::vector<std::string>& depends);
|
||||
|
||||
|
@ -157,6 +161,7 @@ protected:
|
|||
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
|
||||
std::string& linkFlags);
|
||||
cmTarget *Target;
|
||||
cmGeneratorTarget* GeneratorTarget;
|
||||
cmLocalUnixMakefileGenerator3 *LocalGenerator;
|
||||
cmGlobalUnixMakefileGenerator3 *GlobalGenerator;
|
||||
cmMakefile *Makefile;
|
||||
|
@ -198,9 +203,6 @@ protected:
|
|||
std::vector<std::string> Objects;
|
||||
std::vector<std::string> ExternalObjects;
|
||||
|
||||
// The windows module definition source file (.def), if any.
|
||||
std::string ModuleDefinitionFile;
|
||||
|
||||
// Set of object file names that will be built in this directory.
|
||||
std::set<cmStdString> ObjectFiles;
|
||||
|
||||
|
|
|
@ -43,10 +43,13 @@ cmNinjaNormalTargetGenerator(cmTarget* target)
|
|||
this->TargetNamePDB,
|
||||
GetLocalGenerator()->GetConfigName());
|
||||
|
||||
// on Windows the output dir is already needed at compile time
|
||||
// ensure the directory exists (OutDir test)
|
||||
std::string outpath = target->GetDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(outpath.c_str());
|
||||
if(target->GetType() != cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
// on Windows the output dir is already needed at compile time
|
||||
// ensure the directory exists (OutDir test)
|
||||
std::string outpath = target->GetDirectory(this->GetConfigName());
|
||||
cmSystemTools::MakeDirectory(outpath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator()
|
||||
|
@ -67,8 +70,15 @@ void cmNinjaNormalTargetGenerator::Generate()
|
|||
// Write the build statements
|
||||
this->WriteObjectBuildStatements();
|
||||
|
||||
this->WriteLinkRule();
|
||||
this->WriteLinkStatement();
|
||||
if(this->GetTarget()->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
this->WriteObjectLibStatement();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->WriteLinkRule();
|
||||
this->WriteLinkStatement();
|
||||
}
|
||||
|
||||
this->GetBuildFileStream() << "\n";
|
||||
this->GetRulesFileStream() << "\n";
|
||||
|
@ -467,3 +477,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
|
|||
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
|
||||
this->GetTarget());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
|
||||
{
|
||||
// Write a phony output that depends on all object files.
|
||||
cmNinjaDeps outputs;
|
||||
this->GetLocalGenerator()->AppendTargetOutputs(this->GetTarget(), outputs);
|
||||
cmNinjaDeps depends = this->GetObjects();
|
||||
cmGlobalNinjaGenerator::WritePhonyBuild(this->GetBuildFileStream(),
|
||||
"Object library "
|
||||
+ this->GetTargetName(),
|
||||
outputs,
|
||||
depends);
|
||||
|
||||
// Add aliases for the target name.
|
||||
this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
|
||||
this->GetTarget());
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
void WriteLanguagesRules();
|
||||
void WriteLinkRule();
|
||||
void WriteLinkStatement();
|
||||
void WriteObjectLibStatement();
|
||||
std::vector<std::string> ComputeLinkCmd();
|
||||
|
||||
private:
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "cmGlobalNinjaGenerator.h"
|
||||
#include "cmLocalNinjaGenerator.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmNinjaNormalTargetGenerator.h"
|
||||
#include "cmNinjaUtilityTargetGenerator.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
@ -33,6 +34,7 @@ cmNinjaTargetGenerator::New(cmTarget* target)
|
|||
case cmTarget::SHARED_LIBRARY:
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
case cmTarget::MODULE_LIBRARY:
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
return new cmNinjaNormalTargetGenerator(target);
|
||||
|
||||
case cmTarget::UTILITY:
|
||||
|
@ -60,6 +62,8 @@ cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
|
|||
static_cast<cmLocalNinjaGenerator*>(Makefile->GetLocalGenerator())),
|
||||
Objects()
|
||||
{
|
||||
this->GeneratorTarget =
|
||||
this->GetGlobalGenerator()->GetGeneratorTarget(target);
|
||||
}
|
||||
|
||||
cmNinjaTargetGenerator::~cmNinjaTargetGenerator()
|
||||
|
@ -218,7 +222,8 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
|
|||
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
|
||||
{
|
||||
// Static libraries never depend on other targets for linking.
|
||||
if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
|
||||
if (this->Target->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
return cmNinjaDeps();
|
||||
|
||||
cmComputeLinkInformation* cli =
|
||||
|
@ -231,9 +236,9 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const
|
|||
std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath());
|
||||
|
||||
// Add a dependency on the link definitions file, if any.
|
||||
if(!this->ModuleDefinitionFile.empty())
|
||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
{
|
||||
result.push_back(this->ModuleDefinitionFile);
|
||||
result.push_back(this->GeneratorTarget->ModuleDefinitionFile);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -253,7 +258,10 @@ cmNinjaTargetGenerator
|
|||
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
|
||||
if(!path.empty())
|
||||
path += "/";
|
||||
path += this->LocalGenerator->GetObjectFileName(*this->Target, *source);
|
||||
std::string const& objectName = this->GeneratorTarget->Objects[source];
|
||||
path += this->LocalGenerator->GetTargetDirectory(*this->Target);
|
||||
path += "/";
|
||||
path += objectName;
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -377,12 +385,37 @@ cmNinjaTargetGenerator
|
|||
<< this->GetTargetName()
|
||||
<< "\n\n";
|
||||
|
||||
// For each source files of this target.
|
||||
for(std::vector<cmSourceFile*>::const_iterator i =
|
||||
this->GetTarget()->GetSourceFiles().begin();
|
||||
i != this->GetTarget()->GetSourceFiles().end();
|
||||
++i)
|
||||
this->WriteObjectBuildStatement(*i);
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->CustomCommands.begin();
|
||||
si != this->GeneratorTarget->CustomCommands.end(); ++si)
|
||||
{
|
||||
cmCustomCommand const* cc = (*si)->GetCustomCommand();
|
||||
this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
|
||||
}
|
||||
// TODO: this->GeneratorTarget->OSXContent
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->ExternalObjects.begin();
|
||||
si != this->GeneratorTarget->ExternalObjects.end(); ++si)
|
||||
{
|
||||
this->Objects.push_back(this->GetSourceFilePath(*si));
|
||||
}
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->ObjectSources.begin();
|
||||
si != this->GeneratorTarget->ObjectSources.end(); ++si)
|
||||
{
|
||||
this->WriteObjectBuildStatement(*si);
|
||||
}
|
||||
|
||||
{
|
||||
// Add object library contents as external objects.
|
||||
std::vector<std::string> objs;
|
||||
this->GeneratorTarget->UseObjectLibraries(objs);
|
||||
for(std::vector<std::string>::iterator oi = objs.begin();
|
||||
oi != objs.end(); ++oi)
|
||||
{
|
||||
this->Objects.push_back(ConvertToNinjaPath(oi->c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
this->GetBuildFileStream() << "\n";
|
||||
}
|
||||
|
@ -391,26 +424,10 @@ void
|
|||
cmNinjaTargetGenerator
|
||||
::WriteObjectBuildStatement(cmSourceFile* source)
|
||||
{
|
||||
if (cmCustomCommand *cc = source->GetCustomCommand())
|
||||
this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
|
||||
|
||||
cmNinjaDeps emptyDeps;
|
||||
|
||||
std::string comment;
|
||||
const char* language = source->GetLanguage();
|
||||
// If we cannot get the language this is probably a non-source file provided
|
||||
// in the list (typically an header file).
|
||||
if (!language) {
|
||||
if (source->GetPropertyAsBool("EXTERNAL_OBJECT"))
|
||||
this->Objects.push_back(this->GetSourceFilePath(source));
|
||||
if(cmSystemTools::UpperCase(source->GetExtension()) == "DEF")
|
||||
this->ModuleDefinitionFile = GetSourceFilePath(source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (source->GetPropertyAsBool("HEADER_FILE_ONLY"))
|
||||
return;
|
||||
|
||||
std::string rule = this->LanguageCompilerRule(language);
|
||||
|
||||
cmNinjaDeps outputs;
|
||||
|
@ -435,21 +452,16 @@ cmNinjaTargetGenerator
|
|||
std::back_inserter(orderOnlyDeps), MapToNinjaPath());
|
||||
}
|
||||
|
||||
// Add order-only dependency on any header file with a custom command.
|
||||
{
|
||||
const std::vector<cmSourceFile*>& sources =
|
||||
this->GetTarget()->GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator si = sources.begin();
|
||||
si != sources.end(); ++si) {
|
||||
if (!(*si)->GetLanguage()) {
|
||||
if (cmCustomCommand* cc = (*si)->GetCustomCommand()) {
|
||||
const std::vector<std::string>& ccoutputs = cc->GetOutputs();
|
||||
std::transform(ccoutputs.begin(), ccoutputs.end(),
|
||||
std::back_inserter(orderOnlyDeps), MapToNinjaPath());
|
||||
}
|
||||
}
|
||||
// Add order-only dependencies on custom command outputs.
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->CustomCommands.begin();
|
||||
si != this->GeneratorTarget->CustomCommands.end(); ++si)
|
||||
{
|
||||
cmCustomCommand const* cc = (*si)->GetCustomCommand();
|
||||
const std::vector<std::string>& ccoutputs = cc->GetOutputs();
|
||||
std::transform(ccoutputs.begin(), ccoutputs.end(),
|
||||
std::back_inserter(orderOnlyDeps), MapToNinjaPath());
|
||||
}
|
||||
}
|
||||
|
||||
// If the source file is GENERATED and does not have a custom command
|
||||
// (either attached to this source file or another one), assume that one of
|
||||
|
@ -493,7 +505,7 @@ void
|
|||
cmNinjaTargetGenerator
|
||||
::AddModuleDefinitionFlag(std::string& flags)
|
||||
{
|
||||
if(this->ModuleDefinitionFile.empty())
|
||||
if(this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -510,6 +522,6 @@ cmNinjaTargetGenerator
|
|||
// vs6's "cl -link" pass it to the linker.
|
||||
std::string flag = defFileFlag;
|
||||
flag += (this->LocalGenerator->ConvertToLinkReference(
|
||||
this->ModuleDefinitionFile.c_str()));
|
||||
this->GeneratorTarget->ModuleDefinitionFile.c_str()));
|
||||
this->LocalGenerator->AppendFlags(flags, flag.c_str());
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
class cmTarget;
|
||||
class cmGlobalNinjaGenerator;
|
||||
class cmGeneratedFileStream;
|
||||
class cmGeneratorTarget;
|
||||
class cmMakefile;
|
||||
class cmSourceFile;
|
||||
class cmCustomCommand;
|
||||
|
@ -112,13 +113,11 @@ protected:
|
|||
|
||||
private:
|
||||
cmTarget* Target;
|
||||
cmGeneratorTarget* GeneratorTarget;
|
||||
cmMakefile* Makefile;
|
||||
cmLocalNinjaGenerator* LocalGenerator;
|
||||
/// List of object files for this target.
|
||||
cmNinjaDeps Objects;
|
||||
|
||||
// The windows module definition source file (.def), if any.
|
||||
std::string ModuleDefinitionFile;
|
||||
};
|
||||
|
||||
#endif // ! cmNinjaTargetGenerator_h
|
||||
|
|
|
@ -119,12 +119,6 @@ const std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles() const
|
|||
return this->SourceFiles;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::vector<const cmSourceFile*>& cmSourceGroup::GetSourceFiles()
|
||||
{
|
||||
return this->SourceFiles;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSourceGroup::AddChild(cmSourceGroup child)
|
||||
{
|
||||
|
|
|
@ -100,7 +100,6 @@ public:
|
|||
* source group.
|
||||
*/
|
||||
const std::vector<const cmSourceFile*>& GetSourceFiles() const;
|
||||
std::vector<const cmSourceFile*>& GetSourceFiles();
|
||||
|
||||
std::vector<cmSourceGroup> const& GetGroupChildren() const;
|
||||
private:
|
||||
|
|
|
@ -37,6 +37,8 @@ const char* cmTarget::GetTargetTypeName(TargetType targetType)
|
|||
return "MODULE_LIBRARY";
|
||||
case cmTarget::SHARED_LIBRARY:
|
||||
return "SHARED_LIBRARY";
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
return "OBJECT_LIBRARY";
|
||||
case cmTarget::EXECUTABLE:
|
||||
return "EXECUTABLE";
|
||||
case cmTarget::UTILITY:
|
||||
|
@ -1727,7 +1729,15 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs)
|
|||
for(std::vector<std::string>::const_iterator i = srcs.begin();
|
||||
i != srcs.end(); ++i)
|
||||
{
|
||||
this->AddSource(i->c_str());
|
||||
const char* src = i->c_str();
|
||||
if(src[0] == '$' && src[1] == '<')
|
||||
{
|
||||
this->ProcessSourceExpression(*i);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->AddSource(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1745,6 +1755,24 @@ cmSourceFile* cmTarget::AddSource(const char* s)
|
|||
return sf;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmTarget::ProcessSourceExpression(std::string const& expr)
|
||||
{
|
||||
if(strncmp(expr.c_str(), "$<TARGET_OBJECTS:", 17) == 0 &&
|
||||
expr[expr.size()-1] == '>')
|
||||
{
|
||||
std::string objLibName = expr.substr(17, expr.size()-18);
|
||||
this->ObjectLibraries.push_back(objLibName);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Unrecognized generator expression:\n"
|
||||
<< " " << expr;
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
struct cmTarget::SourceFileFlags
|
||||
cmTarget::GetTargetSourceFileFlags(const cmSourceFile* sf)
|
||||
|
@ -4545,7 +4573,21 @@ void cmTarget::ComputeLinkImplementation(const char* config,
|
|||
|
||||
// This target needs runtime libraries for its source languages.
|
||||
std::set<cmStdString> languages;
|
||||
// Get languages used in our source files.
|
||||
this->GetLanguages(languages);
|
||||
// Get languages used in object library sources.
|
||||
for(std::vector<std::string>::iterator i = this->ObjectLibraries.begin();
|
||||
i != this->ObjectLibraries.end(); ++i)
|
||||
{
|
||||
if(cmTarget* objLib = this->Makefile->FindTargetToUse(i->c_str()))
|
||||
{
|
||||
if(objLib->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
objLib->GetLanguages(languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Copy the set of langauges to the link implementation.
|
||||
for(std::set<cmStdString>::iterator li = languages.begin();
|
||||
li != languages.end(); ++li)
|
||||
{
|
||||
|
|
|
@ -59,7 +59,8 @@ class cmTarget
|
|||
public:
|
||||
cmTarget();
|
||||
enum TargetType { EXECUTABLE, STATIC_LIBRARY,
|
||||
SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET,
|
||||
SHARED_LIBRARY, MODULE_LIBRARY,
|
||||
OBJECT_LIBRARY, UTILITY, GLOBAL_TARGET,
|
||||
UNKNOWN_LIBRARY};
|
||||
static const char* GetTargetTypeName(TargetType targetType);
|
||||
enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD };
|
||||
|
@ -116,6 +117,10 @@ public:
|
|||
*/
|
||||
std::vector<cmSourceFile*> const& GetSourceFiles();
|
||||
void AddSourceFile(cmSourceFile* sf);
|
||||
std::vector<std::string> const& GetObjectLibraries() const
|
||||
{
|
||||
return this->ObjectLibraries;
|
||||
}
|
||||
|
||||
/** Get sources that must be built before the given source. */
|
||||
std::vector<cmSourceFile*> const* GetSourceDepends(cmSourceFile* sf);
|
||||
|
@ -548,6 +553,7 @@ private:
|
|||
std::vector<cmCustomCommand> PostBuildCommands;
|
||||
TargetType TargetTypeValue;
|
||||
std::vector<cmSourceFile*> SourceFiles;
|
||||
std::vector<std::string> ObjectLibraries;
|
||||
LinkLibraryVectorType LinkLibraries;
|
||||
LinkLibraryVectorType PrevLinkedLibraries;
|
||||
bool LinkLibrariesAnalyzed;
|
||||
|
@ -589,6 +595,8 @@ private:
|
|||
|
||||
void MaybeInvalidatePropertyCache(const char* prop);
|
||||
|
||||
void ProcessSourceExpression(std::string const& expr);
|
||||
|
||||
// The cmMakefile instance that owns this target. This should
|
||||
// always be set.
|
||||
cmMakefile* Makefile;
|
||||
|
|
|
@ -84,6 +84,16 @@ bool cmTargetLinkLibrariesCommand
|
|||
return true;
|
||||
}
|
||||
|
||||
if(this->Target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
cmOStringStream e;
|
||||
e << "Object library target \"" << args[0] << "\" "
|
||||
<< "may not link to anything.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
return true;
|
||||
}
|
||||
|
||||
// but we might not have any libs after variable expansion
|
||||
if(args.size() < 2)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
============================================================================*/
|
||||
#include "cmVisualStudio10TargetGenerator.h"
|
||||
#include "cmGlobalVisualStudio10Generator.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmComputeLinkInformation.h"
|
||||
#include "cmGeneratedFileStream.h"
|
||||
|
@ -62,6 +63,7 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
|
|||
{
|
||||
this->GlobalGenerator = gg;
|
||||
this->Target = target;
|
||||
this->GeneratorTarget = gg->GetGeneratorTarget(target);
|
||||
this->Makefile = target->GetMakefile();
|
||||
this->LocalGenerator =
|
||||
(cmLocalVisualStudio7Generator*)
|
||||
|
@ -70,7 +72,6 @@ cmVisualStudio10TargetGenerator(cmTarget* target,
|
|||
this->GlobalGenerator->CreateGUID(this->Name.c_str());
|
||||
this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
|
||||
this->Platform = gg->GetPlatformName();
|
||||
this->ComputeObjectNames();
|
||||
this->BuildFileStream = 0;
|
||||
}
|
||||
|
||||
|
@ -147,7 +148,7 @@ void cmVisualStudio10TargetGenerator::Generate()
|
|||
this->Target->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str());
|
||||
this->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
|
||||
".vcxproj");
|
||||
if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY)
|
||||
if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
if(!this->ComputeClOptions())
|
||||
{
|
||||
|
@ -358,6 +359,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
|
|||
case cmTarget::MODULE_LIBRARY:
|
||||
configType += "DynamicLibrary";
|
||||
break;
|
||||
case cmTarget::OBJECT_LIBRARY:
|
||||
case cmTarget::STATIC_LIBRARY:
|
||||
configType += "StaticLibrary";
|
||||
break;
|
||||
|
@ -388,7 +390,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
|
|||
mfcLine += useOfMfcValue + "</UseOfMfc>\n";
|
||||
this->WriteString(mfcLine.c_str(), 2);
|
||||
|
||||
if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY &&
|
||||
if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY &&
|
||||
this->ClOptions[*i]->UsingUnicode() ||
|
||||
this->Target->GetPropertyAsBool("VS_WINRT_EXTENSIONS"))
|
||||
{
|
||||
|
@ -421,12 +423,11 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
|
|||
void cmVisualStudio10TargetGenerator::WriteCustomCommands()
|
||||
{
|
||||
this->SourcesVisited.clear();
|
||||
std::vector<cmSourceFile*> const& sources = this->Target->GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator source = sources.begin();
|
||||
source != sources.end(); ++source)
|
||||
for(std::vector<cmSourceFile*>::const_iterator
|
||||
si = this->GeneratorTarget->CustomCommands.begin();
|
||||
si != this->GeneratorTarget->CustomCommands.end(); ++si)
|
||||
{
|
||||
cmSourceFile* sf = *source;
|
||||
this->WriteCustomCommand(sf);
|
||||
this->WriteCustomCommand(*si);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -634,6 +635,25 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
|
|||
this->WriteGroupSources("Midl", idls, sourceGroups);
|
||||
this->WriteGroupSources("CustomBuild", customBuild, sourceGroups);
|
||||
|
||||
// Add object library contents as external objects.
|
||||
std::vector<std::string> objs;
|
||||
this->GeneratorTarget->UseObjectLibraries(objs);
|
||||
if(!objs.empty())
|
||||
{
|
||||
this->WriteString("<ItemGroup>\n", 1);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
std::string obj = *oi;
|
||||
this->WriteString("<Object Include=\"", 2);
|
||||
this->ConvertToWindowsSlash(obj);
|
||||
(*this->BuildFileStream ) << obj << "\">\n";
|
||||
this->WriteString("<Filter>Object Libraries</Filter>\n", 3);
|
||||
this->WriteString("</Object>\n", 2);
|
||||
}
|
||||
this->WriteString("</ItemGroup>\n", 1);
|
||||
}
|
||||
|
||||
this->WriteString("<ItemGroup>\n", 1);
|
||||
for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
|
||||
g != groupsUsed.end(); ++g)
|
||||
|
@ -657,6 +677,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
|
|||
this->WriteString("</Filter>\n", 2);
|
||||
}
|
||||
}
|
||||
if(!objs.empty())
|
||||
{
|
||||
this->WriteString("<Filter Include=\"Object Libraries\">\n", 2);
|
||||
std::string guidName = "SG_Filter_Object Libraries";
|
||||
this->GlobalGenerator->CreateGUID(guidName.c_str());
|
||||
this->WriteString("<UniqueIdentifier>", 3);
|
||||
std::string guid =
|
||||
this->GlobalGenerator->GetGUID(guidName.c_str());
|
||||
(*this->BuildFileStream) << "{" << guid << "}"
|
||||
<< "</UniqueIdentifier>\n";
|
||||
this->WriteString("</Filter>\n", 2);
|
||||
}
|
||||
this->WriteString("</ItemGroup>\n", 1);
|
||||
this->WriteGroupSources("None", none, sourceGroups);
|
||||
this->WriteString("</Project>\n", 0);
|
||||
|
@ -872,26 +904,20 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
|
|||
(*this->BuildFileStream ) << " />\n";
|
||||
}
|
||||
}
|
||||
this->WriteString("</ItemGroup>\n", 1);
|
||||
}
|
||||
|
||||
void cmVisualStudio10TargetGenerator::ComputeObjectNames()
|
||||
{
|
||||
// get the classes from the source lists then add them to the groups
|
||||
std::vector<cmSourceFile*>const & classes = this->Target->GetSourceFiles();
|
||||
for(std::vector<cmSourceFile*>::const_iterator i = classes.begin();
|
||||
i != classes.end(); i++)
|
||||
// Add object library contents as external objects.
|
||||
std::vector<std::string> objs;
|
||||
this->GeneratorTarget->UseObjectLibraries(objs);
|
||||
for(std::vector<std::string>::const_iterator
|
||||
oi = objs.begin(); oi != objs.end(); ++oi)
|
||||
{
|
||||
// Add the file to the list of sources.
|
||||
std::string source = (*i)->GetFullPath();
|
||||
if(cmSystemTools::UpperCase((*i)->GetExtension()) == "DEF")
|
||||
{
|
||||
this->ModuleDefinitionFile = (*i)->GetFullPath();
|
||||
}
|
||||
std::string obj = *oi;
|
||||
this->WriteString("<Object Include=\"", 2);
|
||||
this->ConvertToWindowsSlash(obj);
|
||||
(*this->BuildFileStream ) << obj << "\" />\n";
|
||||
}
|
||||
|
||||
// Compute which sources need unique object computation.
|
||||
this->LocalGenerator->ComputeObjectNameRequirements(classes);
|
||||
this->WriteString("</ItemGroup>\n", 1);
|
||||
}
|
||||
|
||||
bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
||||
|
@ -900,16 +926,11 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
|
|||
cmSourceFile& sf = *source;
|
||||
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
|
||||
|
||||
// Compute the maximum length full path to the intermediate
|
||||
// files directory for any configuration. This is used to construct
|
||||
// object file names that do not produce paths that are too long.
|
||||
std::string dir_max;
|
||||
lg->ComputeMaxDirectoryLength(dir_max, *this->Target);
|
||||
|
||||
std::string objectName;
|
||||
if(lg->NeedObjectName.find(&sf) != lg->NeedObjectName.end())
|
||||
if(this->GeneratorTarget->ExplicitObjectName.find(&sf)
|
||||
!= this->GeneratorTarget->ExplicitObjectName.end())
|
||||
{
|
||||
objectName = lg->GetObjectFileNameWithoutTarget(sf, dir_max);
|
||||
objectName = this->GeneratorTarget->Objects[&sf];
|
||||
}
|
||||
std::string flags;
|
||||
std::string defines;
|
||||
|
@ -1030,20 +1051,29 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions()
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string targetNameFull =
|
||||
this->Target->GetFullName(config->c_str());
|
||||
std::string intermediateDir = this->LocalGenerator->
|
||||
GetTargetDirectory(*this->Target);
|
||||
intermediateDir += "/";
|
||||
intermediateDir += *config;
|
||||
intermediateDir += "/";
|
||||
std::string outDir;
|
||||
std::string targetNameFull;
|
||||
if(ttype == cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
outDir = intermediateDir;
|
||||
targetNameFull = this->Target->GetName();
|
||||
targetNameFull += ".lib";
|
||||
}
|
||||
else
|
||||
{
|
||||
outDir = this->Target->GetDirectory(config->c_str()) + "/";
|
||||
targetNameFull = this->Target->GetFullName(config->c_str());
|
||||
}
|
||||
this->ConvertToWindowsSlash(intermediateDir);
|
||||
std::string outDir = this->Target->GetDirectory(config->c_str());
|
||||
this->ConvertToWindowsSlash(outDir);
|
||||
|
||||
this->WritePlatformConfigTag("OutDir", config->c_str(), 3);
|
||||
*this->BuildFileStream << outDir
|
||||
<< "\\"
|
||||
<< "</OutDir>\n";
|
||||
|
||||
this->WritePlatformConfigTag("IntDir", config->c_str(), 3);
|
||||
|
@ -1277,11 +1307,15 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
|
|||
*this->BuildFileStream << configName
|
||||
<< "</AssemblerListingLocation>\n";
|
||||
this->WriteString("<ObjectFileName>$(IntDir)</ObjectFileName>\n", 3);
|
||||
this->WriteString("<ProgramDataBaseFileName>", 3);
|
||||
*this->BuildFileStream << this->Target->GetDirectory(configName.c_str())
|
||||
<< "/"
|
||||
<< this->Target->GetPDBName(configName.c_str())
|
||||
<< "</ProgramDataBaseFileName>\n";
|
||||
if(this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
// TODO: PDB for object library?
|
||||
this->WriteString("<ProgramDataBaseFileName>", 3);
|
||||
*this->BuildFileStream << this->Target->GetDirectory(configName.c_str())
|
||||
<< "/"
|
||||
<< this->Target->GetPDBName(configName.c_str())
|
||||
<< "</ProgramDataBaseFileName>\n";
|
||||
}
|
||||
this->WriteString("</ClCompile>\n", 2);
|
||||
}
|
||||
|
||||
|
@ -1513,10 +1547,10 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
|
|||
linkOptions.AddFlag("ImportLibrary", imLib.c_str());
|
||||
linkOptions.AddFlag("ProgramDataBaseFile", pdb.c_str());
|
||||
linkOptions.Parse(flags.c_str());
|
||||
if(!this->ModuleDefinitionFile.empty())
|
||||
if(!this->GeneratorTarget->ModuleDefinitionFile.empty())
|
||||
{
|
||||
linkOptions.AddFlag("ModuleDefinitionFile",
|
||||
this->ModuleDefinitionFile.c_str());
|
||||
this->GeneratorTarget->ModuleDefinitionFile.c_str());
|
||||
}
|
||||
|
||||
linkOptions.RemoveFlag("GenerateManifest");
|
||||
|
@ -1592,7 +1626,7 @@ void cmVisualStudio10TargetGenerator::WriteItemDefinitionGroups()
|
|||
this->WritePlatformConfigTag("ItemDefinitionGroup", i->c_str(), 1);
|
||||
*this->BuildFileStream << "\n";
|
||||
// output cl compile flags <ClCompile></ClCompile>
|
||||
if(this->Target->GetType() <= cmTarget::MODULE_LIBRARY)
|
||||
if(this->Target->GetType() <= cmTarget::OBJECT_LIBRARY)
|
||||
{
|
||||
this->WriteClOptions(*i, includes);
|
||||
// output rc compile flags <ResourceCompile></ResourceCompile>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
class cmTarget;
|
||||
class cmMakefile;
|
||||
class cmGeneratorTarget;
|
||||
class cmGeneratedFileStream;
|
||||
class cmGlobalVisualStudio10Generator;
|
||||
class cmSourceFile;
|
||||
|
@ -75,7 +76,6 @@ private:
|
|||
void WriteEvents(std::string const& configName);
|
||||
void WriteEvent(const char* name, std::vector<cmCustomCommand> & commands,
|
||||
std::string const& configName);
|
||||
void ComputeObjectNames();
|
||||
void WriteGroupSources(const char* name,
|
||||
std::vector<cmSourceFile*> const& sources,
|
||||
std::vector<cmSourceGroup>& );
|
||||
|
@ -87,9 +87,9 @@ private:
|
|||
typedef cmVisualStudioGeneratorOptions Options;
|
||||
typedef std::map<cmStdString, Options*> OptionsMap;
|
||||
OptionsMap ClOptions;
|
||||
std::string ModuleDefinitionFile;
|
||||
std::string PathToVcxproj;
|
||||
cmTarget* Target;
|
||||
cmGeneratorTarget* GeneratorTarget;
|
||||
cmMakefile* Makefile;
|
||||
std::string Platform;
|
||||
std::string GUID;
|
||||
|
|
|
@ -199,6 +199,7 @@ IF(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(CxxOnly CxxOnly)
|
||||
ADD_TEST_MACRO(IPO COnly/COnly)
|
||||
ADD_TEST_MACRO(OutDir runtime/OutDir)
|
||||
ADD_TEST_MACRO(ObjectLibrary UseCshared)
|
||||
ADD_TEST_MACRO(NewlineArgs NewlineArgs)
|
||||
ADD_TEST_MACRO(SetLang SetLang)
|
||||
ADD_TEST_MACRO(ExternalOBJ ExternalOBJ)
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# Add -fPIC so objects can be used in shared libraries.
|
||||
# TODO: Need property for this.
|
||||
if(CMAKE_SHARED_LIBRARY_C_FLAGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
|
||||
add_definitions(-DA)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT a1.c
|
||||
DEPENDS a1.c.in
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/a1.c.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/a1.c
|
||||
)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_library(A OBJECT a1.c a2.c)
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef A
|
||||
# error "A not defined"
|
||||
#endif
|
||||
#ifdef B
|
||||
# error "B must not be defined"
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
#include "a.h"
|
||||
int a1(void) { return 0; }
|
|
@ -0,0 +1,2 @@
|
|||
#include "a.h"
|
||||
int a2(void) { return 0; }
|
|
@ -0,0 +1,5 @@
|
|||
EXPORTS
|
||||
a1
|
||||
a2
|
||||
b1
|
||||
b2
|
|
@ -0,0 +1,15 @@
|
|||
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")
|
||||
# VS 6 generator does not use per-target object locations.
|
||||
set(vs6 _vs6)
|
||||
endif()
|
||||
|
||||
# Add -fPIC so objects can be used in shared libraries.
|
||||
# TODO: Need property for this.
|
||||
if(CMAKE_SHARED_LIBRARY_C_FLAGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS} ${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
|
||||
add_definitions(-DB)
|
||||
add_library(B OBJECT b1.c b2.c)
|
||||
add_library(Bexport OBJECT b1${vs6}.c b2${vs6}.c)
|
||||
set_property(TARGET Bexport PROPERTY COMPILE_DEFINITIONS Bexport)
|
|
@ -0,0 +1,11 @@
|
|||
#ifdef A
|
||||
# error "A must not be defined"
|
||||
#endif
|
||||
#ifndef B
|
||||
# error "B not defined"
|
||||
#endif
|
||||
#if defined(_WIN32) && defined(Bexport)
|
||||
# define EXPORT_B __declspec(dllexport)
|
||||
#else
|
||||
# define EXPORT_B
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
#include "b.h"
|
||||
EXPORT_B int b1(void) { return 0; }
|
|
@ -0,0 +1 @@
|
|||
#include "b1.c"
|
|
@ -0,0 +1,2 @@
|
|||
#include "b.h"
|
||||
EXPORT_B int b2(void) { return 0; }
|
|
@ -0,0 +1 @@
|
|||
#include "b2.c"
|
|
@ -0,0 +1,52 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(ObjectLibrary C)
|
||||
|
||||
add_subdirectory(A)
|
||||
add_subdirectory(B)
|
||||
|
||||
add_library(Cstatic STATIC c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
|
||||
add_executable(UseCstatic main.c)
|
||||
target_link_libraries(UseCstatic Cstatic)
|
||||
|
||||
add_library(Cshared SHARED c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:Bexport>)
|
||||
add_executable(UseCshared main.c)
|
||||
set_property(TARGET UseCshared PROPERTY COMPILE_DEFINITIONS SHARED_C)
|
||||
target_link_libraries(UseCshared Cshared)
|
||||
|
||||
add_executable(UseCinternal main.c c.c $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
|
||||
|
||||
if("${CMAKE_GENERATOR}" MATCHES "^Visual Studio (6|7|7 .NET 2003)$")
|
||||
# VS 6 and 7 generators do not add objects as sources so we need a
|
||||
# dummy object to convince the IDE to build the targets below.
|
||||
set(dummy dummy.obj) # In MinGW: gcc -c dummy.c -o dummy.obj
|
||||
elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
|
||||
# Xcode does not seem to support targets without sources.
|
||||
set(dummy dummy.c)
|
||||
endif()
|
||||
|
||||
# Test static library without its own sources.
|
||||
add_library(ABstatic STATIC ${dummy} $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)
|
||||
add_executable(UseABstatic mainAB.c)
|
||||
target_link_libraries(UseABstatic ABstatic)
|
||||
|
||||
# Test module definition file to export object library symbols in the test
|
||||
# below if the platform needs and supports it.
|
||||
set(ABshared_SRCS $<TARGET_OBJECTS:A>)
|
||||
if(CMAKE_LINK_DEF_FILE_FLAG OR NOT WIN32)
|
||||
list(APPEND ABshared_SRCS $<TARGET_OBJECTS:B> AB.def)
|
||||
else()
|
||||
set(NO_A NO_A)
|
||||
list(APPEND ABshared_SRCS $<TARGET_OBJECTS:Bexport>)
|
||||
endif()
|
||||
|
||||
# Test shared library without its own sources.
|
||||
add_library(ABshared SHARED ${dummy} ${ABshared_SRCS})
|
||||
add_executable(UseABshared mainAB.c)
|
||||
set_property(TARGET UseABshared PROPERTY COMPILE_DEFINITIONS SHARED_B ${NO_A})
|
||||
target_link_libraries(UseABshared ABshared)
|
||||
|
||||
# Test executable without its own sources.
|
||||
add_library(ABmain OBJECT mainAB.c)
|
||||
add_executable(UseABinternal ${dummy}
|
||||
$<TARGET_OBJECTS:ABmain> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>
|
||||
)
|
|
@ -0,0 +1,19 @@
|
|||
#if defined(_WIN32) && defined(Cshared_EXPORTS)
|
||||
# define EXPORT_C __declspec(dllexport)
|
||||
#else
|
||||
# define EXPORT_C
|
||||
#endif
|
||||
|
||||
extern int a1(void);
|
||||
extern int a2(void);
|
||||
extern int b1(void);
|
||||
extern int b2(void);
|
||||
EXPORT_C int c(void)
|
||||
{
|
||||
return 0
|
||||
+ a1()
|
||||
+ a2()
|
||||
+ b1()
|
||||
+ b2()
|
||||
;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
int dummy(void) {return 0;}
|
Binary file not shown.
|
@ -0,0 +1,16 @@
|
|||
#if defined(_WIN32) && defined(SHARED_C)
|
||||
# define IMPORT_C __declspec(dllimport)
|
||||
#else
|
||||
# define IMPORT_C
|
||||
#endif
|
||||
extern IMPORT_C int b1(void);
|
||||
extern IMPORT_C int b2(void);
|
||||
extern IMPORT_C int c(void);
|
||||
int main(void)
|
||||
{
|
||||
return 0
|
||||
+ c()
|
||||
+ b1()
|
||||
+ b2()
|
||||
;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#if defined(_WIN32) && defined(SHARED_B)
|
||||
# define IMPORT_B __declspec(dllimport)
|
||||
#else
|
||||
# define IMPORT_B
|
||||
#endif
|
||||
extern IMPORT_B int b1(void);
|
||||
extern IMPORT_B int b2(void);
|
||||
#ifndef NO_A
|
||||
extern int a1(void);
|
||||
extern int a2(void);
|
||||
#endif
|
||||
int main(void)
|
||||
{
|
||||
return 0
|
||||
#ifndef NO_A
|
||||
+ a1()
|
||||
+ a2()
|
||||
#endif
|
||||
+ b1()
|
||||
+ b2()
|
||||
;
|
||||
}
|
|
@ -40,5 +40,7 @@ macro(add_RunCMake_test test)
|
|||
)
|
||||
endmacro()
|
||||
|
||||
add_RunCMake_test(ObjectLibrary)
|
||||
|
||||
add_RunCMake_test(build_command)
|
||||
add_RunCMake_test(find_package)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,8 @@
|
|||
CMake Error at BadObjSource1.cmake:1 \(add_library\):
|
||||
OBJECT library "A" contains:
|
||||
|
||||
bad.def
|
||||
|
||||
but may contain only headers and sources that compile.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1 @@
|
|||
add_library(A OBJECT a.c bad.def)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,8 @@
|
|||
CMake Error at BadObjSource2.cmake:1 \(add_library\):
|
||||
OBJECT library "A" contains:
|
||||
|
||||
bad.obj
|
||||
|
||||
but may contain only headers and sources that compile.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1 @@
|
|||
add_library(A OBJECT a.c bad.obj)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error at BadSourceExpression1.cmake:1 \(add_library\):
|
||||
Unrecognized generator expression:
|
||||
|
||||
\$<BAD_EXPRESSION>
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1 @@
|
|||
add_library(A STATIC a.c $<BAD_EXPRESSION>)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at BadSourceExpression2.cmake:1 \(add_library\):
|
||||
Objects of target "DoesNotExist" referenced but no such target exists.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1 @@
|
|||
add_library(A STATIC a.c $<TARGET_OBJECTS:DoesNotExist>)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at BadSourceExpression3.cmake:2 \(add_library\):
|
||||
Objects of target "NotObjLib" referenced but is not an OBJECT library.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
|||
add_library(NotObjLib STATIC a.c)
|
||||
add_library(A STATIC a.c $<TARGET_OBJECTS:NotObjLib>)
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} C)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at Export.cmake:2 \(export\):
|
||||
export given OBJECT library "A" which may not be exported.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
|||
add_library(A OBJECT a.c)
|
||||
export(TARGETS A FILE AExport.cmake)
|
|
@ -0,0 +1,15 @@
|
|||
enable_language(CXX)
|
||||
add_library(A OBJECT a.cxx)
|
||||
add_library(B STATIC a.c $<TARGET_OBJECTS:A>)
|
||||
|
||||
# Verify that object library languages are propagated.
|
||||
export(TARGETS B NAMESPACE Exp FILE BExport.cmake)
|
||||
include(${CMAKE_CURRENT_BINARY_DIR}/BExport.cmake)
|
||||
get_property(configs TARGET ExpB PROPERTY IMPORTED_CONFIGURATIONS)
|
||||
foreach(c ${configs})
|
||||
get_property(langs TARGET ExpB PROPERTY IMPORTED_LINK_INTERFACE_LANGUAGES_${c})
|
||||
list(FIND langs CXX pos)
|
||||
if(${pos} LESS 0)
|
||||
message(FATAL_ERROR "Target export does not list object library languages.")
|
||||
endif()
|
||||
endforeach()
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at Import.cmake:1 \(add_library\):
|
||||
The OBJECT library type may not be used for IMPORTED libraries.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1 @@
|
|||
add_library(A OBJECT IMPORTED)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at Install.cmake:2 \(install\):
|
||||
install TARGETS given OBJECT library "A" which may not be installed.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
|||
add_library(A OBJECT a.c)
|
||||
install(TARGETS A DESTINATION lib)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at LinkObjLHS.cmake:2 \(target_link_libraries\):
|
||||
Object library target "AnObjLib" may not link to anything.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
|||
add_library(AnObjLib OBJECT a.c)
|
||||
target_link_libraries(AnObjLib OtherLib)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,6 @@
|
|||
CMake Error at LinkObjRHS1.cmake:3 \(target_link_libraries\):
|
||||
Target "AnObjLib" of type OBJECT_LIBRARY may not be linked into another
|
||||
target. One may link only to STATIC or SHARED libraries, or to executables
|
||||
with the ENABLE_EXPORTS property set.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,3 @@
|
|||
add_library(A STATIC a.c)
|
||||
add_library(AnObjLib OBJECT a.c)
|
||||
target_link_libraries(A AnObjLib)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue