Files
revng-revng/lib/Support/ProgramRunner.cpp
T
Giacomo Vercesi 05dc27715d Improve pipeline saving capabilities
This commit introduces some changes to how the revng pipeline handles
serializing to disk. Specificaly:

* Pipeline globals (specifically model.yml) are better handled if they
  are in a subdirectory. They are now saved in the "context"
  subdirectory.
* In python:revng.api the pipeline is serialized whenever there is a
  non-reproducible change to the state (e.g. binary upload or model
  change).
  In the case of analyses this is done conservatively by checking that
  the diff produced is not empty.
* The logic for computing a step's subdirectory has been moved to the
  pipeline runner, consequently if a step is asked to serialize it
  will not create any subdirectories.
* Functionality for saving a single step/context has been exposed in
  Pipeline C.
* Finally, all path concatenations are now handled by
  llvm::sys::path::append, for extra os-agnosticism.
2022-06-29 14:50:58 +02:00

65 lines
1.9 KiB
C++

/// \file ProgramRunner.cpp
/// \brief a program runner is used to invoke external programs a bit more
/// safelly than to compose a string and invoke system
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include <cstdlib>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include "revng/Support/Assert.h"
#include "revng/Support/PathList.h"
#include "revng/Support/ProgramRunner.h"
using namespace llvm;
ProgramRunner Runner;
ProgramRunner::ProgramRunner() {
using namespace llvm::sys::path;
std::string CurrentProgramPath = parent_path(getCurrentExecutableFullPath())
.str();
llvm::SmallString<128> BinPath;
append(BinPath, getCurrentRoot(), "bin");
Paths = { CurrentProgramPath, BinPath.str().str() };
// Append PATH
char *Path = getenv("PATH");
if (Path == nullptr)
return;
llvm::SmallVector<llvm::StringRef, 64> BasePaths;
StringRef(Path).split(BasePaths, ":");
for (llvm::StringRef BasePath : BasePaths)
Paths.push_back(BasePath.str());
}
int ProgramRunner::run(llvm::StringRef ProgramName,
ArrayRef<std::string> Args) {
using namespace llvm::sys;
llvm::SmallVector<llvm::StringRef, 64> PathsRef;
for (const std::string &Path : Paths)
PathsRef.push_back(llvm::StringRef(Path));
auto MaybeProgramPath = findProgramByName(ProgramName, PathsRef);
revng_assert(not Paths.empty());
revng_assert(MaybeProgramPath,
(ProgramName + " was not found in " + getenv("PATH"))
.str()
.c_str());
// Prepare actual arguments
std::vector<StringRef> StringRefs{ *MaybeProgramPath };
for (const std::string &Arg : Args)
StringRefs.push_back(Arg);
int ExitCode = ExecuteAndWait(StringRefs[0], StringRefs);
return ExitCode;
}