| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- /* 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 "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h"
- #include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h"
- #include "cmRuntimeDependencyArchive.h"
- #include "cmStringAlgorithms.h"
- #include "cmSystemTools.h"
- #include <sstream>
- #include <vector>
- #include "cm_memory.hxx"
- #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 = cmStrCat(searchPath, '/', name);
- if (cmSystemTools::PathExists(path)) {
- resolved = true;
- return true;
- }
- }
- resolved = false;
- return true;
- }
|