diff --git a/src/cmake.cc b/src/cmake.cc index 8a5ee2e..c28a46b 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -5,6 +5,8 @@ #include "terminal.h" #include +std::unordered_set CMake::debug_build_needed; + CMake::CMake(const boost::filesystem::path &path) { const auto find_cmake_project=[this](const boost::filesystem::path &cmake_path) { for(auto &line: filesystem::read_lines(cmake_path)) { @@ -31,12 +33,6 @@ CMake::CMake(const boost::filesystem::path &path) { break; search_path=search_path.parent_path(); } - - if(!project_path.empty()) { - auto default_build_path=get_default_build_path(project_path); - if(!default_build_path.empty() && !boost::filesystem::exists(default_build_path/"compile_commands.json")) - create_compile_commands(project_path); - } } boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &project_path) { @@ -109,12 +105,24 @@ boost::filesystem::path CMake::get_debug_build_path(const boost::filesystem::pat return debug_build_path; } -bool CMake::create_compile_commands(const boost::filesystem::path &project_path) { +bool CMake::create_default_build(const boost::filesystem::path &project_path, bool force) { + if(project_path.empty()) + return false; + + if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) + return false; + auto default_build_path=get_default_build_path(project_path); if(default_build_path.empty()) return false; + + if(!force && boost::filesystem::exists(default_build_path/"compile_commands.json")) + return true; + + debug_build_needed.emplace(project_path.string()); + auto compile_commands_path=default_build_path/"compile_commands.json"; - Dialog::Message message("Creating "+compile_commands_path.string()); + Dialog::Message message("Creating/updating default build"); auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ filesystem::escape_argument(project_path)+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path); message.hide(); @@ -139,12 +147,25 @@ bool CMake::create_compile_commands(const boost::filesystem::path &project_path) } bool CMake::create_debug_build(const boost::filesystem::path &project_path) { + if(project_path.empty()) + return false; + + if(!boost::filesystem::exists(project_path/"CMakeLists.txt")) + return false; + auto debug_build_path=get_debug_build_path(project_path); if(debug_build_path.empty()) return false; + + if(boost::filesystem::exists(debug_build_path/"CMakeCache.txt")) { + auto it=debug_build_needed.find(project_path.string()); + if(it==debug_build_needed.end()) + return true; + debug_build_needed.erase(it); + } + std::unique_ptr message; - if(!boost::filesystem::exists(debug_build_path/"CMakeCache.txt")) - message=std::unique_ptr(new Dialog::Message("Creating debug build")); + message=std::unique_ptr(new Dialog::Message("Creating/updating debug build")); auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ filesystem::escape_argument(project_path)+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path); if(message) diff --git a/src/cmake.h b/src/cmake.h index e26c4cc..bfa463b 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -3,6 +3,7 @@ #include #include #include +#include class CMake { public: @@ -12,7 +13,7 @@ public: static boost::filesystem::path get_default_build_path(const boost::filesystem::path &project_path); static boost::filesystem::path get_debug_build_path(const boost::filesystem::path &project_path); - static bool create_compile_commands(const boost::filesystem::path &project_path); + static bool create_default_build(const boost::filesystem::path &project_path, bool force=false); static bool create_debug_build(const boost::filesystem::path &project_path); boost::filesystem::path get_executable(const boost::filesystem::path &file_path); @@ -30,5 +31,6 @@ private: void parse(); std::vector get_function_parameters(std::string &data); bool parsed=false; + static std::unordered_set debug_build_needed; }; #endif //JUCI_CMAKE_H_ diff --git a/src/notebook.cc b/src/notebook.cc index 2ba702b..eec39b3 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -110,8 +110,7 @@ void Notebook::open(const boost::filesystem::path &file_path) { } } if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { - if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(CMake::get_default_build_path(project_path)/"compile_commands.json")) - CMake::create_compile_commands(project_path); + CMake::create_default_build(project_path); source_views.emplace_back(new Source::ClangView(file_path, project_path, language)); } else @@ -249,12 +248,12 @@ bool Notebook::save(int page) { if(view->file_path.filename()=="CMakeLists.txt") { auto &directories=Directories::get(); if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') { - if(CMake::create_compile_commands(directories.cmake->project_path)) + if(CMake::create_default_build(directories.cmake->project_path, true)) project_path=directories.cmake->project_path; } else { CMake cmake(view->file_path.parent_path()); - if(cmake.project_path!="" && CMake::create_compile_commands(cmake.project_path)) + if(CMake::create_default_build(cmake.project_path, true)) project_path=cmake.project_path; } if(project_path!="") { diff --git a/src/window.cc b/src/window.cc index 6a4a0cd..584c3aa 100644 --- a/src/window.cc +++ b/src/window.cc @@ -208,7 +208,11 @@ std::unique_ptr Window::get_cmake() { path=Directories::get().current_path; if(path.empty()) return nullptr; - return std::unique_ptr(new CMake(path)); + auto cmake=std::unique_ptr(new CMake(path)); + if(cmake->project_path.empty()) + return nullptr; + CMake::create_default_build(cmake->project_path); + return cmake; } void Window::configure() { @@ -594,29 +598,18 @@ void Window::set_menu_actions() { auto cmake=get_cmake(); if(!cmake) return; + auto project_path=std::make_shared(cmake->project_path); - if(project_path->empty()) - return; auto run_arguments_it=project_run_arguments.find(project_path->string()); std::string run_arguments; if(run_arguments_it!=project_run_arguments.end()) run_arguments=run_arguments_it->second; if(run_arguments.empty()) { - boost::filesystem::path cmake_path; - if(notebook.get_current_page()!=-1) - cmake_path=notebook.get_current_view()->file_path.parent_path(); - else - cmake_path=Directories::get().current_path; - if(cmake_path.empty()) - return; - CMake cmake(cmake_path); - if(cmake.project_path.empty()) - return; - auto executable=cmake.get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); if(executable!="") { - auto project_path=cmake.project_path; + auto project_path=cmake->project_path; auto default_build_path=CMake::get_default_build_path(project_path); if(!default_build_path.empty()) { size_t pos=executable.find(project_path.string()); @@ -626,7 +619,7 @@ void Window::set_menu_actions() { run_arguments=filesystem::escape_argument(executable); } else - run_arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake.project_path)); + run_arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); } entry_box.clear(); @@ -655,8 +648,6 @@ void Window::set_menu_actions() { if(!cmake) return; auto project_path=cmake->project_path; - if(project_path.empty()) - return; auto default_build_path=CMake::get_default_build_path(project_path); if(default_build_path.empty()) @@ -700,24 +691,18 @@ void Window::set_menu_actions() { menu.add_action("compile", [this]() { if(compiling) return; - boost::filesystem::path cmake_path; - if(notebook.get_current_page()!=-1) - cmake_path=notebook.get_current_view()->file_path.parent_path(); - else - cmake_path=Directories::get().current_path; - if(cmake_path.empty()) + auto cmake=get_cmake(); + if(!cmake) return; - CMake cmake(cmake_path); - if(cmake.project_path!="") { - auto default_build_path=CMake::get_default_build_path(cmake.project_path); - if(default_build_path.empty()) - return; - compiling=true; - Terminal::get().print("Compiling project "+cmake.project_path.string()+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status){ - compiling=false; - }); - } + + auto default_build_path=CMake::get_default_build_path(cmake->project_path); + if(default_build_path.empty()) + return; + compiling=true; + Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); + Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status){ + compiling=false; + }); }); menu.add_action("run_command", [this]() { @@ -760,29 +745,18 @@ void Window::set_menu_actions() { auto cmake=get_cmake(); if(!cmake) return; + auto project_path=std::make_shared(cmake->project_path); - if(project_path->empty()) - return; auto run_arguments_it=debug_run_arguments.find(project_path->string()); std::string run_arguments; if(run_arguments_it!=debug_run_arguments.end()) run_arguments=run_arguments_it->second; if(run_arguments.empty()) { - boost::filesystem::path cmake_path; - if(notebook.get_current_page()!=-1) - cmake_path=notebook.get_current_view()->file_path.parent_path(); - else - cmake_path=Directories::get().current_path; - if(cmake_path.empty()) - return; - CMake cmake(cmake_path); - if(cmake.project_path.empty()) - return; - auto executable=cmake.get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); + auto executable=cmake->get_executable(notebook.get_current_page()!=-1?notebook.get_current_view()->file_path:"").string(); if(executable!="") { - auto project_path=cmake.project_path; + auto project_path=cmake->project_path; auto debug_build_path=CMake::get_debug_build_path(project_path); if(!debug_build_path.empty()) { size_t pos=executable.find(project_path.string()); @@ -792,7 +766,7 @@ void Window::set_menu_actions() { run_arguments=filesystem::escape_argument(executable); } else - run_arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake.project_path)); + run_arguments=filesystem::escape_argument(CMake::get_debug_build_path(cmake->project_path)); } entry_box.clear(); @@ -823,8 +797,6 @@ void Window::set_menu_actions() { if(!cmake) return; auto project_path=cmake->project_path; - if(project_path.empty()) - return; auto debug_build_path=CMake::get_debug_build_path(project_path); if(debug_build_path.empty())