mirror of
https://github.com/Kitware/CMake.git
synced 2026-06-30 19:57:41 +00:00
Since commitae373e93fb(install(PACKAGE_INFO): Add version and location to package dependencies, 2025-07-31, v4.2.0-rc1~340^2) we add package information to the current package's stack entry as it is discovered. However, a nested package can cause the current package's stack entry to be replaced by a copy with a new ordering index due to commitc6e6861e63(install(EXPORT): Export find_dependency() calls, 2023-11-07, v3.29.0-rc1~439^2~1). Depending on whether imported targets were created by the current package before finding the nested package, the `CurrentPackageInfo` pointer is either invalidated, or left pointing at only one of multiple copies. Fix this by sharing a single instance of package information with all copies of the current package's stack entry. Keep a mutable pointer to the current package's information only while it is still pending. This also avoids the need to expose mutation from the package stack. Add a test that exposes the previously-invalidated pointer to dynamic analysis tools. Fixes: #27730
56 lines
1.4 KiB
C++
56 lines
1.4 KiB
C++
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file LICENSE.rst or https://cmake.org/licensing for details. */
|
|
#pragma once
|
|
|
|
#include "cmConfigure.h" // IWYU pragma: keep
|
|
|
|
#include <memory>
|
|
#include <set>
|
|
#include <string>
|
|
|
|
#include <cm/optional>
|
|
|
|
#include "cmConstStack.h"
|
|
|
|
/**
|
|
* This data represents the actual contents of find_package
|
|
* <PACKAGE>-Config.cmake or <PACKAGE>.cps file, and not what is passed
|
|
* to the find_package command. They can be the same, but it is not guaranteed.
|
|
*/
|
|
|
|
class cmPackageInformation
|
|
{
|
|
public:
|
|
cm::optional<std::string> Directory;
|
|
cm::optional<std::string> Version;
|
|
cm::optional<std::string> Description;
|
|
cm::optional<std::string> License;
|
|
cm::optional<std::string> Website;
|
|
cm::optional<std::string> PackageUrl;
|
|
std::set<std::string> Components;
|
|
};
|
|
|
|
/**
|
|
* Represents one call to find_package.
|
|
*/
|
|
class cmFindPackageCall
|
|
{
|
|
public:
|
|
std::string const Name;
|
|
std::shared_ptr<cmPackageInformation const> PackageInfo;
|
|
unsigned int Index;
|
|
};
|
|
|
|
/**
|
|
* Represents a stack of find_package calls with efficient value semantics.
|
|
*/
|
|
class cmFindPackageStack
|
|
: public cmConstStack<cmFindPackageCall, cmFindPackageStack>
|
|
{
|
|
using cmConstStack::cmConstStack;
|
|
friend class cmConstStack<cmFindPackageCall, cmFindPackageStack>;
|
|
};
|
|
#ifndef cmFindPackageStack_cxx
|
|
extern template class cmConstStack<cmFindPackageCall, cmFindPackageStack>;
|
|
#endif
|