summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2012-03-12 10:47:40 -0400
committerBrad King <brad.king@kitware.com>2012-03-13 14:37:32 -0400
commitb87d7a60a0ed146b79c49baedb666db228d5a70f (patch)
tree4ff0a6246e4c7b78edc7c77e481fa8c0aaec9844
parentd5aedf15a4a6d7023a7ba73dcf92b24607af4606 (diff)
downloadcmake-b87d7a60a0ed146b79c49baedb666db228d5a70f.tar.gz
Add OBJECT_LIBRARY target type
This library type can compile sources to object files but does not link or archive them. It will be useful to reference from executable and normal library targets for direct inclusion of object files in them. Diagnose and reject the following as errors: * An OBJECT library may not be referenced in target_link_libraries. * An OBJECT library may contain only compiling sources and supporting headers and custom commands. Other source types that are not normally ignored are not allowed. * An OBJECT library may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands. * An OBJECT library may not be installed, exported, or imported. Some of these cases may be supported in the future but are not for now. Teach the VS generator that OBJECT_LIBRARY targets are "linkable" just like STATIC_LIBRARY targets for the LinkLibraryDependencies behavior.
-rw-r--r--Source/cmAddLibraryCommand.cxx14
-rw-r--r--Source/cmComputeLinkDepends.cxx13
-rw-r--r--Source/cmExportCommand.cxx8
-rw-r--r--Source/cmGeneratorTarget.cxx21
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx8
-rw-r--r--Source/cmInstallCommand.cxx11
-rw-r--r--Source/cmInstallTargetGenerator.cxx1
-rw-r--r--Source/cmLocalGenerator.cxx4
-rw-r--r--Source/cmMakefile.cxx13
-rw-r--r--Source/cmTarget.cxx2
-rw-r--r--Source/cmTarget.h3
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx10
12 files changed, 104 insertions, 4 deletions
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 9a776fbdea..c1d0e9d6d9 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.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()))
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index ddff2d9215..055aab0321 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -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;
}
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index cb614d4f32..1cc17545ad 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -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;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index afb1f3936a..369eb5cf2e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -29,6 +29,8 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t)
//----------------------------------------------------------------------------
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)
@@ -43,6 +45,7 @@ void cmGeneratorTarget::ClassifySources()
else if(tsFlags.Type != cmTarget::SourceFileTypeNormal)
{
this->OSXContent.push_back(sf);
+ if(isObjLib) { badObjLib.push_back(sf); }
}
else if(sf->GetPropertyAsBool("HEADER_FILE_ONLY"))
{
@@ -51,10 +54,12 @@ void cmGeneratorTarget::ClassifySources()
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()))
{
@@ -69,6 +74,22 @@ void cmGeneratorTarget::ClassifySources()
else
{
this->ExtraSources.push_back(sf);
+ if(isObjLib) { 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());
+ }
}
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 4b9e487911..7da4f8687c 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -375,6 +375,12 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
}
//----------------------------------------------------------------------------
+static bool VSLinkable(cmTarget* t)
+{
+ return t->IsLinkable() || t->GetType() == cmTarget::OBJECT_LIBRARY;
+}
+
+//----------------------------------------------------------------------------
void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target)
{
if(this->VSTargetDepends.find(&target) != this->VSTargetDepends.end())
@@ -458,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());
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index dca528d26a..c656487375 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -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);
}
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index c74dda0636..5f9b6585eb 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -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:
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 19537b5f77..ebfb586165 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1904,6 +1904,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
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 68a8272512..aba2e38ea7 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -853,6 +853,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,
@@ -1912,8 +1920,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;
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index e6be83ade6..9e86681090 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -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:
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index ff05cd3e9b..e2502f06c7 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -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 };
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 36c4ca8bd8..dbea1c3bb4 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -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)
{