Merge topic 'fileapi-windows-implib-missing-error' into release-4.2

c6a940761c fileapi: Handle unused imported libraries with missing IMPORTED_IMPLIB

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Merge-request: !11585
This commit is contained in:
Brad King
2026-01-13 10:32:18 -05:00
committed by Kitware Robot
8 changed files with 101 additions and 12 deletions
+27 -6
View File
@@ -2049,13 +2049,34 @@ Json::Value Target::DumpArtifacts()
}
// Add Windows-specific artifacts produced by the linker.
// NOTE: HasImportLibrary() only checks if the target SHOULD have an import
// library, not whether it has one set.
if (this->GT->HasImportLibrary(this->Config)) {
Json::Value artifact = Json::objectValue;
artifact["path"] =
RelativeIfUnder(this->TopBuild,
this->GT->GetFullPath(
this->Config, cmStateEnums::ImportLibraryArtifact));
artifacts.append(std::move(artifact)); // NOLINT(*)
std::string fullPath;
if (this->GT->IsImported()) {
// This imported target might not be well-formed. For Windows, it should
// have its IMPORTED_IMPLIB property set, and CMP0111's NEW behavior is
// intended to catch and report that. But if nothing uses the imported
// target, there won't have been any opportunity to detect that property
// being missing before here. Therefore, we tell ImportedGetFullPath()
// not to raise that CMP0111 error if it sees the problem. We don't want
// to trigger an error for a target that nothing uses, as that would be a
// regression compared to CMake 4.1 and earlier behavior.
fullPath = this->GT->Target->ImportedGetFullPath(
this->Config, cmStateEnums::ImportLibraryArtifact,
cmTarget::ImportArtifactMissingOk::Yes);
if (cmHasLiteralSuffix(fullPath, "-NOTFOUND")) {
fullPath.clear();
}
} else {
fullPath = this->GT->NormalGetFullPath(
this->Config, cmStateEnums::ImportLibraryArtifact, false);
}
if (!fullPath.empty()) {
Json::Value artifact = Json::objectValue;
artifact["path"] = RelativeIfUnder(this->TopBuild, fullPath);
artifacts.append(std::move(artifact)); // NOLINT(*)
}
}
if (this->GT->IsDLLPlatform() &&
this->GT->GetType() != cmStateEnums::STATIC_LIBRARY) {
+3 -2
View File
@@ -2993,7 +2993,8 @@ char const* cmTarget::GetPrefixVariableInternal(
}
std::string cmTarget::ImportedGetFullPath(
std::string const& config, cmStateEnums::ArtifactType artifact) const
std::string const& config, cmStateEnums::ArtifactType artifact,
ImportArtifactMissingOk missingOk) const
{
assert(this->IsImported());
@@ -3074,7 +3075,7 @@ std::string cmTarget::ImportedGetFullPath(
}
}
if (result.empty()) {
if (result.empty() && missingOk != ImportArtifactMissingOk::Yes) {
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
auto message = [&]() -> std::string {
std::string unset;
+9 -2
View File
@@ -328,8 +328,15 @@ public:
cmBTStringRange GetInterfaceHeaderSetsEntries() const;
cmBTStringRange GetInterfaceCxxModuleSetsEntries() const;
std::string ImportedGetFullPath(std::string const& config,
cmStateEnums::ArtifactType artifact) const;
enum class ImportArtifactMissingOk
{
No,
Yes
};
std::string ImportedGetFullPath(
std::string const& config, cmStateEnums::ArtifactType artifact,
ImportArtifactMissingOk missingOk = ImportArtifactMissingOk::No) const;
struct StrictTargetComparison
{
@@ -1224,6 +1224,7 @@ def gen_check_abstract_targets(c, g, inSource):
read_codemodel_json_data("targets/imported_object_lib.json"),
read_codemodel_json_data("targets/imported_shared_lib.json"),
read_codemodel_json_data("targets/imported_static_lib.json"),
read_codemodel_json_data("targets/unused_imported_shared_lib.json"),
read_codemodel_json_data("targets/iface_none.json"),
read_codemodel_json_data("targets/iface_symbolic.json"),
@@ -20,7 +20,8 @@
"^imported_lib::@ba7eb709d0b48779c6c8$",
"^imported_object_lib::@ba7eb709d0b48779c6c8$",
"^imported_shared_lib::@ba7eb709d0b48779c6c8$",
"^imported_static_lib::@ba7eb709d0b48779c6c8$"
"^imported_static_lib::@ba7eb709d0b48779c6c8$",
"^unused_imported_shared_lib::@ba7eb709d0b48779c6c8$"
],
"projectName": "Imported",
"minimumCMakeVersion": "3.13",
@@ -22,6 +22,7 @@
"^imported_interface_symbolic_lib::@ba7eb709d0b48779c6c8$",
"^imported_object_lib::@ba7eb709d0b48779c6c8$",
"^imported_shared_lib::@ba7eb709d0b48779c6c8$",
"^imported_static_lib::@ba7eb709d0b48779c6c8$"
"^imported_static_lib::@ba7eb709d0b48779c6c8$",
"^unused_imported_shared_lib::@ba7eb709d0b48779c6c8$"
]
}
@@ -0,0 +1,50 @@
{
"name": "unused_imported_shared_lib",
"id": "^unused_imported_shared_lib::@ba7eb709d0b48779c6c8$",
"directorySource": "^imported$",
"projectName": "Imported",
"type": "SHARED_LIBRARY",
"imported": true,
"local": true,
"abstract": true,
"symbolic": null,
"isGeneratorProvided": null,
"fileSets": null,
"sources": [],
"sourceGroups": null,
"compileGroups": null,
"backtrace": [
{
"file": "^imported/CMakeLists\\.txt$",
"line": 48,
"command": "add_library",
"hasParent": true
},
{
"file": "^imported/CMakeLists\\.txt$",
"line": null,
"command": null,
"hasParent": false
}
],
"folder": null,
"nameOnDisk": "^(lib|cyg|msys-)?unused_imported_shared\\.(so|dylib|dll)$",
"artifacts": [
{
"path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg|msys-)?unused_imported_shared\\.(so|dylib|dll)$",
"_dllExtra": false
}
],
"build": "^imported$",
"source": "^imported$",
"install": null,
"link": null,
"archive": null,
"dependencies": null,
"linkLibraries": null,
"interfaceLinkLibraries": null,
"compileDependencies": null,
"interfaceCompileDependencies": null,
"objectDependencies": null,
"orderDependencies": null
}
@@ -42,3 +42,10 @@ install(IMPORTED_RUNTIME_ARTIFACTS imported_shared_lib
install(IMPORTED_RUNTIME_ARTIFACTS imported_shared_lib
DESTINATION lib2 OPTIONAL
)
# This is deliberately missing the IMPORTED_IMPLIB property.
# The file API needs to tolerate this for unused imported targets.
add_library(unused_imported_shared_lib SHARED IMPORTED)
set_target_properties(unused_imported_shared_lib PROPERTIES
IMPORTED_LOCATION "unused_imported_shared${CMAKE_SHARED_LIBRARY_SUFFIX}"
)