From 6f6c1a81475a8b43088e6a29589356120257fcb6 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Sat, 27 Mar 2021 08:04:12 +0100 Subject: [PATCH] Delete temp files Fixes #843 --- docs/generated/CLIOptions.rst | 6 ++++++ include/mull/Config/Configuration.h | 3 +++ lib/Config/Configuration.cpp | 3 ++- lib/Driver.cpp | 10 ++++++++++ lib/Toolchain/Linker.cpp | 28 ++++++++++++++++++---------- tests-lit/CMakeLists.txt | 3 ++- tests-lit/Makefile | 2 +- tests-lit/tests/keep-temps/01/main.c | 19 +++++++++++++++++++ tools/mull-cxx/CLIOptions.cpp | 22 ++++++++++++++++++++++ tools/mull-cxx/CLIOptions.h | 4 ++++ tools/mull-cxx/mull-cxx.cpp | 4 ++++ 11 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 tests-lit/tests/keep-temps/01/main.c diff --git a/docs/generated/CLIOptions.rst b/docs/generated/CLIOptions.rst index c1ac1736c..fcc4f52a0 100644 --- a/docs/generated/CLIOptions.rst +++ b/docs/generated/CLIOptions.rst @@ -1,3 +1,5 @@ +--output path output file + --workers number How many threads to use --timeout number Timeout per test run (milliseconds) @@ -24,6 +26,10 @@ --strict Enables Strict Mode: all warning messages are treated as fatal errors +--keep-object-files Keep temporary object files + +--keep-executable Keep temporary executable file + --no-test-output Does not capture output from test runs --no-mutant-output Does not capture output from mutant runs diff --git a/include/mull/Config/Configuration.h b/include/mull/Config/Configuration.h index 6a04055d9..ac49bda87 100644 --- a/include/mull/Config/Configuration.h +++ b/include/mull/Config/Configuration.h @@ -17,6 +17,8 @@ struct Configuration { bool captureMutantOutput; bool skipSanityCheckRun; bool includeNotCovered; + bool keepObjectFiles; + bool keepExecutable; int timeout; unsigned linkerTimeout; @@ -26,6 +28,7 @@ struct Configuration { std::vector bitcodePaths; std::string executable; + std::string outputFile; std::string coverageInfo; std::string linker; diff --git a/lib/Config/Configuration.cpp b/lib/Config/Configuration.cpp index c55c15d5f..5cec89b60 100644 --- a/lib/Config/Configuration.cpp +++ b/lib/Config/Configuration.cpp @@ -17,7 +17,8 @@ unsigned MullDefaultLinkerTimeoutMilliseconds = 30000; Configuration::Configuration() : debugEnabled(false), dryRunEnabled(false), captureTestOutput(true), captureMutantOutput(true), - skipSanityCheckRun(false), includeNotCovered(false), timeout(MullDefaultTimeoutMilliseconds), + skipSanityCheckRun(false), includeNotCovered(false), keepObjectFiles(false), + keepExecutable(false), timeout(MullDefaultTimeoutMilliseconds), linkerTimeout(MullDefaultLinkerTimeoutMilliseconds), diagnostics(IDEDiagnosticsKind::None), parallelization(singleThreadParallelization()) {} diff --git a/lib/Driver.cpp b/lib/Driver.cpp index fd1c77000..849ffbda8 100644 --- a/lib/Driver.cpp +++ b/lib/Driver.cpp @@ -233,6 +233,12 @@ Driver::normalRunMutations(const std::vector &mutationPoints, singleTask.execute("Link mutated program", [&]() { executable = toolchain.linker().linkObjectFiles(objectFiles); }); + if (!config.keepObjectFiles) { + for (auto &objectFile : objectFiles) { + llvm::sys::fs::remove(objectFile); + } + } + Runner runner(diagnostics); /// On macOS, sometimes newly compiled programs take more time to execute for the first run /// As we take the execution time as a baseline for timeout it makes sense to have an additional @@ -258,6 +264,10 @@ Driver::normalRunMutations(const std::vector &mutationPoints, diagnostics, "Running mutants", mutants, mutationResults, std::move(tasks)); mutantRunner.execute(); + if (!config.keepExecutable) { + llvm::sys::fs::remove(executable); + } + return mutationResults; } diff --git a/lib/Toolchain/Linker.cpp b/lib/Toolchain/Linker.cpp index 72b0af09e..257402b79 100644 --- a/lib/Toolchain/Linker.cpp +++ b/lib/Toolchain/Linker.cpp @@ -10,17 +10,25 @@ using namespace mull; using namespace std::string_literals; +std::string outputFileName(const Configuration &configuration, Diagnostics &diagnostics) { + if (configuration.outputFile.empty()) { + llvm::Twine prefix("mull"); + llvm::SmallString<128> resultPath; + + if (std::error_code err = llvm::sys::fs::createTemporaryFile(prefix, "exe", resultPath)) { + diagnostics.error("Cannot create temporary file"s + err.message()); + return std::string(); + } + return resultPath.str().str(); + } + return configuration.outputFile; +} + Linker::Linker(const Configuration &configuration, Diagnostics &diagnostics) : configuration(configuration), diagnostics(diagnostics) {} std::string Linker::linkObjectFiles(const std::vector &objects) { - llvm::Twine prefix("mull"); - llvm::SmallString<128> resultPath; - - if (std::error_code err = llvm::sys::fs::createTemporaryFile(prefix, "exe", resultPath)) { - diagnostics.error("Cannot create temporary file"s + err.message()); - return std::string(); - } + std::string outputFile = outputFileName(configuration, diagnostics); Runner runner(diagnostics); std::vector arguments; std::copy(std::begin(configuration.linkerFlags), @@ -28,7 +36,7 @@ std::string Linker::linkObjectFiles(const std::vector &objects) { std::back_inserter(arguments)); std::copy(std::begin(objects), std::end(objects), std::back_inserter(arguments)); arguments.emplace_back("-o"); - arguments.push_back(resultPath.str().str()); + arguments.push_back(outputFile); ExecutionResult result = runner.runProgram( configuration.linker, arguments, {}, configuration.linkerTimeout, true, std::nullopt); std::stringstream commandStream; @@ -49,6 +57,6 @@ std::string Linker::linkObjectFiles(const std::vector &objects) { diagnostics.error(message.str()); } diagnostics.debug("Link command: "s + command); - diagnostics.info("Compiled executable: "s + resultPath.c_str()); - return resultPath.str().str(); + diagnostics.info("Compiled executable: "s + outputFile); + return outputFile; } diff --git a/tests-lit/CMakeLists.txt b/tests-lit/CMakeLists.txt index 8962af46b..acd7dc25c 100644 --- a/tests-lit/CMakeLists.txt +++ b/tests-lit/CMakeLists.txt @@ -38,7 +38,8 @@ set(LIT_COMMAND ${LIT_EXEC} -vv ${CMAKE_CURRENT_SOURCE_DIR}/tests -) + + ) add_custom_target(tests-lit COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && make clean diff --git a/tests-lit/Makefile b/tests-lit/Makefile index 933cd8db3..7b791c18e 100644 --- a/tests-lit/Makefile +++ b/tests-lit/Makefile @@ -39,4 +39,4 @@ CLEAN_FIND_CMD=find \ CLEAN_FILES=$(shell $(CLEAN_FIND_CMD)) clean: ## Clean all temporary artefacts echo $(CLEAN_FILES) | \ - xargs rm -rfv + xargs rm -rf diff --git a/tests-lit/tests/keep-temps/01/main.c b/tests-lit/tests/keep-temps/01/main.c new file mode 100644 index 000000000..f81bff665 --- /dev/null +++ b/tests-lit/tests/keep-temps/01/main.c @@ -0,0 +1,19 @@ +int doSomething(int arg1, int arg2) { + return arg1 + arg2; +} + +int main() { + if (doSomething(2, 3) != 5) { + return 1; + } + return 0; +} + +// clang-format off + +// RUN: cd / && %clang_cc %s -fembed-bitcode -g -o %s.exe +// RUN: cd %CURRENT_DIR +// RUN: unset TERM; %MULL_EXEC -linker=%clang_cc -mutators=cxx_add_to_sub -output=%s.mutated-keep.exe -keep-executable %s.exe +// RUN: test -f %s.mutated-keep.exe +// RUN: unset TERM; %MULL_EXEC -linker=%clang_cc -mutators=cxx_add_to_sub -output=%s.mutated-delete.exe %s.exe +// RUN: test ! -f %s.mutated-delete.exe \ No newline at end of file diff --git a/tools/mull-cxx/CLIOptions.cpp b/tools/mull-cxx/CLIOptions.cpp index dbe02f1b2..aafea8549 100644 --- a/tools/mull-cxx/CLIOptions.cpp +++ b/tools/mull-cxx/CLIOptions.cpp @@ -22,6 +22,13 @@ opt tool::InputFile( value_desc("path"), cat(MullCXXCategory)); +opt tool::OutputFile( + "output", + desc("output file"), + value_desc("path"), + init(""), + cat(MullCXXCategory)); + opt tool::Workers( "workers", desc("How many threads to use"), @@ -139,6 +146,16 @@ opt tool::EnableAST( llvm::cl::desc("Enable \"white\" AST search (disabled by default)"), llvm::cl::cat(MullCXXCategory), llvm::cl::init(false)); +opt tool::KeepObjectFiles( + "keep-object-files", llvm::cl::Optional, + llvm::cl::desc("Keep temporary object files"), + llvm::cl::cat(MullCXXCategory), llvm::cl::init(false)); + +opt tool::KeepExecutable( + "keep-executable", llvm::cl::Optional, + llvm::cl::desc("Keep temporary executable file"), + llvm::cl::cat(MullCXXCategory), llvm::cl::init(false)); + opt tool::GitDiffRef( "git-diff-ref", desc("Git branch to run diff against (enables incremental testing)"), @@ -324,6 +341,8 @@ void tool::dumpCLIInterface(Diagnostics &diagnostics) { Option *mutators = &(Option &)Mutators; Option *reporters = &(Option &)ReportersOption; std::vector