summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/Checks/cm_cxx_features.cmake2
-rw-r--r--Source/cmCommonTargetGenerator.cxx3
-rw-r--r--Source/cmComputeLinkInformation.cxx36
-rw-r--r--Source/cmCoreTryCompile.cxx6
-rw-r--r--Source/cmExportBuildFileGenerator.cxx2
-rw-r--r--Source/cmExportFileGenerator.cxx3
-rw-r--r--Source/cmExportInstallFileGenerator.cxx15
-rw-r--r--Source/cmFindPackageCommand.cxx1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx426
-rw-r--r--Source/cmGeneratorTarget.cxx185
-rw-r--r--Source/cmGeneratorTarget.h19
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx145
-rw-r--r--Source/cmGlobalNinjaGenerator.h8
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx29
-rw-r--r--Source/cmIncludeCommand.cxx1
-rw-r--r--Source/cmInstallCommand.cxx73
-rw-r--r--Source/cmInstallTargetGenerator.cxx191
-rw-r--r--Source/cmInstallTargetGenerator.h8
-rw-r--r--Source/cmLocalGenerator.cxx16
-rw-r--r--Source/cmMakefile.cxx7
-rw-r--r--Source/cmMakefile.h4
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx9
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx110
-rw-r--r--Source/cmMakefileTargetGenerator.cxx22
-rw-r--r--Source/cmMakefileTargetGenerator.h6
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx104
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h1
-rw-r--r--Source/cmOSXBundleGenerator.cxx14
-rw-r--r--Source/cmOSXBundleGenerator.h11
-rw-r--r--Source/cmPolicies.h9
-rw-r--r--Source/cmRST.cxx65
-rw-r--r--Source/cmRST.h36
-rw-r--r--Source/cmSourceFile.h4
-rw-r--r--Source/cmState.h12
-rw-r--r--Source/cmTarget.cxx60
-rw-r--r--Source/cmTarget.h6
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx18
-rw-r--r--Source/cmake.cxx2
-rw-r--r--Source/kwsys/SystemTools.cxx6
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake63
42 files changed, 1324 insertions, 418 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index e99da49..163dab3 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -16,6 +16,8 @@ if(NOT CMake_DEFAULT_RECURSION_LIMIT)
set(CMake_DEFAULT_RECURSION_LIMIT 100)
elseif(MINGW OR MSYS)
set(CMake_DEFAULT_RECURSION_LIMIT 400)
+ elseif(WIN32 AND CMAKE_C_COMPILER_ARCHITECTURE_ID STREQUAL "ARM64")
+ set(CMake_DEFAULT_RECURSION_LIMIT 400)
elseif(WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")
set(CMake_DEFAULT_RECURSION_LIMIT 600)
else()
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 616c7e8..73bda5f 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 26)
-set(CMake_VERSION_PATCH 20230301)
+set(CMake_VERSION_PATCH 20230314)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index 73e7ef2..f5b7587 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -38,6 +38,8 @@ function(cm_check_cxx_feature name)
string(REGEX REPLACE " +0 Warning\\(s\\)" "" check_output "${check_output}")
# Filter out MSBuild output that looks like a warning.
string(REGEX REPLACE "[^\n]*warning MSB[0-9][0-9][0-9][0-9][^\n]*" "" check_output "${check_output}")
+ # Filter out MSVC output that looks like a command-line warning.
+ string(REGEX REPLACE "[^\n]*warning D[0-9][0-9][0-9][0-9][^\n]*" "" check_output "${check_output}")
# Filter out warnings caused by user flags.
string(REGEX REPLACE "[^\n]*warning:[^\n]*-Winvalid-command-line-argument[^\n]*" "" check_output "${check_output}")
# Filter out warnings caused by local configuration.
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 1705763..5601bf2 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -25,7 +25,6 @@
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
-#include "cmTarget.h"
#include "cmValue.h"
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
@@ -248,7 +247,7 @@ std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
{
std::string aixExports;
- if (this->GeneratorTarget->Target->IsAIX()) {
+ if (this->GeneratorTarget->IsAIX()) {
if (cmValue exportAll =
this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
if (cmIsOff(*exportAll)) {
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index ff688a4..a93477b 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1157,7 +1157,7 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
// Pass the full path to the target file.
BT<std::string> lib = BT<std::string>(
tgt->GetFullPath(config, artifact, true), item.Backtrace);
- if (tgt->Target->IsAIX() && cmHasLiteralSuffix(lib.Value, "-NOTFOUND") &&
+ if (tgt->IsAIX() && cmHasLiteralSuffix(lib.Value, "-NOTFOUND") &&
artifact == cmStateEnums::ImportLibraryArtifact) {
// This is an imported executable on AIX that has ENABLE_EXPORTS
// but not IMPORTED_IMPLIB. CMake used to produce and accept such
@@ -1185,7 +1185,7 @@ void cmComputeLinkInformation::AddItem(LinkEntry const& entry)
if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s) ||
(entry.Feature == DEFAULT &&
cmSystemTools::IsPathToFramework(item.Value) &&
- this->Makefile->IsOn("APPLE"))) {
+ this->Target->IsApple())) {
// This is a framework.
this->AddFrameworkItem(entry);
} else if (cmSystemTools::FileIsFullPath(item.Value)) {
@@ -1563,7 +1563,7 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
this->OldLinkDirItems.push_back(item.Value);
}
- if (target->IsFrameworkOnApple() && !this->GlobalGenerator->IsXcode()) {
+ if (target->IsFrameworkOnApple()) {
// Add the framework directory and the framework item itself
auto fwDescriptor = this->GlobalGenerator->SplitFrameworkPath(
item.Value, cmGlobalGenerator::FrameworkFormat::Extended);
@@ -1579,26 +1579,32 @@ void cmComputeLinkInformation::AddTargetItem(LinkEntry const& entry)
// Add the directory portion to the framework search path.
this->AddFrameworkPath(fwDescriptor->Directory);
}
- if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
- this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes,
- target,
- this->FindLibraryFeature(entry.Feature));
- } else {
+
+ if (this->GlobalGenerator->IsXcode()) {
this->Items.emplace_back(
item, ItemIsPath::Yes, target,
- this->FindLibraryFeature(
- entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature));
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "__CMAKE_LINK_FRAMEWORK"
+ : entry.Feature));
+ } else {
+ if (cmHasSuffix(entry.Feature, "FRAMEWORK"_s)) {
+ this->Items.emplace_back(fwDescriptor->GetLinkName(), ItemIsPath::Yes,
+ target,
+ this->FindLibraryFeature(entry.Feature));
+ } else {
+ this->Items.emplace_back(
+ item, ItemIsPath::Yes, target,
+ this->FindLibraryFeature(entry.Feature == DEFAULT
+ ? "__CMAKE_LINK_LIBRARY"
+ : entry.Feature));
+ }
}
} else {
// Now add the full path to the library.
this->Items.emplace_back(
item, ItemIsPath::Yes, target,
this->FindLibraryFeature(
- entry.Feature == DEFAULT
- ? (target->IsFrameworkOnApple() && this->GlobalGenerator->IsXcode()
- ? "__CMAKE_LINK_FRAMEWORK"
- : "__CMAKE_LINK_LIBRARY")
- : entry.Feature));
+ entry.Feature == DEFAULT ? "__CMAKE_LINK_LIBRARY" : entry.Feature));
}
}
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index acf1c20..3149ccf 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -72,6 +72,10 @@ SETUP_LANGUAGE(swift_properties, Swift);
std::string const kCMAKE_CUDA_ARCHITECTURES = "CMAKE_CUDA_ARCHITECTURES";
std::string const kCMAKE_CUDA_RUNTIME_LIBRARY = "CMAKE_CUDA_RUNTIME_LIBRARY";
std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
+std::string const kCMAKE_EXECUTABLE_ENABLE_EXPORTS =
+ "CMAKE_EXECUTABLE_ENABLE_EXPORTS";
+std::string const kCMAKE_SHARED_LIBRARY_ENABLE_EXPORTS =
+ "CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS";
std::string const kCMAKE_HIP_ARCHITECTURES = "CMAKE_HIP_ARCHITECTURES";
std::string const kCMAKE_HIP_RUNTIME_LIBRARY = "CMAKE_HIP_RUNTIME_LIBRARY";
std::string const kCMAKE_ISPC_INSTRUCTION_SETS = "CMAKE_ISPC_INSTRUCTION_SETS";
@@ -997,6 +1001,8 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
vars.insert(kCMAKE_CUDA_ARCHITECTURES);
vars.insert(kCMAKE_CUDA_RUNTIME_LIBRARY);
vars.insert(kCMAKE_ENABLE_EXPORTS);
+ vars.insert(kCMAKE_EXECUTABLE_ENABLE_EXPORTS);
+ vars.insert(kCMAKE_SHARED_LIBRARY_ENABLE_EXPORTS);
vars.insert(kCMAKE_HIP_ARCHITECTURES);
vars.insert(kCMAKE_HIP_RUNTIME_LIBRARY);
vars.insert(kCMAKE_ISPC_INSTRUCTION_SETS);
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index ed199ea..caf8ac2 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -254,7 +254,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
if (target->HasImportLibrary(config)) {
std::string prop = cmStrCat("IMPORTED_IMPLIB", suffix);
std::string value =
- target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact);
+ target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact, true);
if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
target->GetImplibGNUtoMS(config, value, value,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}");
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 7f1afba..6e7ef4e 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -1063,7 +1063,8 @@ void cmExportFileGenerator::GenerateImportTargetCode(
}
// Mark the imported executable if it has exports.
- if (target->IsExecutableWithExports()) {
+ if (target->IsExecutableWithExports() ||
+ (target->IsSharedLibraryWithExports() && target->HasImportLibrary(""))) {
os << "set_property(TARGET " << targetName
<< " PROPERTY ENABLE_EXPORTS 1)\n";
}
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 5e190f4..def8227 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -409,7 +409,7 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
// Append the installed file name.
value += cmInstallTargetGenerator::GetInstallFilename(
- target, config, cmInstallTargetGenerator::NameImplib);
+ target, config, cmInstallTargetGenerator::NameImplibReal);
// Store the property.
properties[prop] = value;
@@ -430,6 +430,19 @@ void cmExportInstallFileGenerator::SetImportLocationProperty(
properties[prop] = cmJoin(objects, ";");
importedLocations.insert(prop);
} else {
+ if (target->IsFrameworkOnApple() && target->HasImportLibrary(config)) {
+ // store as well IMPLIB value
+ auto importProp = cmStrCat("IMPORTED_IMPLIB", suffix);
+ auto importValue =
+ cmStrCat(value,
+ cmInstallTargetGenerator::GetInstallFilename(
+ target, config, cmInstallTargetGenerator::NameImplibReal));
+
+ // Store the property.
+ properties[importProp] = importValue;
+ importedLocations.insert(importProp);
+ }
+
// Construct the property name.
std::string prop = cmStrCat("IMPORTED_LOCATION", suffix);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8acfe83..4024dff 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -502,6 +502,7 @@ cmFindPackageCommand::cmFindPackageCommand(cmExecutionStatus& status)
this->DebugMode = false;
this->AppendSearchPathGroups();
+ this->DeprecatedFindModules["CUDA"] = cmPolicies::CMP0146;
this->DeprecatedFindModules["Dart"] = cmPolicies::CMP0145;
this->DeprecatedFindModules["Qt"] = cmPolicies::CMP0084;
}
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 5c7d217..6e78f55 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -2402,15 +2402,12 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
}
} targetObjectsNode;
-static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
+struct TargetRuntimeDllsBaseNode : public cmGeneratorExpressionNode
{
- TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)
-
- std::string Evaluate(
+ std::vector<std::string> CollectDlls(
const std::vector<std::string>& parameters,
cmGeneratorExpressionContext* context,
- const GeneratorExpressionContent* content,
- cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ const GeneratorExpressionContent* content) const
{
std::string const& tgtName = parameters.front();
cmGeneratorTarget* gt = context->LG->FindGeneratorTargetToUse(tgtName);
@@ -2419,7 +2416,7 @@ static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
e << "Objects of target \"" << tgtName
<< "\" referenced but no such target exists.";
reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
+ return std::vector<std::string>();
}
cmStateEnums::TargetType type = gt->GetType();
if (type != cmStateEnums::EXECUTABLE &&
@@ -2430,7 +2427,7 @@ static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
<< "\" referenced but is not one of the allowed target types "
<< "(EXECUTABLE, SHARED, MODULE).";
reportError(context, content->GetOriginalExpression(), e.str());
- return std::string();
+ return std::vector<std::string>();
}
if (auto* cli = gt->GetLinkInformation(context->Config)) {
@@ -2443,13 +2440,51 @@ static const struct TargetRuntimeDllsNode : public cmGeneratorExpressionNode
}
}
- return cmJoin(dllPaths, ";");
+ return dllPaths;
}
- return "";
+ return std::vector<std::string>();
+ }
+};
+
+static const struct TargetRuntimeDllsNode : public TargetRuntimeDllsBaseNode
+{
+ TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ std::vector<std::string> dlls = CollectDlls(parameters, context, content);
+ return cmJoin(dlls, ";");
}
} targetRuntimeDllsNode;
+static const struct TargetRuntimeDllDirsNode : public TargetRuntimeDllsBaseNode
+{
+ TargetRuntimeDllDirsNode() {} // NOLINT(modernize-use-equals-default)
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ std::vector<std::string> dlls = CollectDlls(parameters, context, content);
+ std::vector<std::string> dllDirs;
+ for (const std::string& dll : dlls) {
+ std::string directory = cmSystemTools::GetFilenamePath(dll);
+ if (std::find(dllDirs.begin(), dllDirs.end(), directory) ==
+ dllDirs.end()) {
+ dllDirs.push_back(directory);
+ }
+ }
+ return cmJoin(dllDirs, ";");
+ }
+} targetRuntimeDllDirsNode;
+
static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
{
CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default)
@@ -2658,10 +2693,14 @@ static const struct InstallPrefixNode : public cmGeneratorExpressionNode
class ArtifactDirTag;
class ArtifactLinkerTag;
+class ArtifactLinkerLibraryTag;
+class ArtifactLinkerImportTag;
class ArtifactNameTag;
+class ArtifactImportTag;
class ArtifactPathTag;
class ArtifactPdbTag;
class ArtifactSonameTag;
+class ArtifactSonameImportTag;
class ArtifactBundleDirTag;
class ArtifactBundleDirNameTag;
class ArtifactBundleContentDirTag;
@@ -2771,6 +2810,38 @@ struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
};
template <>
+struct TargetFilesystemArtifactResultCreator<ArtifactSonameImportTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ // The target soname file (.so.1).
+ if (target->IsDLLPlatform()) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_SONAME_IMPORT_FILE is not allowed "
+ "for DLL target platforms.");
+ return std::string();
+ }
+ if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_SONAME_IMPORT_FILE is allowed only for "
+ "SHARED libraries.");
+ return std::string();
+ }
+
+ if (target->HasImportLibrary(context->Config)) {
+ return cmStrCat(target->GetDirectory(
+ context->Config, cmStateEnums::ImportLibraryArtifact),
+ '/',
+ target->GetSOName(context->Config,
+ cmStateEnums::ImportLibraryArtifact));
+ }
+ return std::string{};
+ }
+};
+
+template <>
struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
{
static std::string Create(cmGeneratorTarget* target,
@@ -2817,7 +2888,8 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content)
{
- // The file used to link to the target (.so, .lib, .a).
+ // The file used to link to the target (.so, .lib, .a) or import file
+ // (.lib, .tbd).
if (!target->IsLinkable()) {
::reportError(context, content->GetOriginalExpression(),
"TARGET_LINKER_FILE is allowed only for libraries and "
@@ -2833,6 +2905,55 @@ struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
};
template <>
+struct TargetFilesystemArtifactResultCreator<ArtifactLinkerLibraryTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ // The file used to link to the target (.dylib, .so, .a).
+ if (!target->IsLinkable() ||
+ target->GetType() == cmStateEnums::EXECUTABLE) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_LIBRARY_FILE is allowed only for libraries "
+ "with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (!target->IsDLLPlatform() ||
+ target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ return target->GetFullPath(context->Config,
+ cmStateEnums::RuntimeBinaryArtifact);
+ }
+ return std::string{};
+ }
+};
+
+template <>
+struct TargetFilesystemArtifactResultCreator<ArtifactLinkerImportTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ // The file used to link to the target (.lib, .tbd).
+ if (!target->IsLinkable()) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_LINKER_IMPORT_FILE is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetFullPath(context->Config,
+ cmStateEnums::ImportLibraryArtifact);
+ }
+ return std::string{};
+ }
+};
+
+template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag>
{
static std::string Create(cmGeneratorTarget* target,
@@ -2929,6 +3050,21 @@ struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
}
};
+template <>
+struct TargetFilesystemArtifactResultCreator<ArtifactImportTag>
+{
+ static std::string Create(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* /*unused*/)
+ {
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetFullPath(context->Config,
+ cmStateEnums::ImportLibraryArtifact, true);
+ }
+ return std::string{};
+ }
+};
+
template <typename ArtifactT>
struct TargetFilesystemArtifactResultGetter
{
@@ -3054,12 +3190,24 @@ struct TargetFilesystemArtifactNodeGroup
static const TargetFilesystemArtifactNodeGroup<ArtifactNameTag>
targetNodeGroup;
+static const TargetFilesystemArtifactNodeGroup<ArtifactImportTag>
+ targetImportNodeGroup;
+
static const TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag>
targetLinkerNodeGroup;
+static const TargetFilesystemArtifactNodeGroup<ArtifactLinkerLibraryTag>
+ targetLinkerLibraryNodeGroup;
+
+static const TargetFilesystemArtifactNodeGroup<ArtifactLinkerImportTag>
+ targetLinkerImportNodeGroup;
+
static const TargetFilesystemArtifactNodeGroup<ArtifactSonameTag>
targetSoNameNodeGroup;
+static const TargetFilesystemArtifactNodeGroup<ArtifactSonameImportTag>
+ targetSoNameImportNodeGroup;
+
static const TargetFilesystemArtifactNodeGroup<ArtifactPdbTag>
targetPdbNodeGroup;
@@ -3099,13 +3247,30 @@ struct TargetOutputNameArtifactResultGetter<ArtifactNameTag>
};
template <>
+struct TargetOutputNameArtifactResultGetter<ArtifactImportTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* /*unused*/)
+ {
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetOutputName(context->Config,
+ cmStateEnums::ImportLibraryArtifact) +
+ target->GetFilePostfix(context->Config);
+ }
+ return std::string{};
+ }
+};
+
+template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
{
static std::string Get(cmGeneratorTarget* target,
cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content)
{
- // The file used to link to the target (.so, .lib, .a).
+ // The library file used to link to the target (.so, .lib, .a) or import
+ // file (.lin, .tbd).
if (!target->IsLinkable()) {
::reportError(context, content->GetOriginalExpression(),
"TARGET_LINKER_FILE_BASE_NAME is allowed only for "
@@ -3122,6 +3287,56 @@ struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
};
template <>
+struct TargetOutputNameArtifactResultGetter<ArtifactLinkerLibraryTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ // The library file used to link to the target (.so, .lib, .a).
+ if (!target->IsLinkable() ||
+ target->GetType() == cmStateEnums::EXECUTABLE) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_LIBRARY_FILE_BASE_NAME is allowed only for "
+ "libraries with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (!target->IsDLLPlatform() ||
+ target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ return target->GetOutputName(context->Config,
+ cmStateEnums::ImportLibraryArtifact) +
+ target->GetFilePostfix(context->Config);
+ }
+ return std::string{};
+ }
+};
+
+template <>
+struct TargetOutputNameArtifactResultGetter<ArtifactLinkerImportTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ // The import file used to link to the target (.lib, .tbd).
+ if (!target->IsLinkable()) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_IMPORT_FILE_BASE_NAME is allowed only for "
+ "libraries and executables with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetOutputName(context->Config,
+ cmStateEnums::ImportLibraryArtifact) +
+ target->GetFilePostfix(context->Config);
+ }
+ return std::string{};
+ }
+};
+
+template <>
struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
{
static std::string Get(cmGeneratorTarget* target,
@@ -3192,15 +3407,27 @@ struct TargetFileBaseNameArtifact : public TargetArtifactBase
static const TargetFileBaseNameArtifact<ArtifactNameTag>
targetFileBaseNameNode;
+static const TargetFileBaseNameArtifact<ArtifactImportTag>
+ targetImportFileBaseNameNode;
static const TargetFileBaseNameArtifact<ArtifactLinkerTag>
targetLinkerFileBaseNameNode;
+static const TargetFileBaseNameArtifact<ArtifactLinkerLibraryTag>
+ targetLinkerLibraryFileBaseNameNode;
+static const TargetFileBaseNameArtifact<ArtifactLinkerImportTag>
+ targetLinkerImportFileBaseNameNode;
static const TargetFileBaseNameArtifact<ArtifactPdbTag>
targetPdbFileBaseNameNode;
class ArtifactFilePrefixTag;
+class ArtifactImportFilePrefixTag;
class ArtifactLinkerFilePrefixTag;
+class ArtifactLinkerLibraryFilePrefixTag;
+class ArtifactLinkerImportFilePrefixTag;
class ArtifactFileSuffixTag;
+class ArtifactImportFileSuffixTag;
class ArtifactLinkerFileSuffixTag;
+class ArtifactLinkerLibraryFileSuffixTag;
+class ArtifactLinkerImportFileSuffixTag;
template <typename ArtifactT>
struct TargetFileArtifactResultGetter
@@ -3221,6 +3448,20 @@ struct TargetFileArtifactResultGetter<ArtifactFilePrefixTag>
}
};
template <>
+struct TargetFileArtifactResultGetter<ArtifactImportFilePrefixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent*)
+ {
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetFilePrefix(context->Config,
+ cmStateEnums::ImportLibraryArtifact);
+ }
+ return std::string{};
+ }
+};
+template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
{
static std::string Get(cmGeneratorTarget* target,
@@ -3228,9 +3469,10 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
const GeneratorExpressionContent* content)
{
if (!target->IsLinkable()) {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_LINKER_PREFIX is allowed only for libraries and "
- "executables with ENABLE_EXPORTS.");
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_LINKER_FILE_PREFIX is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
return std::string();
}
@@ -3243,6 +3485,52 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
}
};
template <>
+struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFilePrefixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (!target->IsLinkable() ||
+ target->GetType() == cmStateEnums::EXECUTABLE) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_LINKER_LIBRARY_FILE_PREFIX is allowed only for libraries "
+ "with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (!target->IsDLLPlatform() ||
+ target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ return target->GetFilePrefix(context->Config,
+ cmStateEnums::RuntimeBinaryArtifact);
+ }
+ return std::string{};
+ }
+};
+template <>
+struct TargetFileArtifactResultGetter<ArtifactLinkerImportFilePrefixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (!target->IsLinkable()) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_LINKER_IMPORT_FILE_PREFIX is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetFilePrefix(context->Config,
+ cmStateEnums::ImportLibraryArtifact);
+ }
+ return std::string{};
+ }
+};
+template <>
struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
@@ -3253,6 +3541,20 @@ struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
}
};
template <>
+struct TargetFileArtifactResultGetter<ArtifactImportFileSuffixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent*)
+ {
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetFileSuffix(context->Config,
+ cmStateEnums::ImportLibraryArtifact);
+ }
+ return std::string{};
+ }
+};
+template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
{
static std::string Get(cmGeneratorTarget* target,
@@ -3260,9 +3562,10 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
const GeneratorExpressionContent* content)
{
if (!target->IsLinkable()) {
- ::reportError(context, content->GetOriginalExpression(),
- "TARGET_LINKER_SUFFIX is allowed only for libraries and "
- "executables with ENABLE_EXPORTS.");
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_LINKER_FILE_SUFFIX is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
return std::string();
}
@@ -3274,6 +3577,51 @@ struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
return target->GetFileSuffix(context->Config, artifact);
}
};
+template <>
+struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFileSuffixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (!target->IsLinkable() ||
+ target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ ::reportError(context, content->GetOriginalExpression(),
+ "TARGET_LINKER_LIBRARY_FILE_SUFFIX is allowed only for "
+ "libraries with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (!target->IsDLLPlatform() ||
+ target->GetType() == cmStateEnums::STATIC_LIBRARY) {
+ return target->GetFileSuffix(context->Config,
+ cmStateEnums::RuntimeBinaryArtifact);
+ }
+ return std::string{};
+ }
+};
+template <>
+struct TargetFileArtifactResultGetter<ArtifactLinkerImportFileSuffixTag>
+{
+ static std::string Get(cmGeneratorTarget* target,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content)
+ {
+ if (!target->IsLinkable()) {
+ ::reportError(
+ context, content->GetOriginalExpression(),
+ "TARGET_LINKER_IMPORT_FILE_SUFFIX is allowed only for libraries and "
+ "executables with ENABLE_EXPORTS.");
+ return std::string();
+ }
+
+ if (target->HasImportLibrary(context->Config)) {
+ return target->GetFileSuffix(context->Config,
+ cmStateEnums::ImportLibraryArtifact);
+ }
+ return std::string{};
+ }
+};
template <typename ArtifactT>
struct TargetFileArtifact : public TargetArtifactBase
@@ -3304,11 +3652,23 @@ struct TargetFileArtifact : public TargetArtifactBase
};
static const TargetFileArtifact<ArtifactFilePrefixTag> targetFilePrefixNode;
+static const TargetFileArtifact<ArtifactImportFilePrefixTag>
+ targetImportFilePrefixNode;
static const TargetFileArtifact<ArtifactLinkerFilePrefixTag>
targetLinkerFilePrefixNode;
+static const TargetFileArtifact<ArtifactLinkerLibraryFilePrefixTag>
+ targetLinkerLibraryFilePrefixNode;
+static const TargetFileArtifact<ArtifactLinkerImportFilePrefixTag>
+ targetLinkerImportFilePrefixNode;
static const TargetFileArtifact<ArtifactFileSuffixTag> targetFileSuffixNode;
+static const TargetFileArtifact<ArtifactImportFileSuffixTag>
+ targetImportFileSuffixNode;
static const TargetFileArtifact<ArtifactLinkerFileSuffixTag>
targetLinkerFileSuffixNode;
+static const TargetFileArtifact<ArtifactLinkerLibraryFileSuffixTag>
+ targetLinkerLibraryFileSuffixNode;
+static const TargetFileArtifact<ArtifactLinkerImportFileSuffixTag>
+ targetLinkerImportFileSuffixNode;
static const struct ShellPathNode : public cmGeneratorExpressionNode
{
@@ -3376,23 +3736,52 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "CONFIGURATION", &configurationNode },
{ "CONFIG", &configurationTestNode },
{ "TARGET_FILE", &targetNodeGroup.File },
+ { "TARGET_IMPORT_FILE", &targetImportNodeGroup.File },
{ "TARGET_LINKER_FILE", &targetLinkerNodeGroup.File },
+ { "TARGET_LINKER_LIBRARY_FILE", &targetLinkerLibraryNodeGroup.File },
+ { "TARGET_LINKER_IMPORT_FILE", &targetLinkerImportNodeGroup.File },
{ "TARGET_SONAME_FILE", &targetSoNameNodeGroup.File },
+ { "TARGET_SONAME_IMPORT_FILE", &targetSoNameImportNodeGroup.File },
{ "TARGET_PDB_FILE", &targetPdbNodeGroup.File },
{ "TARGET_FILE_BASE_NAME", &targetFileBaseNameNode },
+ { "TARGET_IMPORT_FILE_BASE_NAME", &targetImportFileBaseNameNode },
{ "TARGET_LINKER_FILE_BASE_NAME", &targetLinkerFileBaseNameNode },
+ { "TARGET_LINKER_LIBRARY_FILE_BASE_NAME",
+ &targetLinkerLibraryFileBaseNameNode },
+ { "TARGET_LINKER_IMPORT_FILE_BASE_NAME",
+ &targetLinkerImportFileBaseNameNode },
{ "TARGET_PDB_FILE_BASE_NAME", &targetPdbFileBaseNameNode },
{ "TARGET_FILE_PREFIX", &targetFilePrefixNode },
+ { "TARGET_IMPORT_FILE_PREFIX", &targetImportFilePrefixNode },
{ "TARGET_LINKER_FILE_PREFIX", &targetLinkerFilePrefixNode },
+ { "TARGET_LINKER_LIBRARY_FILE_PREFIX",
+ &targetLinkerLibraryFilePrefixNode },
+ { "TARGET_LINKER_IMPORT_FILE_PREFIX", &targetLinkerImportFilePrefixNode },
{ "TARGET_FILE_SUFFIX", &targetFileSuffixNode },
+ { "TARGET_IMPORT_FILE_SUFFIX", &targetImportFileSuffixNode },
{ "TARGET_LINKER_FILE_SUFFIX", &targetLinkerFileSuffixNode },
+ { "TARGET_LINKER_LIBRARY_FILE_SUFFIX",
+ &targetLinkerLibraryFileSuffixNode },
+ { "TARGET_LINKER_IMPORT_FILE_SUFFIX", &targetLinkerImportFileSuffixNode },
{ "TARGET_FILE_NAME", &targetNodeGroup.FileName },
+ { "TARGET_IMPORT_FILE_NAME", &targetImportNodeGroup.FileName },
{ "TARGET_LINKER_FILE_NAME", &targetLinkerNodeGroup.FileName },
+ { "TARGET_LINKER_LIBRARY_FILE_NAME",
+ &targetLinkerLibraryNodeGroup.FileName },
+ { "TARGET_LINKER_IMPORT_FILE_NAME",
+ &targetLinkerImportNodeGroup.FileName },
{ "TARGET_SONAME_FILE_NAME", &targetSoNameNodeGroup.FileName },
+ { "TARGET_SONAME_IMPORT_FILE_NAME",
+ &targetSoNameImportNodeGroup.FileName },
{ "TARGET_PDB_FILE_NAME", &targetPdbNodeGroup.FileName },
{ "TARGET_FILE_DIR", &targetNodeGroup.FileDir },
+ { "TARGET_IMPORT_FILE_DIR", &targetImportNodeGroup.FileDir },
{ "TARGET_LINKER_FILE_DIR", &targetLinkerNodeGroup.FileDir },
+ { "TARGET_LINKER_LIBRARY_FILE_DIR",
+ &targetLinkerLibraryNodeGroup.FileDir },
+ { "TARGET_LINKER_IMPORT_FILE_DIR", &targetLinkerImportNodeGroup.FileDir },
{ "TARGET_SONAME_FILE_DIR", &targetSoNameNodeGroup.FileDir },
+ { "TARGET_SONAME_IMPORT_FILE_DIR", &targetSoNameImportNodeGroup.FileDir },
{ "TARGET_PDB_FILE_DIR", &targetPdbNodeGroup.FileDir },
{ "TARGET_BUNDLE_DIR", &targetBundleDirNode },
{ "TARGET_BUNDLE_DIR_NAME", &targetBundleDirNameNode },
@@ -3420,6 +3809,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "TARGET_NAME_IF_EXISTS", &targetNameIfExistsNode },
{ "TARGET_GENEX_EVAL", &targetGenexEvalNode },
{ "TARGET_RUNTIME_DLLS", &targetRuntimeDllsNode },
+ { "TARGET_RUNTIME_DLL_DIRS", &targetRuntimeDllDirsNode },
{ "GENEX_EVAL", &genexEvalNode },
{ "BUILD_INTERFACE", &buildInterfaceNode },
{ "INSTALL_INTERFACE", &installInterfaceNode },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 112a87f..4cfa1d7 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -459,6 +459,11 @@ std::string const& cmGeneratorTarget::GetSafeProperty(
const char* cmGeneratorTarget::GetOutputTargetType(
cmStateEnums::ArtifactType artifact) const
{
+ if (this->IsFrameworkOnApple() || this->GetGlobalGenerator()->IsXcode()) {
+ // import file (i.e. .tbd file) is always in same location as library
+ artifact = cmStateEnums::RuntimeBinaryArtifact;
+ }
+
switch (this->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
if (this->IsDLLPlatform()) {
@@ -471,9 +476,15 @@ const char* cmGeneratorTarget::GetOutputTargetType(
return "ARCHIVE";
}
} else {
- // For non-DLL platforms shared libraries are treated as
- // library targets.
- return "LIBRARY";
+ switch (artifact) {
+ case cmStateEnums::RuntimeBinaryArtifact:
+ // For non-DLL platforms shared libraries are treated as
+ // library targets.
+ return "LIBRARY";
+ case cmStateEnums::ImportLibraryArtifact:
+ // Library import libraries are treated as archive targets.
+ return "ARCHIVE";
+ }
}
break;
case cmStateEnums::STATIC_LIBRARY:
@@ -1730,7 +1741,8 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
std::move(entryCge), fileSet);
entries.Entries.emplace_back(
EvaluateTargetPropertyEntry(headTarget, config, "", dagChecker, tpe));
- for (auto const& file : entries.Entries.back().Values) {
+ EvaluatedTargetPropertyEntry const& entry = entries.Entries.back();
+ for (auto const& file : entry.Values) {
auto* sf = headTarget->Makefile->GetOrCreateSource(file);
if (fileSet->GetType() == "HEADERS"_s) {
sf->SetProperty("HEADER_FILE_ONLY", "TRUE");
@@ -1741,13 +1753,11 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
std::string w;
auto path = sf->ResolveFullPath(&e, &w);
if (!w.empty()) {
- cm->IssueMessage(MessageType::AUTHOR_WARNING, w,
- headTarget->GetBacktrace());
+ cm->IssueMessage(MessageType::AUTHOR_WARNING, w, entry.Backtrace);
}
if (path.empty()) {
if (!e.empty()) {
- cm->IssueMessage(MessageType::FATAL_ERROR, e,
- headTarget->GetBacktrace());
+ cm->IssueMessage(MessageType::FATAL_ERROR, e, entry.Backtrace);
}
return;
}
@@ -1822,11 +1832,11 @@ bool processSources(cmGeneratorTarget const* tgt,
std::string fullPath = sf->ResolveFullPath(&e, &w);
cmake* cm = tgt->GetLocalGenerator()->GetCMakeInstance();
if (!w.empty()) {
- cm->IssueMessage(MessageType::AUTHOR_WARNING, w, tgt->GetBacktrace());
+ cm->IssueMessage(MessageType::AUTHOR_WARNING, w, entry.Backtrace);
}
if (fullPath.empty()) {
if (!e.empty()) {
- cm->IssueMessage(MessageType::FATAL_ERROR, e, tgt->GetBacktrace());
+ cm->IssueMessage(MessageType::FATAL_ERROR, e, entry.Backtrace);
}
return contextDependent;
}
@@ -2534,7 +2544,8 @@ bool cmGeneratorTarget::CanGenerateInstallNameDir(
return !skip;
}
-std::string cmGeneratorTarget::GetSOName(const std::string& config) const
+std::string cmGeneratorTarget::GetSOName(
+ const std::string& config, cmStateEnums::ArtifactType artifact) const
{
if (this->IsImported()) {
// Lookup the imported soname.
@@ -2562,7 +2573,9 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return "";
}
// Compute the soname that will be built.
- return this->GetLibraryNames(config).SharedObject;
+ return artifact == cmStateEnums::RuntimeBinaryArtifact
+ ? this->GetLibraryNames(config).SharedObject
+ : this->GetLibraryNames(config).ImportLibrary;
}
namespace {
@@ -3090,6 +3103,16 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo(
}
}
+bool cmGeneratorTarget::IsAIX() const
+{
+ return this->Target->IsAIX();
+}
+
+bool cmGeneratorTarget::IsApple() const
+{
+ return this->Target->IsApple();
+}
+
bool cmGeneratorTarget::IsDLLPlatform() const
{
return this->Target->IsDLLPlatform();
@@ -3428,7 +3451,7 @@ std::string cmGeneratorTarget::GetCompilePDBDirectory(
void cmGeneratorTarget::GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const
{
- if (!this->Makefile->IsOn("APPLE")) {
+ if (!this->IsApple()) {
return;
}
cmValue archs = nullptr;
@@ -3926,7 +3949,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
&dagChecker, entries, IncludeRuntimeInterface::Yes);
- if (this->Makefile->IsOn("APPLE")) {
+ if (this->IsApple()) {
if (cmLinkImplementationLibraries const* impl =
this->GetLinkImplementationLibraries(config,
LinkInterfaceFor::Usage)) {
@@ -5094,10 +5117,18 @@ void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
f = cmStrCat(dir, '/', targetNames.PDB);
gg->AddToManifest(f);
}
+
+ dir = this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact);
+ if (!targetNames.ImportOutput.empty()) {
+ f = cmStrCat(dir, '/', targetNames.ImportOutput);
+ gg->AddToManifest(f);
+ }
if (!targetNames.ImportLibrary.empty()) {
- f =
- cmStrCat(this->GetDirectory(config, cmStateEnums::ImportLibraryArtifact),
- '/', targetNames.ImportLibrary);
+ f = cmStrCat(dir, '/', targetNames.ImportLibrary);
+ gg->AddToManifest(f);
+ }
+ if (!targetNames.ImportReal.empty()) {
+ f = cmStrCat(dir, '/', targetNames.ImportReal);
gg->AddToManifest(f);
}
}
@@ -5217,14 +5248,20 @@ std::string cmGeneratorTarget::NormalGetFullPath(
}
break;
case cmStateEnums::ImportLibraryArtifact:
- fpath += this->GetFullName(config, cmStateEnums::ImportLibraryArtifact);
+ if (realname) {
+ fpath +=
+ this->NormalGetRealName(config, cmStateEnums::ImportLibraryArtifact);
+ } else {
+ fpath +=
+ this->GetFullName(config, cmStateEnums::ImportLibraryArtifact);
+ }
break;
}
return fpath;
}
std::string cmGeneratorTarget::NormalGetRealName(
- const std::string& config) const
+ const std::string& config, cmStateEnums::ArtifactType artifact) const
{
// This should not be called for imported targets.
// TODO: Split cmTarget into a class hierarchy to get compile-time
@@ -5235,12 +5272,13 @@ std::string cmGeneratorTarget::NormalGetRealName(
this->LocalGenerator->IssueMessage(MessageType::INTERNAL_ERROR, msg);
}
- if (this->GetType() == cmStateEnums::EXECUTABLE) {
- // Compute the real name that will be built.
- return this->GetExecutableNames(config).Real;
- }
+ Names names = this->GetType() == cmStateEnums::EXECUTABLE
+ ? this->GetExecutableNames(config)
+ : this->GetLibraryNames(config);
+
// Compute the real name that will be built.
- return this->GetLibraryNames(config).Real;
+ return artifact == cmStateEnums::RuntimeBinaryArtifact ? names.Real
+ : names.ImportReal;
}
cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
@@ -5285,17 +5323,16 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
// The library name.
targetNames.Base = components.base;
targetNames.Output =
- components.prefix + targetNames.Base + components.suffix;
+ cmStrCat(components.prefix, targetNames.Base, components.suffix);
if (this->IsFrameworkOnApple()) {
targetNames.Real = components.prefix;
if (!this->Makefile->PlatformIsAppleEmbedded()) {
- targetNames.Real += "Versions/";
- targetNames.Real += this->GetFrameworkVersion();
- targetNames.Real += "/";
+ targetNames.Real +=
+ cmStrCat("Versions/", this->GetFrameworkVersion(), '/');
}
- targetNames.Real += targetNames.Base + components.suffix;
- targetNames.SharedObject = targetNames.Real + components.suffix;
+ targetNames.Real += cmStrCat(targetNames.Base, components.suffix);
+ targetNames.SharedObject = targetNames.Real;
} else {
// The library's soname.
this->ComputeVersionedName(targetNames.SharedObject, components.prefix,
@@ -5308,11 +5345,36 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
targetNames.Output, version);
}
- // The import library name.
+ // The import library names.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::MODULE_LIBRARY) {
- targetNames.ImportLibrary =
- this->GetFullNameInternal(config, cmStateEnums::ImportLibraryArtifact);
+ NameComponents const& importComponents =
+ this->GetFullNameInternalComponents(config,
+ cmStateEnums::ImportLibraryArtifact);
+ targetNames.ImportOutput = cmStrCat(
+ importComponents.prefix, importComponents.base, importComponents.suffix);
+
+ if (this->IsFrameworkOnApple() && this->IsSharedLibraryWithExports()) {
+ targetNames.ImportReal = components.prefix;
+ if (!this->Makefile->PlatformIsAppleEmbedded()) {
+ targetNames.ImportReal +=
+ cmStrCat("Versions/", this->GetFrameworkVersion(), '/');
+ }
+ targetNames.ImportReal +=
+ cmStrCat(importComponents.base, importComponents.suffix);
+ targetNames.ImportLibrary = targetNames.ImportOutput;
+ } else {
+ // The import library's soname.
+ this->ComputeVersionedName(
+ targetNames.ImportLibrary, importComponents.prefix,
+ importComponents.base, importComponents.suffix,
+ targetNames.ImportOutput, soversion);
+
+ // The import library's real name on disk.
+ this->ComputeVersionedName(
+ targetNames.ImportReal, importComponents.prefix, importComponents.base,
+ importComponents.suffix, targetNames.ImportOutput, version);
+ }
}
// The program database file name.
@@ -5374,6 +5436,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
// The import library name.
targetNames.ImportLibrary =
this->GetFullNameInternal(config, cmStateEnums::ImportLibraryArtifact);
+ targetNames.ImportReal = targetNames.ImportLibrary;
+ targetNames.ImportOutput = targetNames.ImportLibrary;
// The program database file name.
targetNames.PDB = this->GetPDBName(config);
@@ -5455,15 +5519,18 @@ cmGeneratorTarget::GetFullNameInternalComponents(
}
// Compute the full name for main target types.
- const std::string configPostfix = this->GetFilePostfix(config);
+ std::string configPostfix = this->GetFilePostfix(config);
- // frameworks have directory prefix but no suffix
+ // frameworks have directory prefix
std::string fw_prefix;
if (this->IsFrameworkOnApple()) {
fw_prefix =
cmStrCat(this->GetFrameworkDirectory(config, ContentLevel), '/');
targetPrefix = cmValue(fw_prefix);
- targetSuffix = nullptr;
+ if (!isImportedLibraryArtifact) {
+ // no suffix
+ targetSuffix = nullptr;
+ }
}
if (this->IsCFBundleOnApple()) {
@@ -5482,8 +5549,8 @@ cmGeneratorTarget::GetFullNameInternalComponents(
// When using Xcode, the postfix should be part of the suffix rather than
// the base, because the suffix ends up being used in Xcode's
// EXECUTABLE_SUFFIX attribute.
- if (this->IsFrameworkOnApple() &&
- this->GetGlobalGenerator()->GetName() == "Xcode") {
+ if (this->IsFrameworkOnApple() && this->GetGlobalGenerator()->IsXcode()) {
+ configPostfix += *targetSuffix;
targetSuffix = cmValue(configPostfix);
} else {
outBase += configPostfix;
@@ -6779,12 +6846,12 @@ void cmGeneratorTarget::ComputeVersionedName(
std::string& vName, std::string const& prefix, std::string const& base,
std::string const& suffix, std::string const& name, cmValue version) const
{
- vName = this->Makefile->IsOn("APPLE") ? (prefix + base) : name;
+ vName = this->IsApple() ? (prefix + base) : name;
if (version) {
vName += ".";
vName += *version;
}
- vName += this->Makefile->IsOn("APPLE") ? suffix : std::string();
+ vName += this->IsApple() ? suffix : std::string();
}
std::vector<std::string> cmGeneratorTarget::GetPropertyKeys() const
@@ -8553,19 +8620,38 @@ bool cmGeneratorTarget::HasContextDependentSources() const
bool cmGeneratorTarget::IsExecutableWithExports() const
{
- return (this->GetType() == cmStateEnums::EXECUTABLE &&
- this->GetPropertyAsBool("ENABLE_EXPORTS"));
+ return this->Target->IsExecutableWithExports();
+}
+
+bool cmGeneratorTarget::IsSharedLibraryWithExports() const
+{
+ return this->Target->IsSharedLibraryWithExports();
}
bool cmGeneratorTarget::HasImportLibrary(std::string const& config) const
{
+ bool generate_Stubs = true;
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ // take care of CMAKE_XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS variable
+ // as well as XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS property
+ if (cmValue propGenStubs =
+ this->GetProperty("XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS")) {
+ generate_Stubs = propGenStubs == "YES";
+ } else if (cmValue varGenStubs = this->Makefile->GetDefinition(
+ "CMAKE_XCODE_ATTRIBUTE_GENERATE_TEXT_BASED_STUBS")) {
+ generate_Stubs = varGenStubs == "YES";
+ }
+ }
+
return (this->IsDLLPlatform() &&
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) &&
// Assemblies which have only managed code do not have
// import libraries.
this->GetManagedType(config) != ManagedType::Managed) ||
- (this->Target->IsAIX() && this->IsExecutableWithExports());
+ (this->IsAIX() && this->IsExecutableWithExports()) ||
+ (this->Makefile->PlatformSupportsAppleTextStubs() &&
+ this->IsSharedLibraryWithExports() && generate_Stubs);
}
bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const
@@ -8603,17 +8689,12 @@ bool cmGeneratorTarget::IsLinkable() const
bool cmGeneratorTarget::IsFrameworkOnApple() const
{
- return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
- this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
- this->Makefile->IsOn("APPLE") &&
- this->GetPropertyAsBool("FRAMEWORK"));
+ return this->Target->IsFrameworkOnApple();
}
bool cmGeneratorTarget::IsAppBundleOnApple() const
{
- return (this->GetType() == cmStateEnums::EXECUTABLE &&
- this->Makefile->IsOn("APPLE") &&
- this->GetPropertyAsBool("MACOSX_BUNDLE"));
+ return this->Target->IsAppBundleOnApple();
}
bool cmGeneratorTarget::IsXCTestOnApple() const
@@ -8623,8 +8704,8 @@ bool cmGeneratorTarget::IsXCTestOnApple() const
bool cmGeneratorTarget::IsCFBundleOnApple() const
{
- return (this->GetType() == cmStateEnums::MODULE_LIBRARY &&
- this->Makefile->IsOn("APPLE") && this->GetPropertyAsBool("BUNDLE"));
+ return (this->GetType() == cmStateEnums::MODULE_LIBRARY && this->IsApple() &&
+ this->GetPropertyAsBool("BUNDLE"));
}
cmGeneratorTarget::ManagedType cmGeneratorTarget::CheckManagedType(
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index e46c719..5d26191 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -273,7 +273,9 @@ public:
std::string NormalGetFullPath(const std::string& config,
cmStateEnums::ArtifactType artifact,
bool realname) const;
- std::string NormalGetRealName(const std::string& config) const;
+ std::string NormalGetRealName(const std::string& config,
+ cmStateEnums::ArtifactType artifact =
+ cmStateEnums::RuntimeBinaryArtifact) const;
/** Get the names of an object library's object files underneath
its object file directory. */
@@ -348,7 +350,9 @@ public:
const std::string* GetExportMacro() const;
/** Get the soname of the target. Allowed only for a shared library. */
- std::string GetSOName(const std::string& config) const;
+ std::string GetSOName(const std::string& config,
+ cmStateEnums::ArtifactType artifact =
+ cmStateEnums::RuntimeBinaryArtifact) const;
struct NameComponents
{
@@ -389,6 +393,11 @@ public:
ModuleDefinitionInfo const* GetModuleDefinitionInfo(
std::string const& config) const;
+ /** Return whether or not we are targeting AIX. */
+ bool IsAIX() const;
+ /** Return whether or not we are targeting Apple. */
+ bool IsApple() const;
+
/** Return whether or not the target is for a DLL platform. */
bool IsDLLPlatform() const;
@@ -735,6 +744,8 @@ public:
std::string Base;
std::string Output;
std::string Real;
+ std::string ImportOutput;
+ std::string ImportReal;
std::string ImportLibrary;
std::string PDB;
std::string SharedObject;
@@ -781,6 +792,10 @@ public:
bool IsExecutableWithExports() const;
+ /* Return whether this target is a shared library with capability to generate
+ * a file describing symbols exported (for example, .tbd file on Apple). */
+ bool IsSharedLibraryWithExports() const;
+
/** Return whether or not the target has a DLL import library. */
bool HasImportLibrary(std::string const& config) const;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index b5e1529..650d0aa 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -8,7 +8,6 @@
#include <cstdio>
#include <functional>
#include <sstream>
-#include <tuple>
#include <utility>
#include <cm/iterator>
@@ -571,6 +570,7 @@ void cmGlobalNinjaGenerator::Generate()
msg.str());
return;
}
+ this->InitOutputPathPrefix();
if (!this->OpenBuildFileStreams()) {
return;
}
@@ -579,10 +579,9 @@ void cmGlobalNinjaGenerator::Generate()
}
for (auto& it : this->Configs) {
- it.second.TargetDependsClosureLocalOutputs.clear();
+ it.second.TargetDependsClosures.clear();
}
- this->InitOutputPathPrefix();
this->TargetAll = this->NinjaOutputPath("all");
this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt");
this->DiagnosedCxxModuleNinjaSupport = false;
@@ -1270,6 +1269,10 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
}
CM_FALLTHROUGH;
case cmStateEnums::EXECUTABLE: {
+ if (target->IsApple() && target->HasImportLibrary(config)) {
+ outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
+ config, cmStateEnums::ImportLibraryArtifact, realname)));
+ }
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
config, cmStateEnums::RuntimeBinaryArtifact, realname)));
break;
@@ -1359,85 +1362,70 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
const std::string& config, const std::string& fileConfig, bool genexOutput)
{
- struct Entry
- {
- Entry(cmGeneratorTarget const* target_, std::string config_,
- std::string fileConfig_)
- : target(target_)
- , config(std::move(config_))
- , fileConfig(std::move(fileConfig_))
- {
- }
+ cmNinjaOuts outs;
+ this->AppendTargetDependsClosure(target, outs, config, fileConfig,
+ genexOutput, true);
+ cm::append(outputs, outs);
+}
- bool operator<(Entry const& other) const
- {
- return std::tie(target, config, fileConfig) <
- std::tie(other.target, other.config, other.fileConfig);
- }
+void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
+ cmGeneratorTarget const* target, cmNinjaOuts& outputs,
+ const std::string& config, const std::string& fileConfig, bool genexOutput,
+ bool omit_self)
+{
- cmGeneratorTarget const* target;
- std::string config;
- std::string fileConfig;
+ // try to locate the target in the cache
+ ByConfig::TargetDependsClosureKey key{
+ target,
+ config,
+ genexOutput,
};
-
- cmNinjaOuts outputSet;
- std::vector<Entry> stack;
- stack.emplace_back(target, config, fileConfig);
- std::set<Entry> seen = { stack.back() };
-
- do {
- Entry entry = std::move(stack.back());
- stack.pop_back();
-
- // generate the outputs of the target itself, if applicable
- if (entry.target != target) {
- // try to locate the target in the cache
- ByConfig::TargetDependsClosureKey localCacheKey{
- entry.target,
- entry.config,
- genexOutput,
- };
- auto& configs = this->Configs[entry.fileConfig];
- auto lb =
- configs.TargetDependsClosureLocalOutputs.lower_bound(localCacheKey);
-
- if (lb == configs.TargetDependsClosureLocalOutputs.end() ||
- lb->first != localCacheKey) {
- cmNinjaDeps outs;
- this->AppendTargetOutputs(entry.target, outs, entry.config,
- DependOnTargetArtifact);
- configs.TargetDependsClosureLocalOutputs.emplace_hint(
- lb, localCacheKey, outs);
- for (auto& value : outs) {
- outputSet.emplace(std::move(value));
- }
- } else {
- outputSet.insert(lb->second.begin(), lb->second.end());
- }
- }
-
- // push next dependencies
- for (const auto& dep_target : this->GetTargetDirectDepends(entry.target)) {
+ auto find = this->Configs[fileConfig].TargetDependsClosures.lower_bound(key);
+
+ if (find == this->Configs[fileConfig].TargetDependsClosures.end() ||
+ find->first != key) {
+ // We now calculate the closure outputs by inspecting the dependent
+ // targets recursively.
+ // For that we have to distinguish between a local result set that is only
+ // relevant for filling the cache entries properly isolated and a global
+ // result set that is relevant for the result of the top level call to
+ // AppendTargetDependsClosure.
+ cmNinjaOuts this_outs; // this will be the new cache entry
+
+ for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
if (!dep_target->IsInBuildSystem()) {
continue;
}
- if (!this->IsSingleConfigUtility(entry.target) &&
+ if (!this->IsSingleConfigUtility(target) &&
!this->IsSingleConfigUtility(dep_target) &&
this->EnableCrossConfigBuild() && !dep_target.IsCross() &&
!genexOutput) {
continue;
}
- auto emplaceRes = seen.emplace(
- dep_target, dep_target.IsCross() ? entry.fileConfig : entry.config,
- entry.fileConfig);
- if (emplaceRes.second) {
- stack.emplace_back(*emplaceRes.first);
+ if (dep_target.IsCross()) {
+ this->AppendTargetDependsClosure(dep_target, this_outs, fileConfig,
+ fileConfig, genexOutput, false);
+ } else {
+ this->AppendTargetDependsClosure(dep_target, this_outs, config,
+ fileConfig, genexOutput, false);
}
}
- } while (!stack.empty());
- cm::append(outputs, outputSet);
+ find = this->Configs[fileConfig].TargetDependsClosures.emplace_hint(
+ find, key, std::move(this_outs));
+ }
+
+ // now fill the outputs of the final result from the newly generated cache
+ // entry
+ outputs.insert(find->second.begin(), find->second.end());
+
+ // finally generate the outputs of the target itself, if applicable
+ cmNinjaDeps outs;
+ if (!omit_self) {
+ this->AppendTargetOutputs(target, outs, config, DependOnTargetArtifact);
+ }
+ outputs.insert(outs.begin(), outs.end());
}
void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
@@ -2075,9 +2063,10 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
build.Outputs.front() = this->BuildAlias(
this->NinjaOutputPath(this->GetCleanTargetName()), config);
if (this->IsMultiConfig()) {
- build.Variables["TARGETS"] =
- cmStrCat(this->BuildAlias(GetByproductsForCleanTargetName(), config),
- " ", GetByproductsForCleanTargetName());
+ build.Variables["TARGETS"] = cmStrCat(
+ this->BuildAlias(
+ this->NinjaOutputPath(GetByproductsForCleanTargetName()), config),
+ " ", this->NinjaOutputPath(GetByproductsForCleanTargetName()));
}
build.ExplicitDeps.clear();
if (additionalFiles) {
@@ -2092,7 +2081,8 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
if (this->IsMultiConfig()) {
build.Variables["FILE_ARG"] = cmStrCat(
"-f ",
- cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+ this->NinjaOutputPath(
+ cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig)));
}
this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
}
@@ -2114,8 +2104,8 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
std::vector<std::string> byproducts;
byproducts.reserve(this->CrossConfigs.size());
for (auto const& config : this->CrossConfigs) {
- byproducts.push_back(
- this->BuildAlias(GetByproductsForCleanTargetName(), config));
+ byproducts.push_back(this->BuildAlias(
+ this->NinjaOutputPath(GetByproductsForCleanTargetName()), config));
}
byproducts.emplace_back(GetByproductsForCleanTargetName());
build.Variables["TARGETS"] = cmJoin(byproducts, " ");
@@ -2123,7 +2113,8 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
for (auto const& fileConfig : configs) {
build.Variables["FILE_ARG"] = cmStrCat(
"-f ",
- cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+ this->NinjaOutputPath(
+ cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig)));
this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
}
}
@@ -2906,7 +2897,8 @@ bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
*this->DefaultFileStream << "# Build using rules for '"
<< this->DefaultFileConfig << "'.\n\n"
<< "include "
- << GetNinjaImplFilename(this->DefaultFileConfig)
+ << this->NinjaOutputPath(
+ GetNinjaImplFilename(this->DefaultFileConfig))
<< "\n\n";
// Write a comment about this file.
@@ -2939,7 +2931,8 @@ bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
*this->ConfigFileStreams[config]
<< "# This file contains aliases specific to the \"" << config
<< "\"\n# configuration.\n\n"
- << "include " << GetNinjaImplFilename(config) << "\n\n";
+ << "include " << this->NinjaOutputPath(GetNinjaImplFilename(config))
+ << "\n\n";
return true;
});
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 6d23e89..c08bb46 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -354,6 +354,11 @@ public:
const std::string& config,
const std::string& fileConfig,
bool genexOutput);
+ void AppendTargetDependsClosure(cmGeneratorTarget const* target,
+ cmNinjaOuts& outputs,
+ const std::string& config,
+ const std::string& fileConfig,
+ bool genexOutput, bool omit_self);
void AppendDirectoryForConfig(const std::string& prefix,
const std::string& config,
@@ -611,8 +616,7 @@ private:
bool GenexOutput;
};
- std::map<TargetDependsClosureKey, cmNinjaDeps>
- TargetDependsClosureLocalOutputs;
+ std::map<TargetDependsClosureKey, cmNinjaOuts> TargetDependsClosures;
TargetAliasMap TargetAliases;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index d4ce69e..5b3ac60 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1739,7 +1739,7 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
std::string str_so_file =
cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>');
std::string str_link_file =
- cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>');
+ cmStrCat("$<TARGET_LINKER_LIBRARY_FILE:", gtgt->GetName(), '>');
cmCustomCommandLines cmd = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library",
str_file, str_so_file, str_link_file });
@@ -1754,6 +1754,27 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
postbuild.push_back(std::move(command));
}
+ if (gtgt->HasImportLibrary("") && !gtgt->IsFrameworkOnApple()) {
+ // create symbolic links for .tbd file
+ std::string file = cmStrCat("$<TARGET_IMPORT_FILE:", gtgt->GetName(), '>');
+ std::string soFile =
+ cmStrCat("$<TARGET_SONAME_IMPORT_FILE:", gtgt->GetName(), '>');
+ std::string linkFile =
+ cmStrCat("$<TARGET_LINKER_IMPORT_FILE:", gtgt->GetName(), '>');
+ cmCustomCommandLines symlink_command = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library", file,
+ soFile, linkFile });
+
+ cmCustomCommand command;
+ command.SetCommandLines(symlink_command);
+ command.SetComment("Creating import symlinks");
+ command.SetWorkingDirectory("");
+ command.SetBacktrace(this->CurrentMakefile->GetBacktrace());
+ command.SetStdPipesUTF8(true);
+
+ postbuild.push_back(std::move(command));
+ }
+
cmXCodeObject* legacyCustomCommandsBuildPhase = nullptr;
cmXCodeObject* preBuildPhase = nullptr;
cmXCodeObject* preLinkPhase = nullptr;
@@ -2682,6 +2703,12 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("LIBRARY_STYLE",
this->CreateString("DYNAMIC"));
+
+ if (gtgt->HasImportLibrary(configName)) {
+ // Request .tbd file generation
+ buildSettings->AddAttribute("GENERATE_TEXT_BASED_STUBS",
+ this->CreateString("YES"));
+ }
break;
}
case cmStateEnums::EXECUTABLE: {
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 3564cf7..56883fb 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -22,6 +22,7 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
if (DeprecatedModules.empty()) {
DeprecatedModules["Dart"] = cmPolicies::CMP0145;
DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
+ DeprecatedModules["FindCUDA"] = cmPolicies::CMP0146;
DeprecatedModules["FindDart"] = cmPolicies::CMP0145;
DeprecatedModules["WriteCompilerDetectionHeader"] = cmPolicies::CMP0120;
}
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 56c8b26..40230d9 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -553,34 +553,35 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
// Enforce argument rules too complex to specify for the
// general-purpose parser.
- if (archiveArgs.GetNamelinkOnly() || runtimeArgs.GetNamelinkOnly() ||
- objectArgs.GetNamelinkOnly() || frameworkArgs.GetNamelinkOnly() ||
- bundleArgs.GetNamelinkOnly() || privateHeaderArgs.GetNamelinkOnly() ||
+ if (runtimeArgs.GetNamelinkOnly() || objectArgs.GetNamelinkOnly() ||
+ frameworkArgs.GetNamelinkOnly() || bundleArgs.GetNamelinkOnly() ||
+ privateHeaderArgs.GetNamelinkOnly() ||
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly() ||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
[](const cmInstallCommandFileSetArguments& fileSetArg)
-> bool { return fileSetArg.GetNamelinkOnly(); }) ||
cxxModuleBmiArgs.GetNamelinkOnly()) {
status.SetError(
- "TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
- "The NAMELINK_ONLY option may be specified only following LIBRARY.");
+ "TARGETS given NAMELINK_ONLY option not in LIBRARY or ARCHIVE group. "
+ "The NAMELINK_ONLY option may be specified only following LIBRARY or "
+ "ARCHIVE.");
return false;
}
- if (archiveArgs.GetNamelinkSkip() || runtimeArgs.GetNamelinkSkip() ||
- objectArgs.GetNamelinkSkip() || frameworkArgs.GetNamelinkSkip() ||
- bundleArgs.GetNamelinkSkip() || privateHeaderArgs.GetNamelinkSkip() ||
+ if (runtimeArgs.GetNamelinkSkip() || objectArgs.GetNamelinkSkip() ||
+ frameworkArgs.GetNamelinkSkip() || bundleArgs.GetNamelinkSkip() ||
+ privateHeaderArgs.GetNamelinkSkip() ||
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip() ||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
[](const cmInstallCommandFileSetArguments& fileSetArg)
-> bool { return fileSetArg.GetNamelinkSkip(); }) ||
cxxModuleBmiArgs.GetNamelinkSkip()) {
status.SetError(
- "TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
- "The NAMELINK_SKIP option may be specified only following LIBRARY.");
+ "TARGETS given NAMELINK_SKIP option not in LIBRARY or ARCHIVE group. "
+ "The NAMELINK_SKIP option may be specified only following LIBRARY or "
+ "ARCHIVE.");
return false;
}
- if (archiveArgs.HasNamelinkComponent() ||
- runtimeArgs.HasNamelinkComponent() ||
+ if (runtimeArgs.HasNamelinkComponent() ||
objectArgs.HasNamelinkComponent() ||
frameworkArgs.HasNamelinkComponent() ||
bundleArgs.HasNamelinkComponent() ||
@@ -592,9 +593,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
-> bool { return fileSetArg.HasNamelinkComponent(); }) ||
cxxModuleBmiArgs.HasNamelinkComponent()) {
status.SetError(
- "TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. "
- "The NAMELINK_COMPONENT option may be specified only following "
- "LIBRARY.");
+ "TARGETS given NAMELINK_COMPONENT option not in LIBRARY or ARCHIVE "
+ "group. The NAMELINK_COMPONENT option may be specified only following "
+ "LIBRARY or ARCHIVE.");
return false;
}
if (libraryArgs.GetNamelinkOnly() && libraryArgs.GetNamelinkSkip()) {
@@ -674,6 +675,14 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
} else if (libraryArgs.GetNamelinkSkip()) {
namelinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
}
+ // Select the mode for installing symlinks to versioned imported libraries.
+ cmInstallTargetGenerator::NamelinkModeType importlinkMode =
+ cmInstallTargetGenerator::NamelinkModeNone;
+ if (archiveArgs.GetNamelinkOnly()) {
+ importlinkMode = cmInstallTargetGenerator::NamelinkModeOnly;
+ } else if (archiveArgs.GetNamelinkSkip()) {
+ importlinkMode = cmInstallTargetGenerator::NamelinkModeSkip;
+ }
// Check if there is something to do.
if (targetList.empty()) {
@@ -725,6 +734,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
bool installsArchive = false;
bool installsLibrary = false;
bool installsNamelink = false;
+ bool installsImportlink = false;
bool installsRuntime = false;
bool installsObject = false;
bool installsFramework = false;
@@ -742,6 +752,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
std::unique_ptr<cmInstallTargetGenerator> archiveGenerator;
std::unique_ptr<cmInstallTargetGenerator> libraryGenerator;
std::unique_ptr<cmInstallTargetGenerator> namelinkGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> importlinkGenerator;
std::unique_ptr<cmInstallTargetGenerator> runtimeGenerator;
std::unique_ptr<cmInstallTargetGenerator> objectGenerator;
std::unique_ptr<cmInstallTargetGenerator> frameworkGenerator;
@@ -885,6 +896,32 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
namelinkOnly =
(namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
+
+ if (target.GetMakefile()->PlatformSupportsAppleTextStubs() &&
+ target.IsSharedLibraryWithExports()) {
+ // Apple .tbd files use the ARCHIVE properties
+ if (!archiveArgs.GetDestination().empty()) {
+ artifactsSpecified = true;
+ }
+ if (importlinkMode !=
+ cmInstallTargetGenerator::NamelinkModeOnly) {
+ archiveGenerator = CreateInstallTargetGenerator(
+ target, archiveArgs, true, helper.Makefile->GetBacktrace(),
+ helper.GetLibraryDestination(&archiveArgs));
+ archiveGenerator->SetImportlinkMode(
+ cmInstallTargetGenerator::NamelinkModeSkip);
+ }
+ if (importlinkMode !=
+ cmInstallTargetGenerator::NamelinkModeSkip) {
+ importlinkGenerator = CreateInstallTargetGenerator(
+ target, archiveArgs, true, helper.Makefile->GetBacktrace(),
+ helper.GetLibraryDestination(&archiveArgs), false, true);
+ importlinkGenerator->SetImportlinkMode(
+ cmInstallTargetGenerator::NamelinkModeOnly);
+ }
+ namelinkOnly =
+ (importlinkMode == cmInstallTargetGenerator::NamelinkModeOnly);
+ }
}
if (runtimeDependencySet && libraryGenerator) {
runtimeDependencySet->AddLibrary(libraryGenerator.get());
@@ -1157,6 +1194,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
installsArchive = installsArchive || archiveGenerator;
installsLibrary = installsLibrary || libraryGenerator;
installsNamelink = installsNamelink || namelinkGenerator;
+ installsImportlink = installsImportlink || importlinkGenerator;
installsRuntime = installsRuntime || runtimeGenerator;
installsObject = installsObject || objectGenerator;
installsFramework = installsFramework || frameworkGenerator;
@@ -1169,6 +1207,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
helper.Makefile->AddInstallGenerator(std::move(archiveGenerator));
helper.Makefile->AddInstallGenerator(std::move(libraryGenerator));
helper.Makefile->AddInstallGenerator(std::move(namelinkGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(importlinkGenerator));
helper.Makefile->AddInstallGenerator(std::move(runtimeGenerator));
helper.Makefile->AddInstallGenerator(std::move(objectGenerator));
helper.Makefile->AddInstallGenerator(std::move(frameworkGenerator));
@@ -1203,6 +1242,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
libraryArgs.GetNamelinkComponent());
}
+ if (installsImportlink) {
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
+ archiveArgs.GetNamelinkComponent());
+ }
if (installsRuntime) {
helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
runtimeArgs.GetComponent());
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index 16c5002..6c31da6 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -4,12 +4,15 @@
#include <algorithm>
#include <cassert>
+#include <functional>
#include <map>
#include <set>
#include <sstream>
#include <utility>
#include <vector>
+#include <cm/optional>
+
#include "cmComputeLinkInformation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -40,6 +43,84 @@ std::string computeInstallObjectDir(cmGeneratorTarget* gt,
objectDir += gt->GetName();
return objectDir;
}
+
+void computeFilesToInstall(
+ cmInstallTargetGenerator::Files& files,
+ cmInstallTargetGenerator::NamelinkModeType namelinkMode,
+ std::string const& fromDirConfig, std::string const& output,
+ std::string const& library, std::string const& real,
+ cm::optional<std::function<void(std::string const&)>> GNUToMS = cm::nullopt)
+{
+ bool haveNamelink = false;
+ auto convert = [&GNUToMS](std::string const& file) {
+ if (GNUToMS) {
+ (*GNUToMS)(file);
+ }
+ };
+
+ // Library link name.
+ std::string fromName = cmStrCat(fromDirConfig, output);
+ std::string toName = output;
+
+ // Library interface name.
+ std::string fromSOName;
+ std::string toSOName;
+ if (library != output) {
+ haveNamelink = true;
+ fromSOName = cmStrCat(fromDirConfig, library);
+ toSOName = library;
+ }
+
+ // Library implementation name.
+ std::string fromRealName;
+ std::string toRealName;
+ if (real != output && real != library) {
+ haveNamelink = true;
+ fromRealName = cmStrCat(fromDirConfig, real);
+ toRealName = real;
+ }
+
+ // Add the names based on the current namelink mode.
+ if (haveNamelink) {
+ files.NamelinkMode = namelinkMode;
+ // With a namelink we need to check the mode.
+ if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
+ // Install the namelink only.
+ files.From.emplace_back(fromName);
+ files.To.emplace_back(toName);
+ convert(output);
+ } else {
+ // Install the real file if it has its own name.
+ if (!fromRealName.empty()) {
+ files.From.emplace_back(fromRealName);
+ files.To.emplace_back(toRealName);
+ convert(real);
+ }
+
+ // Install the soname link if it has its own name.
+ if (!fromSOName.empty()) {
+ files.From.emplace_back(fromSOName);
+ files.To.emplace_back(toSOName);
+ convert(library);
+ }
+
+ // Install the namelink if it is not to be skipped.
+ if (namelinkMode != cmInstallTargetGenerator::NamelinkModeSkip) {
+ files.From.emplace_back(fromName);
+ files.To.emplace_back(toName);
+ convert(output);
+ }
+ }
+ } else {
+ // Without a namelink there will be only one file. Install it
+ // if this is not a namelink-only rule.
+ if (namelinkMode != cmInstallTargetGenerator::NamelinkModeOnly) {
+ files.From.emplace_back(fromName);
+ files.To.emplace_back(toName);
+ convert(output);
+ }
+ }
+}
}
cmInstallTargetGenerator::cmInstallTargetGenerator(
@@ -56,6 +137,7 @@ cmInstallTargetGenerator::cmInstallTargetGenerator(
{
this->ActionsPerConfig = true;
this->NamelinkMode = NamelinkModeNone;
+ this->ImportlinkMode = NamelinkModeNone;
}
cmInstallTargetGenerator::~cmInstallTargetGenerator() = default;
@@ -247,18 +329,21 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles(
this->Target->GetLibraryNames(config);
if (this->ImportLibrary) {
// There is a bug in cmInstallCommand if this fails.
- assert(this->NamelinkMode == NamelinkModeNone);
+ assert(this->Target->Makefile->PlatformSupportsAppleTextStubs() ||
+ this->ImportlinkMode == NamelinkModeNone);
+
+ auto GNUToMS = [this, &config, &files,
+ &fromDirConfig](const std::string& lib) {
+ std::string importLib;
+ if (this->Target->GetImplibGNUtoMS(config, lib, importLib)) {
+ files.From.emplace_back(fromDirConfig + importLib);
+ files.To.emplace_back(importLib);
+ }
+ };
- std::string from1 = fromDirConfig + targetNames.ImportLibrary;
- std::string to1 = targetNames.ImportLibrary;
- files.From.emplace_back(std::move(from1));
- files.To.emplace_back(std::move(to1));
- std::string targetNameImportLib;
- if (this->Target->GetImplibGNUtoMS(config, targetNames.ImportLibrary,
- targetNameImportLib)) {
- files.From.emplace_back(fromDirConfig + targetNameImportLib);
- files.To.emplace_back(targetNameImportLib);
- }
+ computeFilesToInstall(
+ files, this->ImportlinkMode, fromDirConfig, targetNames.ImportOutput,
+ targetNames.ImportLibrary, targetNames.ImportReal, GNUToMS);
// An import library looks like a static library.
files.Type = cmInstallType_STATIC_LIBRARY;
@@ -318,66 +403,9 @@ cmInstallTargetGenerator::Files cmInstallTargetGenerator::GetFiles(
files.From.emplace_back(std::move(from1));
files.To.emplace_back(std::move(to1));
} else {
- bool haveNamelink = false;
-
- // Library link name.
- std::string fromName = fromDirConfig + targetNames.Output;
- std::string toName = targetNames.Output;
-
- // Library interface name.
- std::string fromSOName;
- std::string toSOName;
- if (targetNames.SharedObject != targetNames.Output) {
- haveNamelink = true;
- fromSOName = fromDirConfig + targetNames.SharedObject;
- toSOName = targetNames.SharedObject;
- }
-
- // Library implementation name.
- std::string fromRealName;
- std::string toRealName;
- if (targetNames.Real != targetNames.Output &&
- targetNames.Real != targetNames.SharedObject) {
- haveNamelink = true;
- fromRealName = fromDirConfig + targetNames.Real;
- toRealName = targetNames.Real;
- }
-
- // Add the names based on the current namelink mode.
- if (haveNamelink) {
- files.NamelinkMode = this->NamelinkMode;
- // With a namelink we need to check the mode.
- if (this->NamelinkMode == NamelinkModeOnly) {
- // Install the namelink only.
- files.From.emplace_back(fromName);
- files.To.emplace_back(toName);
- } else {
- // Install the real file if it has its own name.
- if (!fromRealName.empty()) {
- files.From.emplace_back(fromRealName);
- files.To.emplace_back(toRealName);
- }
-
- // Install the soname link if it has its own name.
- if (!fromSOName.empty()) {
- files.From.emplace_back(fromSOName);
- files.To.emplace_back(toSOName);
- }
-
- // Install the namelink if it is not to be skipped.
- if (this->NamelinkMode != NamelinkModeSkip) {
- files.From.emplace_back(fromName);
- files.To.emplace_back(toName);
- }
- }
- } else {
- // Without a namelink there will be only one file. Install it
- // if this is not a namelink-only rule.
- if (this->NamelinkMode != NamelinkModeOnly) {
- files.From.emplace_back(fromName);
- files.To.emplace_back(toName);
- }
- }
+ computeFilesToInstall(files, this->NamelinkMode, fromDirConfig,
+ targetNames.Output, targetNames.SharedObject,
+ targetNames.Real);
}
}
@@ -425,6 +453,12 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
fname = targetNames.ImportLibrary;
}
+ } else if (nameType == NameImplibReal) {
+ // Use the import library name.
+ if (!target->GetImplibGNUtoMS(config, targetNames.ImportReal, fname,
+ "${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
+ fname = targetNames.ImportReal;
+ }
} else if (nameType == NameReal) {
// Use the canonical name.
fname = targetNames.Real;
@@ -434,11 +468,14 @@ std::string cmInstallTargetGenerator::GetInstallFilename(
}
} else {
cmGeneratorTarget::Names targetNames = target->GetLibraryNames(config);
- if (nameType == NameImplib) {
+ if (nameType == NameImplib || nameType == NameImplibReal) {
+ const auto& importName = nameType == NameImplib
+ ? targetNames.ImportLibrary
+ : targetNames.ImportReal;
// Use the import library name.
- if (!target->GetImplibGNUtoMS(config, targetNames.ImportLibrary, fname,
+ if (!target->GetImplibGNUtoMS(config, importName, fname,
"${CMAKE_IMPORT_LIBRARY_SUFFIX}")) {
- fname = targetNames.ImportLibrary;
+ fname = importName;
}
} else if (nameType == NameSO) {
// Use the soname.
@@ -784,7 +821,7 @@ void cmInstallTargetGenerator::AddStripRule(std::ostream& os, Indent indent,
}
// Don't handle OSX Bundles.
- if (this->Target->Target->GetMakefile()->IsOn("APPLE") &&
+ if (this->Target->IsApple() &&
this->Target->GetPropertyAsBool("MACOSX_BUNDLE")) {
return;
}
@@ -796,7 +833,7 @@ void cmInstallTargetGenerator::AddStripRule(std::ostream& os, Indent indent,
std::string stripArgs;
// macOS 'strip' is picky, executables need '-u -r' and dylibs need '-x'.
- if (this->Target->Target->GetMakefile()->IsOn("APPLE")) {
+ if (this->Target->IsApple()) {
if (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
stripArgs = "-x ";
@@ -822,7 +859,7 @@ void cmInstallTargetGenerator::AddRanlibRule(std::ostream& os, Indent indent,
// Perform post-installation processing on the file depending
// on its type.
- if (!this->Target->Target->GetMakefile()->IsOn("APPLE")) {
+ if (!this->Target->IsApple()) {
return;
}
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 3fc4b59..2f41163 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -39,6 +39,10 @@ public:
NamelinkModeSkip
};
void SetNamelinkMode(NamelinkModeType mode) { this->NamelinkMode = mode; }
+ void SetImportlinkMode(NamelinkModeType mode)
+ {
+ this->ImportlinkMode = mode;
+ }
std::string GetInstallFilename(const std::string& config) const;
@@ -50,7 +54,8 @@ public:
NameNormal,
NameImplib,
NameSO,
- NameReal
+ NameReal,
+ NameImplibReal
};
static std::string GetInstallFilename(const cmGeneratorTarget* target,
@@ -121,6 +126,7 @@ protected:
cmGeneratorTarget* Target = nullptr;
std::string const FilePermissions;
NamelinkModeType NamelinkMode;
+ NamelinkModeType ImportlinkMode;
bool const ImportLibrary;
bool const Optional;
};
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index c2138ee..bd7eb3f 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -85,6 +85,7 @@ static auto ruleReplaceVars = { "CMAKE_${LANG}_COMPILER",
"CMAKE_RANLIB",
"CMAKE_LINKER",
"CMAKE_MT",
+ "CMAKE_TAPI",
"CMAKE_CUDA_HOST_COMPILER",
"CMAKE_CUDA_HOST_LINK_LAUNCHER",
"CMAKE_CL_SHOWINCLUDES_PREFIX" };
@@ -134,6 +135,13 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
}
+ // OSX SYSROOT can be required by some tools, like tapi
+ {
+ cmValue osxSysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
+ this->VariableMappings["CMAKE_OSX_SYSROOT"] =
+ osxSysroot.IsEmpty() ? "/" : this->EscapeForShell(*osxSysroot, true);
+ }
+
if (cmValue appleArchSysroots =
this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) {
std::string const& appleArchs =
@@ -1644,7 +1652,7 @@ static std::string GetFrameworkFlags(const std::string& lang,
cmLocalGenerator* lg = target->GetLocalGenerator();
cmMakefile* mf = lg->GetMakefile();
- if (!mf->IsOn("APPLE")) {
+ if (!target->IsApple()) {
return std::string();
}
@@ -1818,7 +1826,7 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
// OLD behavior is to always add the flags, except on AIX where
// we compute symbol exports if ENABLE_EXPORTS is on.
add_shlib_flags =
- !(tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"));
+ !(tgt.IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"));
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
@@ -1830,7 +1838,7 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
// NEW behavior is to only add the flags if ENABLE_EXPORTS is on,
// except on AIX where we compute symbol exports.
add_shlib_flags =
- !tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS");
+ !tgt.IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS");
break;
}
@@ -1864,7 +1872,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
const std::string& filterArch)
{
// Only add Apple specific flags on Apple platforms
- if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) {
+ if (target->IsApple() && this->EmitUniversalBinaryFlags) {
std::vector<std::string> archs;
target->GetAppleArchs(config, archs);
if (!archs.empty() &&
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 2fc2974..3fcc7f7 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1229,7 +1229,7 @@ void cmMakefile::AddCustomCommandOldStyle(
// Each output must get its own copy of this rule.
cmsys::RegularExpression sourceFiles(
- "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|mpp|ixx|cppm|cu|m|mm|"
+ "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|mpp|ixx|cppm|ccm|cxxm|c\\+\\+m|cu|m|mm|"
"rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|"
"hm|hpp|hxx|in|txx|inl)$");
@@ -2493,6 +2493,11 @@ bool cmMakefile::PlatformIsAppleEmbedded() const
return this->GetAppleSDKType() != AppleSDK::MacOS;
}
+bool cmMakefile::PlatformSupportsAppleTextStubs() const
+{
+ return this->IsOn("APPLE") && this->IsSet("CMAKE_TAPI");
+}
+
const char* cmMakefile::GetSONameFlag(const std::string& language) const
{
std::string name = "CMAKE_SHARED_LIBRARY_SONAME";
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 3cf6e61..6f04937 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -562,6 +562,10 @@ public:
/** Return whether the target platform is Apple iOS. */
bool PlatformIsAppleEmbedded() const;
+ /** Return whether the target platform supports generation of text base stubs
+ (.tbd file) describing exports (Apple specific). */
+ bool PlatformSupportsAppleTextStubs() const;
+
/** Retrieve soname flag for the specified language if supported */
const char* GetSONameFlag(const std::string& language) const;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 41daa5a..1960073 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -185,14 +185,15 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
std::string linkLibs;
this->CreateLinkLibs(
linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
- cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
+ linkLanguage, cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
this->CreateObjectLists(
useLinkScript, false, useResponseFileForObjects, buildObjs, depends,
- false, cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
+ false, linkLanguage,
+ cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
cmRulePlaceholderExpander::RuleVariables vars;
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -503,13 +504,13 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Collect up flags to link in needed libraries.
std::string linkLibs;
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
- useResponseFileForLibs, depends);
+ useResponseFileForLibs, depends, linkLanguage);
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
- buildObjs, depends, useWatcomQuote);
+ buildObjs, depends, useWatcomQuote, linkLanguage);
if (!this->DeviceLinkObject.empty()) {
buildObjs += " " +
this->LocalGenerator->ConvertToOutputFormat(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index cb567ff..3e4a08e 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -327,14 +327,14 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
this->CreateLinkLibs(
linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
- cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
+ linkLanguage, cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
this->CreateObjectLists(
useLinkScript, false, // useArchiveRules
- useResponseFileForObjects, buildObjs, depends, false,
+ useResponseFileForObjects, buildObjs, depends, false, linkLanguage,
cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -465,9 +465,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string outpathImp;
if (this->GeneratorTarget->IsFrameworkOnApple()) {
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+ cmOSXBundleGenerator::SkipParts bundleSkipParts;
+ if (this->GeneratorTarget->HasImportLibrary(this->GetConfigName())) {
+ bundleSkipParts.TextStubs = false;
+ }
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
- outpath, this->GetConfigName());
+ outpath, this->GetConfigName(),
+ bundleSkipParts);
outpath += '/';
+ if (!this->TargetNames.ImportLibrary.empty()) {
+ outpathImp = this->GeneratorTarget->GetDirectory(
+ this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
+ cmSystemTools::MakeDirectory(outpathImp);
+ outpathImp += '/';
+ }
} else if (this->GeneratorTarget->IsCFBundleOnApple()) {
outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
@@ -679,11 +690,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Expand the rule variables.
+ std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
+ this->LocalGenerator->CreateRulePlaceholderExpander());
+ bool useWatcomQuote =
+ this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
std::vector<std::string> real_link_commands;
{
- bool useWatcomQuote =
- this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
-
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -700,7 +712,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
linkLineComputer->SetRelink(relink);
this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
- useResponseFileForLibs, depends);
+ useResponseFileForLibs, depends, linkLanguage);
}
// Construct object file lists that may be needed to expand the
@@ -708,7 +720,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string buildObjs;
this->CreateObjectLists(useLinkScript, useArchiveRules,
useResponseFileForObjects, buildObjs, depends,
- useWatcomQuote);
+ useWatcomQuote, linkLanguage);
if (!this->DeviceLinkObject.empty()) {
buildObjs += " " +
this->LocalGenerator->ConvertToOutputFormat(
@@ -816,8 +828,6 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
// Construct the main link rule and expand placeholders.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
if (useArchiveRules) {
@@ -950,6 +960,86 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
commands, false);
+ // Add rule to generate text-based stubs, if required
+ if (this->GeneratorTarget->IsApple() &&
+ this->GeneratorTarget->HasImportLibrary(this->GetConfigName())) {
+ auto genStubsRule =
+ this->Makefile->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
+ auto genStubs_commands = cmExpandedList(genStubsRule);
+
+ std::string TBDFullPath =
+ cmStrCat(outpathImp, this->TargetNames.ImportOutput);
+ std::string TBDFullPathReal =
+ cmStrCat(outpathImp, this->TargetNames.ImportReal);
+ std::string TBDFullPathSO =
+ cmStrCat(outpathImp, this->TargetNames.ImportLibrary);
+
+ // Expand placeholders.
+ cmRulePlaceholderExpander::RuleVariables vars;
+ std::string target = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeRelativeToCurBinDir(targetFullPathReal),
+ cmOutputConverter::SHELL, useWatcomQuote);
+ vars.Target = target.c_str();
+ std::string TBDOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPathReal),
+ cmOutputConverter::SHELL, useWatcomQuote);
+ rulePlaceholderExpander->SetTargetImpLib(TBDOutPathReal);
+ for (std::string& command : genStubs_commands) {
+ rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
+ command, vars);
+ }
+ outputs.clear();
+ outputs.push_back(TBDFullPathReal);
+ if (this->TargetNames.ImportLibrary != this->TargetNames.ImportReal) {
+ outputs.push_back(TBDFullPathSO);
+ }
+ if (this->TargetNames.ImportOutput != this->TargetNames.ImportLibrary &&
+ this->TargetNames.ImportOutput != this->TargetNames.ImportReal) {
+ outputs.push_back(TBDFullPath);
+ }
+ this->ExtraFiles.insert(TBDFullPath);
+
+ depends.clear();
+ depends.push_back(targetFullPathReal);
+
+ // Add a rule to create necessary symlinks for the library.
+ // Frameworks are handled by cmOSXBundleGenerator.
+ if (TBDFullPath != TBDFullPathReal &&
+ !this->GeneratorTarget->IsFrameworkOnApple()) {
+ auto TBDOutPathSO = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPathSO),
+ cmOutputConverter::SHELL, useWatcomQuote);
+ auto TBDOutPath = this->LocalGenerator->ConvertToOutputFormat(
+ this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPath),
+ cmOutputConverter::SHELL, useWatcomQuote);
+
+ std::string symlink =
+ cmStrCat("$(CMAKE_COMMAND) -E cmake_symlink_library ", TBDOutPathReal,
+ ' ', TBDOutPathSO, ' ', TBDOutPath);
+ commands1.push_back(std::move(symlink));
+ this->LocalGenerator->CreateCDCommand(
+ commands1, this->Makefile->GetCurrentBinaryDirectory(),
+ this->LocalGenerator->GetBinaryDirectory());
+ cm::append(genStubs_commands, commands1);
+ commands1.clear();
+ }
+
+ this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs, depends,
+ genStubs_commands, false);
+
+ // clean actions for apple specific outputs
+ // clean actions for ImportLibrary are already specified
+ if (this->TargetNames.ImportReal != this->TargetNames.ImportLibrary) {
+ libCleanFiles.insert(
+ this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPathReal));
+ }
+ if (this->TargetNames.ImportOutput != this->TargetNames.ImportReal &&
+ this->TargetNames.ImportOutput != this->TargetNames.ImportLibrary) {
+ libCleanFiles.insert(
+ this->LocalGenerator->MaybeRelativeToCurBinDir(TBDFullPath));
+ }
+ }
+
// Write the main driver rule to build everything in this target.
this->WriteTargetDriverRule(targetFullPath, relink);
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 915a412..2ead739 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -2189,16 +2189,16 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries(
std::string cmMakefileTargetGenerator::CreateResponseFile(
const std::string& name, std::string const& options,
- std::vector<std::string>& makefile_depends)
+ std::vector<std::string>& makefile_depends, std::string const& language)
{
// FIXME: Find a better way to determine the response file encoding,
// perhaps using tool-specific platform information variables.
// For now, use the makefile encoding as a heuristic.
codecvt::Encoding responseEncoding =
this->GlobalGenerator->GetMakefileEncoding();
- // Non-MSVC tooling may not understand a BOM.
+ // Non-MSVC tooling doesn't understand BOM encoded files.
if (responseEncoding == codecvt::UTF8_WITH_BOM &&
- !this->Makefile->IsOn("MSVC")) {
+ (language == "CUDA" || !this->Makefile->IsOn("MSVC"))) {
responseEncoding = codecvt::UTF8;
}
@@ -2235,7 +2235,7 @@ cmMakefileTargetGenerator::CreateLinkLineComputer(
void cmMakefileTargetGenerator::CreateLinkLibs(
cmLinkLineComputer* linkLineComputer, std::string& linkLibs,
bool useResponseFile, std::vector<std::string>& makefile_depends,
- ResponseFlagFor responseMode)
+ std::string const& linkLanguage, ResponseFlagFor responseMode)
{
std::string frameworkPath;
std::string linkPath;
@@ -2253,8 +2253,9 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
// Create this response file.
std::string responseFileName =
(responseMode == Link) ? "linkLibs.rsp" : "deviceLinkLibs.rsp";
- std::string link_rsp =
- this->CreateResponseFile(responseFileName, linkLibs, makefile_depends);
+ std::string responseLang = (responseMode == Link) ? linkLanguage : "CUDA";
+ std::string link_rsp = this->CreateResponseFile(
+ responseFileName, linkLibs, makefile_depends, responseLang);
// Reference the response file.
linkLibs = cmStrCat(responseFlag,
@@ -2266,7 +2267,8 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
void cmMakefileTargetGenerator::CreateObjectLists(
bool useLinkScript, bool useArchiveRules, bool useResponseFile,
std::string& buildObjs, std::vector<std::string>& makefile_depends,
- bool useWatcomQuote, ResponseFlagFor responseMode)
+ bool useWatcomQuote, std::string const& linkLanguage,
+ ResponseFlagFor responseMode)
{
std::string variableName;
std::string variableNameExternal;
@@ -2295,7 +2297,7 @@ void cmMakefileTargetGenerator::CreateObjectLists(
// Create this response file.
std::string objects_rsp = this->CreateResponseFile(
- responseFileName, object_strings[i], makefile_depends);
+ responseFileName, object_strings[i], makefile_depends, linkLanguage);
// Separate from previous response file references.
buildObjs += sep;
@@ -2347,8 +2349,8 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
}
std::string name = cmStrCat("includes_", lang, ".rsp");
std::string arg = std::move(responseFlag) +
- this->CreateResponseFile(name, includeFlags,
- this->FlagFileDepends[lang]);
+ this->CreateResponseFile(name, includeFlags, this->FlagFileDepends[lang],
+ lang);
this->LocalGenerator->AppendFlags(flags, arg);
} else {
this->LocalGenerator->AppendFlags(flags, includeFlags);
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 5d614fe..98c3a0e 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -160,7 +160,8 @@ protected:
response file name. */
std::string CreateResponseFile(const std::string& name,
std::string const& options,
- std::vector<std::string>& makefile_depends);
+ std::vector<std::string>& makefile_depends,
+ std::string const& language);
bool CheckUseResponseFileForObjects(std::string const& l) const;
bool CheckUseResponseFileForLibraries(std::string const& l) const;
@@ -175,13 +176,14 @@ protected:
void CreateLinkLibs(cmLinkLineComputer* linkLineComputer,
std::string& linkLibs, bool useResponseFile,
std::vector<std::string>& makefile_depends,
+ std::string const& linkLanguage,
ResponseFlagFor responseMode = ResponseFlagFor::Link);
/** Create lists of object files for linking and cleaning. */
void CreateObjectLists(bool useLinkScript, bool useArchiveRules,
bool useResponseFile, std::string& buildObjs,
std::vector<std::string>& makefile_depends,
- bool useWatcomQuote,
+ bool useWatcomQuote, std::string const& linkLanguage,
ResponseFlagFor responseMode = ResponseFlagFor::Link);
/** Add commands for generate def files */
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 45a4dda..4d68460 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -204,6 +204,15 @@ std::string cmNinjaNormalTargetGenerator::LanguageLinkerCudaFatbinaryRule(
'_', config);
}
+std::string cmNinjaNormalTargetGenerator::TextStubsGeneratorRule(
+ const std::string& config) const
+{
+ return cmStrCat(
+ "TEXT_STUBS_GENERATOR__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
+}
+
struct cmNinjaRemoveNoOpCommands
{
bool operator()(std::string const& cmd)
@@ -527,6 +536,45 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
this->GetGlobalGenerator()->AddRule(rule);
}
}
+
+ if (this->GetGeneratorTarget()->IsApple() &&
+ this->GetGeneratorTarget()->HasImportLibrary(config)) {
+ cmNinjaRule rule(this->TextStubsGeneratorRule(config));
+ rule.Comment = cmStrCat("Rule for generating text-based stubs for ",
+ this->GetVisibleTypeName(), '.');
+ rule.Description = "Creating text-based stubs $out";
+
+ std::string cmd =
+ this->GetMakefile()->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
+ std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ cmRulePlaceholderExpander::RuleVariables vars;
+ vars.Target = "$in";
+ rulePlaceholderExpander->SetTargetImpLib("$out");
+ rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
+ cmd, vars);
+
+ rule.Command =
+ this->GetLocalGenerator()->BuildCommandLine({ cmd }, config, config);
+ this->GetGlobalGenerator()->AddRule(rule);
+
+ if (tgtNames.ImportOutput != tgtNames.ImportReal &&
+ !this->GetGeneratorTarget()->IsFrameworkOnApple()) {
+ cmNinjaRule slRule("CMAKE_SYMLINK_IMPORT_LIBRARY");
+ {
+ std::string cmakeCommand =
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
+ std::string slCmd =
+ cmStrCat(cmakeCommand, " -E cmake_symlink_library $in $SONAME $out");
+ slRule.Command = this->GetLocalGenerator()->BuildCommandLine(
+ { slCmd }, config, config);
+ }
+ slRule.Description = "Creating import library symlink $out";
+ slRule.Comment = "Rule for creating import library symlink.";
+ this->GetGlobalGenerator()->AddRule(slRule);
+ }
+ }
}
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
@@ -1030,9 +1078,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
// the current configuration has a postfix. The non-postfix configuration
// Info.plist can be used by all the other configurations.
if (!postFix.empty()) {
- bundleSkipParts.infoPlist = true;
+ bundleSkipParts.InfoPlist = true;
}
}
+ if (gt->HasImportLibrary(config)) {
+ bundleSkipParts.TextStubs = false;
+ }
this->OSXBundleGenerator->CreateFramework(
tgtNames.Output, gt->GetDirectory(config), config, bundleSkipParts);
@@ -1214,7 +1265,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmGlobalNinjaGenerator::CCOutputs byproducts(this->GetGlobalGenerator());
- if (!tgtNames.ImportLibrary.empty()) {
+ if (!gt->IsApple() && !tgtNames.ImportLibrary.empty()) {
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
@@ -1471,6 +1522,55 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
// Add aliases for the file name and the target name.
globalGen->AddTargetAlias(tgtNames.Output, gt, config);
globalGen->AddTargetAlias(this->GetTargetName(), gt, config);
+
+ if (this->GetGeneratorTarget()->IsApple() &&
+ this->GetGeneratorTarget()->HasImportLibrary(config)) {
+ auto dirTBD =
+ gt->GetDirectory(config, cmStateEnums::ImportLibraryArtifact);
+ auto targetTBD =
+ this->ConvertToNinjaPath(cmStrCat(dirTBD, '/', tgtNames.ImportReal));
+ this->EnsureParentDirectoryExists(targetTBD);
+ cmNinjaBuild build(this->TextStubsGeneratorRule(config));
+ build.Comment = cmStrCat("Generate the text-based stubs file ", targetTBD);
+ build.Outputs.push_back(targetTBD);
+ build.ExplicitDeps.push_back(targetOutputReal);
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
+
+ if (tgtNames.ImportOutput != tgtNames.ImportReal &&
+ !this->GetGeneratorTarget()->IsFrameworkOnApple()) {
+ auto outputTBD =
+ this->ConvertToNinjaPath(cmStrCat(dirTBD, '/', tgtNames.ImportOutput));
+ std::string const soNameTBD = this->ConvertToNinjaPath(
+ cmStrCat(dirTBD, '/', tgtNames.ImportLibrary));
+
+ cmNinjaBuild slBuild("CMAKE_SYMLINK_IMPORT_LIBRARY");
+ slBuild.Comment = cmStrCat("Create import library symlink ", outputTBD);
+ cmNinjaVars slVars;
+
+ // If one link has to be created.
+ if (targetTBD == soNameTBD || outputTBD == soNameTBD) {
+ slVars["SONAME"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ soNameTBD, cmOutputConverter::SHELL);
+ } else {
+ slVars["SONAME"].clear();
+ slBuild.Outputs.push_back(soNameTBD);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(soNameTBD);
+ }
+ }
+ slBuild.Outputs.push_back(outputTBD);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(outputTBD);
+ }
+ slBuild.ExplicitDeps.push_back(targetTBD);
+ slBuild.Variables = std::move(slVars);
+
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), slBuild);
+ }
+
+ // Add alias for the import file name
+ globalGen->AddTargetAlias(tgtNames.ImportOutput, gt, config);
+ }
}
void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 30127fe..85f42a4 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -25,6 +25,7 @@ private:
std::string LanguageLinkerCudaDeviceCompileRule(
const std::string& config) const;
std::string LanguageLinkerCudaFatbinaryRule(const std::string& config) const;
+ std::string TextStubsGeneratorRule(const std::string& config) const;
const char* GetVisibleTypeName() const;
void WriteLanguagesRules(const std::string& config);
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index 674735b..4301f05 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -11,6 +11,7 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmValue.h"
class cmSourceFile;
@@ -77,7 +78,7 @@ void cmOSXBundleGenerator::CreateFramework(
std::string frameworkVersion = this->GT->GetFrameworkVersion();
std::string name = cmSystemTools::GetFilenameName(targetName);
- if (!skipParts.infoPlist) {
+ if (!skipParts.InfoPlist) {
// Configure the Info.plist file
std::string plist = newoutpath;
if (!this->Makefile->PlatformIsAppleEmbedded()) {
@@ -120,6 +121,17 @@ void cmOSXBundleGenerator::CreateFramework(
cmSystemTools::CreateSymlink(oldName, newName);
this->Makefile->AddCMakeOutputFile(newName);
+ if (!skipParts.TextStubs) {
+ // foo.tbd -> Versions/Current/foo.tbd
+ cmValue tbdSuffix =
+ this->Makefile->GetDefinition("CMAKE_APPLE_IMPORT_FILE_SUFFIX");
+ oldName = cmStrCat("Versions/Current/", name, tbdSuffix);
+ newName = cmStrCat(contentdir, name, tbdSuffix);
+ cmSystemTools::RemoveFile(newName);
+ cmSystemTools::CreateSymlink(oldName, newName);
+ this->Makefile->AddCMakeOutputFile(newName);
+ }
+
// Resources -> Versions/Current/Resources
if (this->MacContentFolders->find("Resources") !=
this->MacContentFolders->end()) {
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index c33b087..38453fd 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -20,11 +20,10 @@ public:
struct SkipParts
{
- SkipParts()
- : infoPlist(false)
- {
- }
- bool infoPlist; // NOLINT(modernize-use-default-member-init)
+ SkipParts() {} // NOLINT(modernize-use-equals-default)
+
+ bool InfoPlist = false;
+ bool TextStubs = true;
};
// create an app bundle at a given root, and return
@@ -35,7 +34,7 @@ public:
// create a framework at a given root
void CreateFramework(const std::string& targetName, const std::string& root,
const std::string& config,
- const SkipParts& skipParts = SkipParts());
+ const SkipParts& skipParts = SkipParts{});
// create a cf bundle at a given root
void CreateCFBundle(const std::string& targetName, const std::string& root,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 830e14b..52993b8 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -439,6 +439,11 @@ class cmMakefile;
"find_package uses upper-case <PACKAGENAME>_ROOT variables.", 3, 27, \
0, cmPolicies::WARN) \
SELECT(POLICY, CMP0145, "The Dart and FindDart modules are removed.", 3, \
+ 27, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0146, "The FindCUDA module is removed.", 3, 27, 0, \
+ cmPolicies::WARN) \
+ SELECT(POLICY, CMP0147, \
+ "Visual Studio generators build custom commands in parallel.", 3, \
27, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
@@ -479,7 +484,9 @@ class cmMakefile;
F(CMP0131) \
F(CMP0142)
-#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) F(CMP0116)
+#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
+ F(CMP0116) \
+ F(CMP0147)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index fa9d4cc..5ff7009 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -20,8 +20,8 @@ cmRST::cmRST(std::ostream& os, std::string docroot)
: OS(os)
, DocRoot(std::move(docroot))
, CMakeDirective("^.. (cmake:)?("
- "command|envvar|genex|variable"
- ")::[ \t]+([^ \t\n]+)$")
+ "command|envvar|genex|signature|variable"
+ ")::")
, CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$")
, ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$")
, CodeBlockDirective("^.. code-block::[ \t]*(.*)$")
@@ -126,27 +126,27 @@ void cmRST::Reset()
if (!this->MarkupLines.empty()) {
cmRST::UnindentLines(this->MarkupLines);
}
- switch (this->Directive) {
- case DirectiveNone:
+ switch (this->DirectiveType) {
+ case Directive::None:
break;
- case DirectiveParsedLiteral:
+ case Directive::ParsedLiteral:
this->ProcessDirectiveParsedLiteral();
break;
- case DirectiveLiteralBlock:
+ case Directive::LiteralBlock:
this->ProcessDirectiveLiteralBlock();
break;
- case DirectiveCodeBlock:
+ case Directive::CodeBlock:
this->ProcessDirectiveCodeBlock();
break;
- case DirectiveReplace:
+ case Directive::Replace:
this->ProcessDirectiveReplace();
break;
- case DirectiveTocTree:
+ case Directive::TocTree:
this->ProcessDirectiveTocTree();
break;
}
- this->Markup = MarkupNone;
- this->Directive = DirectiveNone;
+ this->MarkupType = Markup::None;
+ this->DirectiveType = Directive::None;
this->MarkupLines.clear();
}
@@ -160,9 +160,9 @@ void cmRST::ProcessLine(std::string const& line)
(line.size() >= 3 && line[0] == '.' && line[1] == '.' &&
isspace(line[2]))) {
this->Reset();
- this->Markup =
- (line.find_first_not_of(" \t", 2) == std::string::npos ? MarkupEmpty
- : MarkupNormal);
+ this->MarkupType =
+ (line.find_first_not_of(" \t", 2) == std::string::npos ? Markup::Empty
+ : Markup::Normal);
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
if (this->CMakeDirective.find(line)) {
@@ -171,33 +171,33 @@ void cmRST::ProcessLine(std::string const& line)
} else if (this->CMakeModuleDirective.find(line)) {
// Process cmake-module directive: scan .cmake file comments.
std::string file = this->CMakeModuleDirective.match(1);
- if (file.empty() || !this->ProcessInclude(file, IncludeModule)) {
+ if (file.empty() || !this->ProcessInclude(file, Include::Module)) {
this->NormalLine(line);
}
} else if (this->ParsedLiteralDirective.find(line)) {
// Record the literal lines to output after whole block.
- this->Directive = DirectiveParsedLiteral;
+ this->DirectiveType = Directive::ParsedLiteral;
this->MarkupLines.push_back(this->ParsedLiteralDirective.match(1));
} else if (this->CodeBlockDirective.find(line)) {
// Record the literal lines to output after whole block.
// Ignore the language spec and record the opening line as blank.
- this->Directive = DirectiveCodeBlock;
+ this->DirectiveType = Directive::CodeBlock;
this->MarkupLines.emplace_back();
} else if (this->ReplaceDirective.find(line)) {
// Record the replace directive content.
- this->Directive = DirectiveReplace;
+ this->DirectiveType = Directive::Replace;
this->ReplaceName = this->ReplaceDirective.match(1);
this->MarkupLines.push_back(this->ReplaceDirective.match(2));
} else if (this->IncludeDirective.find(line)) {
// Process the include directive or output the directive and its
// content normally if it fails.
std::string file = this->IncludeDirective.match(1);
- if (file.empty() || !this->ProcessInclude(file, IncludeNormal)) {
+ if (file.empty() || !this->ProcessInclude(file, Include::Normal)) {
this->NormalLine(line);
}
} else if (this->TocTreeDirective.find(line)) {
// Record the toctree entries to process after whole block.
- this->Directive = DirectiveTocTree;
+ this->DirectiveType = Directive::TocTree;
this->MarkupLines.push_back(this->TocTreeDirective.match(1));
} else if (this->ProductionListDirective.find(line)) {
// Output productionlist directives and their content normally.
@@ -211,14 +211,15 @@ void cmRST::ProcessLine(std::string const& line)
this->NormalLine(line);
}
}
- // An explicit markup start followed nothing but whitespace and a
+ // An explicit markup start followed by nothing but whitespace and a
// blank line does not consume any indented text following.
- else if (this->Markup == MarkupEmpty && line.empty()) {
+ else if (this->MarkupType == Markup::Empty && line.empty()) {
this->NormalLine(line);
}
// Indented lines following an explicit markup start are explicit markup.
- else if (this->Markup && (line.empty() || isspace(line[0]))) {
- this->Markup = MarkupNormal;
+ else if (this->MarkupType != Markup::None &&
+ (line.empty() || isspace(line[0]))) {
+ this->MarkupType = Markup::Normal;
// Record markup lines if the start line was recorded.
if (!this->MarkupLines.empty()) {
this->MarkupLines.push_back(line);
@@ -227,8 +228,8 @@ void cmRST::ProcessLine(std::string const& line)
// A blank line following a paragraph ending in "::" starts a literal block.
else if (lastLineEndedInColonColon && line.empty()) {
// Record the literal lines to output after whole block.
- this->Markup = MarkupNormal;
- this->Directive = DirectiveLiteralBlock;
+ this->MarkupType = Markup::Normal;
+ this->DirectiveType = Directive::LiteralBlock;
this->MarkupLines.emplace_back();
this->OutputLine("", false);
}
@@ -354,14 +355,14 @@ void cmRST::OutputMarkupLines(bool inlineMarkup)
this->OutputLinePending = true;
}
-bool cmRST::ProcessInclude(std::string file, IncludeType type)
+bool cmRST::ProcessInclude(std::string file, Include type)
{
bool found = false;
if (this->IncludeDepth < 10) {
cmRST r(this->OS, this->DocRoot);
r.IncludeDepth = this->IncludeDepth + 1;
r.OutputLinePending = this->OutputLinePending;
- if (type != IncludeTocTree) {
+ if (type != Include::TocTree) {
r.Replace = this->Replace;
}
if (file[0] == '/') {
@@ -369,8 +370,8 @@ bool cmRST::ProcessInclude(std::string file, IncludeType type)
} else {
file = this->DocDir + "/" + file;
}
- found = r.ProcessFile(file, type == IncludeModule);
- if (type != IncludeTocTree) {
+ found = r.ProcessFile(file, type == Include::Module);
+ if (type != Include::TocTree) {
this->Replace = r.Replace;
}
this->OutputLinePending = r.OutputLinePending;
@@ -408,9 +409,9 @@ void cmRST::ProcessDirectiveTocTree()
if (!line.empty() && line[0] != ':') {
if (this->TocTreeLink.find(line)) {
std::string const& link = this->TocTreeLink.match(1);
- this->ProcessInclude(link + ".rst", IncludeTocTree);
+ this->ProcessInclude(link + ".rst", Include::TocTree);
} else {
- this->ProcessInclude(line + ".rst", IncludeTocTree);
+ this->ProcessInclude(line + ".rst", Include::TocTree);
}
}
}
diff --git a/Source/cmRST.h b/Source/cmRST.h
index ea4ef22..65a8a71 100644
--- a/Source/cmRST.h
+++ b/Source/cmRST.h
@@ -29,26 +29,26 @@ public:
bool ProcessFile(std::string const& fname, bool isModule = false);
private:
- enum IncludeType
+ enum class Include
{
- IncludeNormal,
- IncludeModule,
- IncludeTocTree
+ Normal,
+ Module,
+ TocTree
};
- enum MarkupType
+ enum class Markup
{
- MarkupNone,
- MarkupNormal,
- MarkupEmpty
+ None,
+ Normal,
+ Empty
};
- enum DirectiveType
+ enum class Directive
{
- DirectiveNone,
- DirectiveParsedLiteral,
- DirectiveLiteralBlock,
- DirectiveCodeBlock,
- DirectiveReplace,
- DirectiveTocTree
+ None,
+ ParsedLiteral,
+ LiteralBlock,
+ CodeBlock,
+ Replace,
+ TocTree
};
void ProcessRST(std::istream& is);
@@ -59,7 +59,7 @@ private:
void OutputLine(std::string const& line, bool inlineMarkup);
std::string ReplaceSubstitutions(std::string const& line);
void OutputMarkupLines(bool inlineMarkup);
- bool ProcessInclude(std::string file, IncludeType type);
+ bool ProcessInclude(std::string file, Include type);
void ProcessDirectiveParsedLiteral();
void ProcessDirectiveLiteralBlock();
void ProcessDirectiveCodeBlock();
@@ -72,8 +72,8 @@ private:
int IncludeDepth = 0;
bool OutputLinePending = false;
bool LastLineEndedInColonColon = false;
- MarkupType Markup = MarkupNone;
- DirectiveType Directive = DirectiveNone;
+ Markup MarkupType = Markup::None;
+ Directive DirectiveType = Directive::None;
cmsys::RegularExpression CMakeDirective;
cmsys::RegularExpression CMakeModuleDirective;
cmsys::RegularExpression ParsedLiteralDirective;
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index c1c5201..9308af4 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -183,8 +183,8 @@ private:
#define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"
#define CM_SOURCE_REGEX \
- "\\.(C|F|M|c|c\\+\\+|cc|cpp|mpp|cxx|ixx|cppm|cu|f|f90|for|fpp|ftn|m|mm|" \
- "rc|def|r|odl|idl|hpj|bat)$"
+ "\\.(C|F|M|c|c\\+\\+|cc|cpp|mpp|cxx|ixx|cppm|ccm|cxxm|c\\+\\+m|cu" \
+ "|f|f90|for|fpp|ftn|m|mm|rc|def|r|odl|idl|hpj|bat)$"
#define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$"
diff --git a/Source/cmState.h b/Source/cmState.h
index 9a17b22..0a42df0 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -253,18 +253,6 @@ public:
private:
friend class cmake;
- void AddCacheEntry(const std::string& key, const char* value,
- const char* helpString, cmStateEnums::CacheEntryType type)
- {
- this->AddCacheEntry(key,
- value ? cmValue(std::string(value)) : cmValue(nullptr),
- helpString, type);
- }
- void AddCacheEntry(const std::string& key, const std::string& value,
- const char* helpString, cmStateEnums::CacheEntryType type)
- {
- this->AddCacheEntry(key, cmValue(value), helpString, type);
- }
void AddCacheEntry(const std::string& key, cmValue value,
const char* helpString,
cmStateEnums::CacheEntryType type);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index fc13560..f06e26b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -447,7 +447,7 @@ TargetProperty const StaticTargetProperties[] = {
{ "AUTORCC_OPTIONS"_s, IC::CanCompileSources },
// Linking properties
- { "ENABLE_EXPORTS"_s, IC::ExecutableTarget },
+ { "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
{ "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
{ "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
{ "LINK_SEARCH_END_STATIC"_s, IC::CanCompileSources },
@@ -614,7 +614,6 @@ TargetProperty const StaticTargetProperties[] = {
#undef COMMON_LANGUAGE_PROPERTIES
#undef IC
#undef R
-
}
class cmTargetInternals
@@ -631,6 +630,7 @@ public:
bool HaveInstallRule;
bool IsDLLPlatform;
bool IsAIX;
+ bool IsApple;
bool IsAndroid;
bool BuildInterfaceIncludesAppended;
bool PerConfig;
@@ -917,6 +917,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->impl->HaveInstallRule = false;
this->impl->IsDLLPlatform = false;
this->impl->IsAIX = false;
+ this->impl->IsApple = false;
this->impl->IsAndroid = false;
this->impl->TargetVisibility = vis;
this->impl->BuildInterfaceIncludesAppended = false;
@@ -934,6 +935,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->impl->IsAIX = (systemName == "AIX" || systemName == "OS400");
}
+ // Check whether we are targeting Apple.
+ this->impl->IsApple = this->impl->Makefile->IsOn("APPLE");
+
// Check whether we are targeting an Android platform.
this->impl->IsAndroid = (this->impl->Makefile->GetSafeDefinition(
"CMAKE_SYSTEM_NAME") == "Android");
@@ -1033,6 +1037,31 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
defKey += "CMAKE_";
auto initProperty = [this, mf, &defKey](const std::string& property,
const char* default_value) {
+ // special init for ENABLE_EXPORTS
+ // For SHARED_LIBRARY, only CMAKE_SHARED_LIBRARY_ENABLE_EXPORTS variable
+ // is used
+ // For EXECUTABLE, CMAKE_EXECUTABLE_ENABLE_EXPORTS or else
+ // CMAKE_ENABLE_EXPORTS variables are used
+ if (property == "ENABLE_EXPORTS"_s) {
+ // Replace everything after "CMAKE_"
+ defKey.replace(
+ defKey.begin() + 6, defKey.end(),
+ cmStrCat(this->impl->TargetType == cmStateEnums::EXECUTABLE
+ ? "EXECUTABLE"
+ : "SHARED_LIBRARY",
+ '_', property));
+ if (cmValue value = mf->GetDefinition(defKey)) {
+ this->SetProperty(property, value);
+ return;
+ }
+ if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY) {
+ if (default_value) {
+ this->SetProperty(property, default_value);
+ }
+ return;
+ }
+ }
+
// Replace everything after "CMAKE_"
defKey.replace(defKey.begin() + 6, defKey.end(), property);
if (cmValue value = mf->GetDefinition(defKey)) {
@@ -1207,18 +1236,22 @@ bool cmTarget::IsExecutableWithExports() const
this->GetPropertyAsBool("ENABLE_EXPORTS"));
}
+bool cmTarget::IsSharedLibraryWithExports() const
+{
+ return (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
+ this->GetPropertyAsBool("ENABLE_EXPORTS"));
+}
+
bool cmTarget::IsFrameworkOnApple() const
{
return ((this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY) &&
- this->impl->Makefile->IsOn("APPLE") &&
- this->GetPropertyAsBool("FRAMEWORK"));
+ this->IsApple() && this->GetPropertyAsBool("FRAMEWORK"));
}
bool cmTarget::IsAppBundleOnApple() const
{
- return (this->GetType() == cmStateEnums::EXECUTABLE &&
- this->impl->Makefile->IsOn("APPLE") &&
+ return (this->GetType() == cmStateEnums::EXECUTABLE && this->IsApple() &&
this->GetPropertyAsBool("MACOSX_BUNDLE"));
}
@@ -1783,7 +1816,6 @@ std::string ConvertToString<cmValue>(cmValue value)
{
return std::string(*value);
}
-
}
template <typename ValueType>
@@ -2586,6 +2618,10 @@ bool cmTarget::IsAIX() const
{
return this->impl->IsAIX;
}
+bool cmTarget::IsApple() const
+{
+ return this->impl->IsApple;
+}
bool cmTarget::IsNormal() const
{
@@ -2685,7 +2721,8 @@ const char* cmTarget::GetSuffixVariableInternal(
case cmStateEnums::RuntimeBinaryArtifact:
return "CMAKE_SHARED_LIBRARY_SUFFIX";
case cmStateEnums::ImportLibraryArtifact:
- return "CMAKE_IMPORT_LIBRARY_SUFFIX";
+ return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_SUFFIX"
+ : "CMAKE_IMPORT_LIBRARY_SUFFIX";
}
break;
case cmStateEnums::MODULE_LIBRARY:
@@ -2726,7 +2763,8 @@ const char* cmTarget::GetPrefixVariableInternal(
case cmStateEnums::RuntimeBinaryArtifact:
return "CMAKE_SHARED_LIBRARY_PREFIX";
case cmStateEnums::ImportLibraryArtifact:
- return "CMAKE_IMPORT_LIBRARY_PREFIX";
+ return this->IsApple() ? "CMAKE_APPLE_IMPORT_FILE_PREFIX"
+ : "CMAKE_IMPORT_LIBRARY_PREFIX";
}
break;
case cmStateEnums::MODULE_LIBRARY:
@@ -3001,7 +3039,9 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
bool allowImp = (this->IsDLLPlatform() &&
(this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports())) ||
- (this->IsAIX() && this->IsExecutableWithExports());
+ (this->IsAIX() && this->IsExecutableWithExports()) ||
+ (this->GetMakefile()->PlatformSupportsAppleTextStubs() &&
+ this->IsSharedLibraryWithExports());
// If a mapping was found, check its configurations.
for (auto mci = mappedConfigs.begin();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 95539fa..24f6fcd 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -205,6 +205,8 @@ public:
//! Return whether or not we are targeting AIX.
bool IsAIX() const;
+ //! Return whether or not we are targeting Apple.
+ bool IsApple() const;
bool IsNormal() const;
bool IsSynthetic() const;
@@ -219,6 +221,10 @@ public:
//! Return whether this target is an executable with symbol exports enabled.
bool IsExecutableWithExports() const;
+ //! Return whether this target is a shared library with symbol exports
+ //! enabled.
+ bool IsSharedLibraryWithExports() const;
+
//! Return whether this target is a shared library Framework on Apple.
bool IsFrameworkOnApple() const;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 652ca54..8926f9e 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -693,12 +693,12 @@ void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile(
switch (this->ProjectType) {
case VsProjectType::vcxproj: {
+ Elem(e0, "Import").Attribute("Project", VS10_CXX_DEFAULT_PROPS);
std::string const& props =
this->GlobalGenerator->GetPlatformToolsetVersionProps();
if (!props.empty()) {
Elem(e0, "Import").Attribute("Project", props);
}
- Elem(e0, "Import").Attribute("Project", VS10_CXX_DEFAULT_PROPS);
} break;
case VsProjectType::csproj:
Elem(e0, "Import")
@@ -1810,13 +1810,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
this->WriteCustomRuleCSharp(e0, c, name, script, additional_inputs.str(),
outputs.str(), comment, ccg);
} else {
- this->WriteCustomRuleCpp(
- *spe2, c, script, additional_inputs.str(), outputs.str(), comment, ccg,
- symbolic,
- (command.GetUsesTerminal() ||
- (command.HasMainDependency() && source->GetIsGenerated()))
- ? BuildInParallel::No
- : BuildInParallel::Yes);
+ BuildInParallel buildInParallel = BuildInParallel::No;
+ if (command.GetCMP0147Status() == cmPolicies::NEW &&
+ !command.GetUsesTerminal() &&
+ !(command.HasMainDependency() && source->GetIsGenerated())) {
+ buildInParallel = BuildInParallel::Yes;
+ }
+ this->WriteCustomRuleCpp(*spe2, c, script, additional_inputs.str(),
+ outputs.str(), comment, ccg, symbolic,
+ buildInParallel);
}
}
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index dbf961d..d4bbc14 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -335,7 +335,7 @@ cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
// The "c" extension MUST precede the "C" extension.
setupExts(this->CLikeSourceFileExtensions,
{ "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M",
- "mm", "ixx", "cppm" });
+ "mm", "ixx", "cppm", "ccm", "cxxm", "c++m" });
setupExts(this->HeaderFileExtensions,
{ "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
setupExts(this->CudaFileExtensions, { "cu" });
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 6cdd5a3..3bb7869 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2528,6 +2528,12 @@ SystemTools::CopyStatus SystemTools::CloneFileContent(
return status;
#elif defined(__APPLE__) && \
defined(KWSYS_SYSTEMTOOLS_HAVE_MACOS_COPYFILE_CLONE)
+ // When running as root, copyfile() copies more metadata than we
+ // want, such as ownership. Pretend it is not available.
+ if (getuid() == 0) {
+ return CopyStatus{ Status::POSIX(ENOSYS), CopyStatus::NoPath };
+ }
+
// NOTE: we cannot use `clonefile` as the {a,c,m}time for the file needs to
// be updated by `copy_file_if_different` and `copy_file`.
if (copyfile(source.c_str(), destination.c_str(), nullptr,
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index 89be4b8..6c006bc 100644
--- a/Source/kwsys/kwsysPlatformTests.cmake
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -8,9 +8,6 @@ macro(KWSYS_PLATFORM_TEST lang var description invert)
if(NOT DEFINED ${var}_COMPILED)
message(STATUS "${description}")
set(maybe_cxx_standard "")
- if(CMAKE_VERSION VERSION_LESS 3.8 AND CMAKE_CXX_STANDARD)
- set(maybe_cxx_standard "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
- endif()
try_compile(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
@@ -18,14 +15,16 @@ macro(KWSYS_PLATFORM_TEST lang var description invert)
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${KWSYS_PLATFORM_TEST_LINK_LIBRARIES}"
${maybe_cxx_standard}
OUTPUT_VARIABLE OUTPUT)
- if(${var}_COMPILED)
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "${description} compiled with the following output:\n${OUTPUT}\n\n")
- else()
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
+ if(CMAKE_VERSION VERSION_LESS 3.26)
+ if(${var}_COMPILED)
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${description} compiled with the following output:\n${OUTPUT}\n\n")
+ else()
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
+ endif()
endif()
if(${invert} MATCHES INVERT)
if(${var}_COMPILED)
@@ -67,19 +66,23 @@ macro(KWSYS_PLATFORM_TEST_RUN lang var description invert)
# Note that ${var} will be a 0 return value on success.
if(${var}_COMPILED)
- if(${var})
+ if(CMAKE_VERSION VERSION_LESS 3.26)
+ if(${var})
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
+ else()
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
+ endif()
+ endif()
+ else()
+ if(CMAKE_VERSION VERSION_LESS 3.26)
file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
- else()
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
+ "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
endif()
- else()
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
set(${var} -1 CACHE INTERNAL "${description} failed to compile.")
endif()
@@ -188,14 +191,16 @@ macro(KWSYS_PLATFORM_INFO_TEST lang var description)
OUTPUT_VARIABLE OUTPUT
COPY_FILE ${KWSYS_PLATFORM_INFO_FILE}
)
- if(${var}_COMPILED)
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "${description} compiled with the following output:\n${OUTPUT}\n\n")
- else()
- file(APPEND
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
+ if(CMAKE_VERSION VERSION_LESS 3.26)
+ if(${var}_COMPILED)
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "${description} compiled with the following output:\n${OUTPUT}\n\n")
+ else()
+ file(APPEND
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "${description} failed to compile with the following output:\n${OUTPUT}\n\n")
+ endif()
endif()
if(${var}_COMPILED)
message(STATUS "${description} - compiled")