From 42b3f00980dd3595443a94998cd6893d6b76c928 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 6 Jan 2022 09:41:10 +0100 Subject: [PATCH] Added extra checks for valid CMake builds, and fixed previous check for correct project path in CMakeCache.txt --- src/project.cpp | 27 +++++++++++++++++---------- src/project_build.cpp | 31 +++++++++++++++---------------- src/project_build.hpp | 8 ++++---- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/project.cpp b/src/project.cpp index e5359ad..f96fcbd 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -150,7 +150,7 @@ void Project::debug_update_stop() { } } } - //Add debug stop source mark + // Add debug stop source mark debug_last_stop_file_path.clear(); for(size_t c = 0; c < Notebook::get().size(); c++) { auto view = Notebook::get().get_view(c); @@ -369,8 +369,8 @@ void Project::LLDB::debug_compile_and_start() { auto view = Notebook::get().get_current_view(); run_arguments = build->get_executable(view ? view->file_path : Directories::get().path).string(); if(run_arguments.empty()) { - if(!build->is_valid()) - Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please rebuild project.\n", true); + if(!build->is_valid(default_build_path)) + Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please recreate project.\n", true); else { Terminal::get().print("\e[33mWarning\e[m: could not find executable.\n"); Terminal::get().print("Either use Project Set Run Arguments, or open a source file within a directory where an executable is defined.\n"); @@ -389,9 +389,12 @@ void Project::LLDB::debug_compile_and_start() { Terminal::get().clear(); Terminal::get().print("\e[2mCompiling and debugging: " + run_arguments + "\e[m\n"); - Terminal::get().async_process(build->get_compile_command(), debug_build_path, [self = this->shared_from_this(), run_arguments, project_path = build->project_path, remote_host](int exit_status) { - if(exit_status != EXIT_SUCCESS) + Terminal::get().async_process(build->get_compile_command(), debug_build_path, [self = shared_from_this(), debug_build_path, run_arguments, project_path = build->project_path, remote_host](int exit_status) { + if(exit_status != 0) { debugging = false; + if(!self->build->is_valid(debug_build_path)) + Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please recreate project.\n", true); + } else { self->debug_start(run_arguments, project_path, remote_host); } @@ -546,7 +549,7 @@ void Project::LLDB::debug_backtrace() { for(auto &frame : frames) { std::string row = "" + frame.module_filename + ""; - //Shorten frame.function_name if it is too long + // Shorten frame.function_name if it is too long if(frame.function_name.size() > 120) { frame.function_name = frame.function_name.substr(0, 58) + "...." + frame.function_name.substr(frame.function_name.size() - 58); } @@ -717,8 +720,10 @@ void Project::Clang::compile() { Terminal::get().clear(); Terminal::get().print("\e[2mCompiling project: " + filesystem::get_short_path(build->project_path).string() + "\e[m\n"); - Terminal::get().async_process(build->get_compile_command(), default_build_path, [](int exit_status) { + Terminal::get().async_process(build->get_compile_command(), default_build_path, [self = shared_from_this(), default_build_path](int exit_status) { compiling = false; + if(exit_status != 0 && !self->build->is_valid(default_build_path)) + Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please recreate project.\n", true); }); } @@ -738,8 +743,8 @@ void Project::Clang::compile_and_run() { auto view = Notebook::get().get_current_view(); auto executable = build->get_executable(view ? view->file_path : Directories::get().path); if(executable.empty()) { - if(!build->is_valid()) - Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please rebuild project.\n", true); + if(!build->is_valid(default_build_path)) + Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please recreate project.\n", true); else { Terminal::get().print("\e[33mWarning\e[m: could not find executable.\n"); Terminal::get().print("Either use Project Set Run Arguments, or open a source file within a directory where an executable is defined.\n"); @@ -755,13 +760,15 @@ void Project::Clang::compile_and_run() { Terminal::get().clear(); Terminal::get().print("\e[2mCompiling and running: " + arguments + "\e[m\n"); - Terminal::get().async_process(build->get_compile_command(), default_build_path, [arguments, project_path](int exit_status) { + Terminal::get().async_process(build->get_compile_command(), default_build_path, [self = shared_from_this(), arguments, project_path, default_build_path](int exit_status) { compiling = false; if(exit_status == 0) { Terminal::get().async_process(arguments, project_path, [arguments](int exit_status) { Terminal::get().print("\e[2m" + arguments + " returned: " + (exit_status == 0 ? "\e[32m" : "\e[31m") + std::to_string(exit_status) + "\e[m\n"); }); } + else if(!self->build->is_valid(default_build_path)) + Terminal::get().print("\e[31mError\e[m: build folder no longer valid, please recreate project.\n", true); }); } diff --git a/src/project_build.cpp b/src/project_build.cpp index f8b096d..5d37f2e 100644 --- a/src/project_build.cpp +++ b/src/project_build.cpp @@ -146,23 +146,25 @@ boost::filesystem::path Project::CMakeBuild::get_executable(const boost::filesys return executable; } -bool Project::CMakeBuild::is_valid() { - if(project_path.empty()) - return true; - auto default_path = get_default_path(); - if(default_path.empty()) +bool Project::CMakeBuild::is_valid(const boost::filesystem::path &build_path) const { + if(project_path.empty() || build_path.empty()) return true; - std::ifstream input((default_path / "CMakeCache.txt").string(), std::ios::binary); + std::ifstream input((build_path / "CMakeCache.txt").string(), std::ios::binary); if(!input) return true; std::string line; + bool correct_source_dir = false; + bool correct_cmake_command = false; while(std::getline(input, line)) { - const static std::regex regex("^.*_SOURCE_DIR:STATIC=(.*)$", std::regex::optimize); + const static std::regex source_dir_regex("^.*_SOURCE_DIR:STATIC=(.*)$", std::regex::optimize); + const static std::regex cmake_command_regex("^CMAKE_COMMAND:INTERNAL=(.*)$", std::regex::optimize); std::smatch sm; - if(std::regex_match(line, sm, regex)) - return boost::filesystem::path(sm[1].str()) == project_path; + if(std::regex_match(line, sm, source_dir_regex)) + correct_source_dir |= boost::filesystem::path(sm[1].str()) == project_path; + else if(std::regex_match(line, sm, cmake_command_regex)) + correct_cmake_command |= filesystem::is_executable(sm[1].str()); } - return true; + return correct_source_dir && correct_cmake_command; } Project::MesonBuild::MesonBuild(const boost::filesystem::path &path) : Project::Build(), meson(path) { @@ -193,14 +195,11 @@ boost::filesystem::path Project::MesonBuild::get_executable(const boost::filesys return executable; } -bool Project::MesonBuild::is_valid() { - if(project_path.empty()) - return true; - auto default_path = get_default_path(); - if(default_path.empty()) +bool Project::MesonBuild::is_valid(const boost::filesystem::path &build_path) const { + if(project_path.empty() || build_path.empty()) return true; try { - JSON info(default_path / "meson-info" / "meson-info.json"); + JSON info(build_path / "meson-info" / "meson-info.json"); return boost::filesystem::path(info.object("directories").string("source")) == project_path; } catch(...) { diff --git a/src/project_build.hpp b/src/project_build.hpp index b9ade14..4f24643 100644 --- a/src/project_build.hpp +++ b/src/project_build.hpp @@ -18,8 +18,8 @@ namespace Project { virtual std::string get_compile_command() { return std::string(); } virtual boost::filesystem::path get_executable(const boost::filesystem::path &path) { return boost::filesystem::path(); } - /// Returns true if the project path reported by build system is correct - virtual bool is_valid() { return true; } + /// Returns false if an invalid build is found, true otherwise even when build is not found. + virtual bool is_valid(const boost::filesystem::path &build_path) const { return true; } std::vector get_exclude_folders(); @@ -38,7 +38,7 @@ namespace Project { std::string get_compile_command() override; boost::filesystem::path get_executable(const boost::filesystem::path &path) override; - bool is_valid() override; + bool is_valid(const boost::filesystem::path &build_path) const override; }; class MesonBuild : public Build { @@ -53,7 +53,7 @@ namespace Project { std::string get_compile_command() override; boost::filesystem::path get_executable(const boost::filesystem::path &path) override; - bool is_valid() override; + bool is_valid(const boost::filesystem::path &build_path) const override; }; class CompileCommandsBuild : public Build {