diff options
author | Kyle Edwards <kyle.edwards@kitware.com> | 2019-03-14 15:58:34 (GMT) |
---|---|---|
committer | Kyle Edwards <kyle.edwards@kitware.com> | 2019-06-10 18:35:28 (GMT) |
commit | 1f9ef25130caa89969cc69b4873edf1723533a5f (patch) | |
tree | f48bf3864cc3c6ccd87e6efffcba2c1f582ac0e0 /Source/cmBinUtilsWindowsPELinker.cxx | |
parent | f36719111de99e5be426552e9aaba96518b888b7 (diff) | |
download | CMake-1f9ef25130caa89969cc69b4873edf1723533a5f.zip CMake-1f9ef25130caa89969cc69b4873edf1723533a5f.tar.gz CMake-1f9ef25130caa89969cc69b4873edf1723533a5f.tar.bz2 |
file: Add GET_RUNTIME_DEPENDENCIES mode
Co-Authored-by: Bryon Bean <bryon.bean@kitware.com>
Diffstat (limited to 'Source/cmBinUtilsWindowsPELinker.cxx')
-rw-r--r-- | Source/cmBinUtilsWindowsPELinker.cxx | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx new file mode 100644 index 0000000..796e9ed --- /dev/null +++ b/Source/cmBinUtilsWindowsPELinker.cxx @@ -0,0 +1,121 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include "cmBinUtilsWindowsPELinker.h" +#include "cmAlgorithms.h" +#include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h" +#include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h" +#include "cmRuntimeDependencyArchive.h" +#include "cmSystemTools.h" + +#include <memory> +#include <sstream> +#include <vector> + +#ifdef _WIN32 +# include <windows.h> +#endif + +cmBinUtilsWindowsPELinker::cmBinUtilsWindowsPELinker( + cmRuntimeDependencyArchive* archive) + : cmBinUtilsLinker(archive) +{ +} + +bool cmBinUtilsWindowsPELinker::Prepare() +{ + std::string tool = this->Archive->GetGetRuntimeDependenciesTool(); + if (tool.empty()) { + std::vector<std::string> command; + if (this->Archive->GetGetRuntimeDependenciesCommand("dumpbin", command)) { + tool = "dumpbin"; + } else { + tool = "objdump"; + } + } + if (tool == "dumpbin") { + this->Tool = + cm::make_unique<cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool>( + this->Archive); + } else if (tool == "objdump") { + this->Tool = + cm::make_unique<cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool>( + this->Archive); + } else { + std::ostringstream e; + e << "Invalid value for CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL: " << tool; + this->SetError(e.str()); + return false; + } + + return true; +} + +bool cmBinUtilsWindowsPELinker::ScanDependencies( + std::string const& file, cmStateEnums::TargetType /* unused */) +{ + std::vector<std::string> needed; + if (!this->Tool->GetFileInfo(file, needed)) { + return false; + } + for (auto& n : needed) { + n = cmSystemTools::LowerCase(n); + } + std::string origin = cmSystemTools::GetFilenamePath(file); + + for (auto const& lib : needed) { + if (!this->Archive->IsPreExcluded(lib)) { + std::string path; + bool resolved = false; + if (!this->ResolveDependency(lib, origin, path, resolved)) { + return false; + } + if (resolved) { + if (!this->Archive->IsPostExcluded(path)) { + bool unique; + this->Archive->AddResolvedPath(lib, path, unique); + if (unique && + !this->ScanDependencies(path, cmStateEnums::SHARED_LIBRARY)) { + return false; + } + } + } else { + this->Archive->AddUnresolvedPath(lib); + } + } + } + + return true; +} + +bool cmBinUtilsWindowsPELinker::ResolveDependency(std::string const& name, + std::string const& origin, + std::string& path, + bool& resolved) +{ + auto dirs = this->Archive->GetSearchDirectories(); + +#ifdef _WIN32 + char buf[MAX_PATH]; + unsigned int len; + if ((len = GetWindowsDirectoryA(buf, MAX_PATH)) > 0) { + dirs.insert(dirs.begin(), std::string(buf, len)); + } + if ((len = GetSystemDirectoryA(buf, MAX_PATH)) > 0) { + dirs.insert(dirs.begin(), std::string(buf, len)); + } +#endif + + dirs.insert(dirs.begin(), origin); + + for (auto const& searchPath : dirs) { + path = searchPath + '/' + name; + if (cmSystemTools::PathExists(path)) { + resolved = true; + return true; + } + } + + resolved = false; + return true; +} |