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 {