Browse Source

Added extra checks for valid CMake builds, and fixed previous check for correct project path in CMakeCache.txt

merge-requests/413/head
eidheim 4 years ago
parent
commit
42b3f00980
  1. 23
      src/project.cpp
  2. 31
      src/project_build.cpp
  3. 8
      src/project_build.hpp

23
src/project.cpp

@ -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);
}
@ -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);
});
}

31
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(...) {

8
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<std::string> 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 {

Loading…
Cancel
Save