summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-04-12 15:36:06 (GMT)
committerKitware Robot <kwrobot@kitware.com>2018-04-12 15:36:28 (GMT)
commit498be66fd7211fb782eaac8be7c2b0e50e3ab5da (patch)
tree2bf6aa9f7a8132b8585bcc53394df3802a6f34b4 /Source
parent2cdefcbe62707a82eccbc301fe34f85bb74d932a (diff)
parent312527de473692e17f2b858a87faa157c73e488f (diff)
downloadCMake-498be66fd7211fb782eaac8be7c2b0e50e3ab5da.zip
CMake-498be66fd7211fb782eaac8be7c2b0e50e3ab5da.tar.gz
CMake-498be66fd7211fb782eaac8be7c2b0e50e3ab5da.tar.bz2
Merge topic 'add_support_for_clr_targets'
312527de47 document COMMON_LANGUAGE_RUNTIME target properties 4b7a82b4ed cmVisualStudio10TargetGenerator: set /clr compiler flag from property 20e31fb4c9 cmExportFileGenerator: add target property for managed targets 411a22706a cmGeneratorTarget: add handling of managed assemblies to HasImportLibrary() fb433ff283 cmGeneratorTarget: Make import library checks config-aware 4c1f33961f cmGeneratorTarget: add GetManagedType() and CheckManagedType() methods 6c517a9f8d cmGeneratorTarget: add HasLanguage() as wrapper for GetLanguages() Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1916
Diffstat (limited to 'Source')
-rw-r--r--Source/cmExportBuildFileGenerator.cxx5
-rw-r--r--Source/cmExportFileGenerator.cxx14
-rw-r--r--Source/cmGeneratorExpressionNode.cxx3
-rw-r--r--Source/cmGeneratorTarget.cxx84
-rw-r--r--Source/cmGeneratorTarget.h31
-rw-r--r--Source/cmInstallTargetGenerator.cxx8
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx16
11 files changed, 151 insertions, 24 deletions
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index bbbc998..72489bf 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -224,13 +224,14 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
}
// Add the import library for windows DLLs.
- if (target->HasImportLibrary() &&
+ if (target->HasImportLibrary(config) &&
mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
std::string prop = "IMPORTED_IMPLIB";
prop += suffix;
std::string value =
target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact);
- target->GetImplibGNUtoMS(value, value, "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+ target->GetImplibGNUtoMS(config, value, value,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
properties[prop] = value;
}
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 2dcbfa0..8894d44 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -777,6 +777,20 @@ void cmExportFileGenerator::SetImportDetailProperties(
properties[prop] = m.str();
}
}
+
+ // Add information if this target is a managed target
+ if (target->GetManagedType(config) !=
+ cmGeneratorTarget::ManagedType::Native) {
+ std::string prop = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
+ prop += suffix;
+ std::string propval;
+ if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ propval = p;
+ }
+ // TODO: make sure propval is set to non-empty string for
+ // CSharp targets (i.e. force ManagedType::Managed).
+ properties[prop] = propval;
+ }
}
template <typename T>
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 09b7faf..89ed4f0 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1675,7 +1675,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
"executables with ENABLE_EXPORTS.");
return std::string();
}
- cmStateEnums::ArtifactType artifact = target->HasImportLibrary()
+ cmStateEnums::ArtifactType artifact =
+ target->HasImportLibrary(context->Config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
return target->GetFullPath(context->Config, artifact);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 63bfbc6..0cb299c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4978,6 +4978,16 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
}
+ // Get information if target is managed assembly.
+ {
+ std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
+ if (auto pc = this->GetProperty(linkProp + suffix)) {
+ info.Managed = this->CheckManagedType(pc);
+ } else if (auto p = this->GetProperty(linkProp)) {
+ info.Managed = this->CheckManagedType(p);
+ }
+ }
+
// Get the cyclic repetition count.
if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
std::string linkProp = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
@@ -5195,6 +5205,18 @@ void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
}
}
+bool cmGeneratorTarget::HasLanguage(std::string const& language,
+ std::string const& config,
+ bool exclusive) const
+{
+ std::set<std::string> languages;
+ this->GetLanguages(languages, config);
+ // add linker language (if it is different from compiler languages)
+ languages.insert(this->GetLinkerLanguage(config));
+ return (languages.size() == 1 || !exclusive) &&
+ languages.count(language) > 0;
+}
+
void cmGeneratorTarget::ComputeLinkImplementationLanguages(
const std::string& config, cmOptionalLinkImplementation& impl) const
{
@@ -5381,16 +5403,17 @@ std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
return "";
}
-bool cmGeneratorTarget::HasImplibGNUtoMS() const
+bool cmGeneratorTarget::HasImplibGNUtoMS(std::string const& config) const
{
- return this->HasImportLibrary() && this->GetPropertyAsBool("GNUtoMS");
+ return this->HasImportLibrary(config) && this->GetPropertyAsBool("GNUtoMS");
}
-bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& gnuName,
+bool cmGeneratorTarget::GetImplibGNUtoMS(std::string const& config,
+ std::string const& gnuName,
std::string& out,
const char* newExt) const
{
- if (this->HasImplibGNUtoMS() && gnuName.size() > 6 &&
+ if (this->HasImplibGNUtoMS(config) && gnuName.size() > 6 &&
gnuName.substr(gnuName.size() - 6) == ".dll.a") {
out = gnuName.substr(0, gnuName.size() - 6);
out += newExt ? newExt : ".lib";
@@ -5405,11 +5428,14 @@ bool cmGeneratorTarget::IsExecutableWithExports() const
this->GetPropertyAsBool("ENABLE_EXPORTS"));
}
-bool cmGeneratorTarget::HasImportLibrary() const
+bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const
{
return (this->IsDLLPlatform() &&
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->IsExecutableWithExports()));
+ this->IsExecutableWithExports()) &&
+ // Assemblies which have only managed code do not have
+ // import libraries.
+ this->GetManagedType(config) != ManagedType::Managed);
}
std::string cmGeneratorTarget::GetSupportDirectory() const
@@ -5462,3 +5488,49 @@ bool cmGeneratorTarget::IsCFBundleOnApple() const
return (this->GetType() == cmStateEnums::MODULE_LIBRARY &&
this->Makefile->IsOn("APPLE") && this->GetPropertyAsBool("BUNDLE"));
}
+
+cmGeneratorTarget::ManagedType cmGeneratorTarget::CheckManagedType(
+ std::string const& propval) const
+{
+ // The type of the managed assembly (mixed unmanaged C++ and C++/CLI,
+ // or only C++/CLI) does only depend on whether the property is an empty
+ // string or contains any value at all. In Visual Studio generators
+ // this propval is prepended with /clr[:] which results in:
+ //
+ // 1. propval does not exist: no /clr flag, unmanaged target, has import
+ // lib
+ // 2. empty propval: add /clr as flag, mixed unmanaged/managed
+ // target, has import lib
+ // 3. any value (safe,pure): add /clr:[propval] as flag, target with
+ // managed code only, no import lib
+ return propval.empty() ? ManagedType::Mixed : ManagedType::Managed;
+}
+
+cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
+ const std::string& config) const
+{
+ // Only libraries and executables can be managed targets.
+ if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+ this->GetType() != cmStateEnums::EXECUTABLE) {
+ return ManagedType::Undefined;
+ }
+
+ // Check imported target.
+ if (this->IsImported()) {
+ if (cmGeneratorTarget::ImportInfo const* info =
+ this->GetImportInfo(config)) {
+ return info->Managed;
+ }
+ return ManagedType::Undefined;
+ }
+
+ // Check for explicitly set clr target property.
+ if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ return this->CheckManagedType(clr);
+ }
+
+ // TODO: need to check if target is a CSharp target here.
+ // If yes: return ManagedType::Managed.
+ return ManagedType::Native;
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2f6ce33..d4a553a 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -364,6 +364,12 @@ public:
void GetLanguages(std::set<std::string>& languages,
std::string const& config) const;
+ // Evaluate if the target uses the given language for compilation
+ // and/or linking. If 'exclusive' is true, 'language' is expected
+ // to be the only language used for the target.
+ bool HasLanguage(std::string const& language, std::string const& config,
+ bool exclusive = true) const;
+
void GetObjectLibrariesCMP0026(
std::vector<cmGeneratorTarget*>& objlibs) const;
@@ -566,17 +572,17 @@ public:
std::string GetLinkerLanguage(const std::string& config) const;
/** Does this target have a GNU implib to convert to MS format? */
- bool HasImplibGNUtoMS() const;
+ bool HasImplibGNUtoMS(std::string const& config) const;
/** Convert the given GNU import library name (.dll.a) to a name with a new
extension (.lib or ${CMAKE_IMPORT_LIBRARY_SUFFIX}). */
- bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out,
- const char* newExt = nullptr) const;
+ bool GetImplibGNUtoMS(std::string const& config, std::string const& gnuName,
+ std::string& out, const char* newExt = nullptr) const;
bool IsExecutableWithExports() const;
/** Return whether or not the target has a DLL import library. */
- bool HasImportLibrary() const;
+ bool HasImportLibrary(std::string const& config) const;
/** Get a build-tree directory in which to place target support files. */
std::string GetSupportDirectory() const;
@@ -597,6 +603,19 @@ public:
/** Return whether this target is a CFBundle (plugin) on Apple. */
bool IsCFBundleOnApple() const;
+ /** Assembly types. The order of the values of this enum is relevant
+ because of smaller/larger comparison operations! */
+ enum ManagedType
+ {
+ Undefined = 0, // target is no lib or executable
+ Native, // target compiles to unmanaged binary.
+ Mixed, // target compiles to mixed (managed and unmanaged) binary.
+ Managed // target compiles to managed binary.
+ };
+
+ /** Return the type of assembly this target compiles to. */
+ ManagedType GetManagedType(const std::string& config) const;
+
struct SourceFileFlags GetTargetSourceFileFlags(
const cmSourceFile* sf) const;
@@ -741,10 +760,12 @@ private:
{
ImportInfo()
: NoSOName(false)
+ , Managed(Native)
, Multiplicity(0)
{
}
bool NoSOName;
+ ManagedType Managed;
unsigned int Multiplicity;
std::string Location;
std::string SOName;
@@ -838,6 +859,8 @@ private:
bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
std::string& out) const;
+ ManagedType CheckManagedType(std::string const& propval) const;
+
public:
const std::vector<const cmGeneratorTarget*>& GetLinkImplementationClosure(
const std::string& config) const;
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index a9b4908..e0afa2d 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -135,7 +135,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
filesFrom.push_back(std::move(from1));
filesTo.push_back(std::move(to1));
std::string targetNameImportLib;
- if (this->Target->GetImplibGNUtoMS(targetNameImport,
+ if (this->Target->GetImplibGNUtoMS(config, targetNameImport,
targetNameImportLib)) {
filesFrom.push_back(fromDirConfig + targetNameImportLib);
filesTo.push_back(toDir + targetNameImportLib);
@@ -201,7 +201,7 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
filesFrom.push_back(std::move(from1));
filesTo.push_back(std::move(to1));
std::string targetNameImportLib;
- if (this->Target->GetImplibGNUtoMS(targetNameImport,
+ if (this->Target->GetImplibGNUtoMS(config, targetNameImport,
targetNameImportLib)) {
filesFrom.push_back(fromDirConfig + targetNameImportLib);
filesTo.push_back(toDir + targetNameImportLib);
@@ -398,7 +398,7 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
targetNamePDB, config);
if (nameType == NameImplib) {
// Use the import library name.
- if (!target->GetImplibGNUtoMS(targetNameImport, fname,
+ if (!target->GetImplibGNUtoMS(config, targetNameImport, fname,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
fname = targetNameImport;
}
@@ -419,7 +419,7 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
targetNameImport, targetNamePDB, config);
if (nameType == NameImplib) {
// Use the import library name.
- if (!target->GetImplibGNUtoMS(targetNameImport, fname,
+ if (!target->GetImplibGNUtoMS(config, targetNameImport, fname,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
fname = targetNameImport;
}
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 9bbc043..1e59f44 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -477,8 +477,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport));
std::string implib;
- if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
- implib)) {
+ if (this->GeneratorTarget->GetImplibGNUtoMS(
+ this->ConfigName, targetFullPathImport, implib)) {
exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 9299ffe..27fae04 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -641,8 +641,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->GetCurrentBinaryDirectory(),
targetFullPathImport));
std::string implib;
- if (this->GeneratorTarget->GetImplibGNUtoMS(targetFullPathImport,
- implib)) {
+ if (this->GeneratorTarget->GetImplibGNUtoMS(
+ this->ConfigName, targetFullPathImport, implib)) {
libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index abe5ff3..3998823 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -1402,7 +1402,7 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
const std::string& linkRuleVar)
{
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
- if (this->GeneratorTarget->HasImplibGNUtoMS()) {
+ if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
std::string ruleVar = "CMAKE_";
ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
ruleVar += "_GNUtoMS_RULE";
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 52e3677..542bb0a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -482,7 +482,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
const char* linkCmd = mf->GetDefinition(linkCmdVar);
if (linkCmd) {
std::string linkCmdStr = linkCmd;
- if (this->GetGeneratorTarget()->HasImplibGNUtoMS()) {
+ if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
std::string ruleVar = "CMAKE_";
ruleVar += this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
ruleVar += "_GNUtoMS_RULE";
@@ -881,7 +881,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
- if (genTarget.HasImportLibrary()) {
+ if (genTarget.HasImportLibrary(cfgName)) {
byproducts.push_back(targetOutputImplib);
}
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 3289b55..13af167 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2418,6 +2418,22 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.AddFlag("AssemblerListingLocation", asmLocation);
}
}
+
+ // check for managed C++ assembly compiler flag. This overrides any
+ // /clr* compiler flags which may be defined in the flags variable(s).
+ if (this->ProjectType != csproj) {
+ // TODO: add check here, if /clr was defined manually and issue
+ // warning that this is discouraged.
+ if (auto* clr =
+ this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ std::string clrString = clr;
+ if (!clrString.empty()) {
+ clrString = ":" + clrString;
+ }
+ flags += " /clr" + clrString;
+ }
+ }
+
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
std::vector<std::string> targetDefines;