From 606db580d53dd516095016d3fd3a0d1c2889d0d0 Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 19 Dec 2015 10:51:39 +0100 Subject: [PATCH] Fixes #121, #131 and #132. More testing needed, except bugfix commits soon. --- src/cmake.cc | 39 ++++++++++++++++++++++++++++++++++++--- src/cmake.h | 2 ++ src/config.cc | 2 ++ src/config.h | 1 + src/files.h | 4 +++- src/notebook.cc | 2 +- src/source_clang.cc | 3 ++- src/window.cc | 15 +++++++++++---- 8 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/cmake.cc b/src/cmake.cc index 620575f..3665cae 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -33,14 +33,47 @@ CMake::CMake(const boost::filesystem::path &path) { } if(!project_path.empty()) { - if(boost::filesystem::exists(project_path/"CMakeLists.txt") && !boost::filesystem::exists(project_path/"compile_commands.json")) + if(!boost::filesystem::exists(get_default_build_path(project_path)/"compile_commands.json")) create_compile_commands(project_path); } } +boost::filesystem::path CMake::get_default_build_path(const boost::filesystem::path &path) { + boost::filesystem::path default_build_path=Config::get().terminal.default_build_path; + + const std::string path_variable_project_directory_name=""; + size_t pos=0; + auto default_build_path_string=default_build_path.string(); + auto path_filename_string=path.filename().string(); + while((pos=default_build_path_string.find(path_variable_project_directory_name, pos))!=std::string::npos) { + default_build_path_string.replace(pos, path_variable_project_directory_name.size(), path_filename_string); + pos+=path_filename_string.size(); + } + if(pos!=0) + default_build_path=default_build_path_string; + + if(default_build_path.is_relative()) + default_build_path=path/default_build_path; + + if(!boost::filesystem::exists(default_build_path)) { + boost::system::error_code ec; + boost::filesystem::create_directories(default_build_path, ec); + if(ec) { + Terminal::get().print("Could not create "+default_build_path.string()+": "+ec.message(), true); + return boost::filesystem::path(); + } + } + + return default_build_path; +} + bool CMake::create_compile_commands(const boost::filesystem::path &path) { - Dialog::Message message("Creating "+path.string()+"/compile_commands.json"); - auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path); + auto default_build_path=get_default_build_path(path); + if(default_build_path.empty()) + return false; + Dialog::Message message("Creating "+default_build_path.string()+"/compile_commands.json"); + auto exit_status=Terminal::get().process(Config::get().terminal.cmake_command+" "+ + path.string()+" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", default_build_path); message.hide(); if(exit_status==EXIT_SUCCESS) { #ifdef _WIN32 //Temporary fix to MSYS2's libclang diff --git a/src/cmake.h b/src/cmake.h index 8be9d13..e995b23 100644 --- a/src/cmake.h +++ b/src/cmake.h @@ -8,6 +8,7 @@ class CMake { public: CMake(const boost::filesystem::path &path); std::vector > > get_functions_parameters(const std::string &name); + static boost::filesystem::path get_default_build_path(const boost::filesystem::path &path); static bool create_compile_commands(const boost::filesystem::path &path); std::vector paths; @@ -15,6 +16,7 @@ public: boost::filesystem::path project_path; std::unordered_map variables; private: + void read_files(); void remove_tabs(); void remove_comments(); diff --git a/src/config.cc b/src/config.cc index 8663e64..aa583fd 100644 --- a/src/config.cc +++ b/src/config.cc @@ -84,6 +84,8 @@ void Config::retrieve_config() { window.theme_variant=cfg.get("gtk_theme.variant"); window.version = cfg.get("version"); window.default_size = {cfg.get("default_window_size.width"), cfg.get("default_window_size.height")}; + + terminal.default_build_path=cfg.get("project.default_build_path"); terminal.make_command=cfg.get("project.make_command"); terminal.cmake_command=cfg.get("project.cmake_command"); terminal.history_size=cfg.get("terminal_history_size"); diff --git a/src/config.h b/src/config.h index d86f1d2..6599c3a 100644 --- a/src/config.h +++ b/src/config.h @@ -24,6 +24,7 @@ public: class Terminal { public: + std::string default_build_path; std::string cmake_command; std::string make_command; std::string clang_format_command; diff --git a/src/files.h b/src/files.h index c896e74..1400e0f 100644 --- a/src/files.h +++ b/src/files.h @@ -2,7 +2,7 @@ #define JUCI_FILES_H_ #include -#define JUCI_VERSION "1.0.0" +#define JUCI_VERSION "1.0.1" const std::string configjson = "{\n" @@ -107,6 +107,8 @@ const std::string configjson = " \"close_tab\": \"w\"\n" " },\n" " \"project\": {\n" +" \"default_build_path_comment\": \"Use to insert the project top level directory name\",\n" +" \"default_build_path\": \"./build\",\n" #ifdef _WIN32 " \"cmake_command\": \"cmake -G\\\"MSYS Makefiles\\\" -DCMAKE_INSTALL_PREFIX="+JUCI_CMAKE_INSTALL_PREFIX+"\",\n" #else diff --git a/src/notebook.cc b/src/notebook.cc index 2c62395..0308bc3 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -110,7 +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(project_path.string()+"/compile_commands.json")) + 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); source_views.emplace_back(new Source::ClangView(file_path, project_path, language)); } diff --git a/src/source_clang.cc b/src/source_clang.cc index 864f318..10e226e 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -1,6 +1,7 @@ #include "source_clang.h" #include "config.h" #include "terminal.h" +#include "cmake.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -178,7 +179,7 @@ void Source::ClangViewParse::soft_reparse() { } std::vector Source::ClangViewParse::get_compilation_commands() { - clang::CompilationDatabase db(project_path.string()); + clang::CompilationDatabase db(CMake::get_default_build_path(project_path).string()); clang::CompileCommands commands(file_path.string(), db); std::vector cmds = commands.get_commands(); std::vector arguments; diff --git a/src/window.cc b/src/window.cc index acc4024..041a164 100644 --- a/src/window.cc +++ b/src/window.cc @@ -540,9 +540,16 @@ void Window::set_menu_actions() { if(cmake.project_path!="") { if(executable_path!="") { compiling=true; - Terminal::get().print("Compiling and running "+executable_path.string()+"\n"); auto project_path=cmake.project_path; - Terminal::get().async_process(Config::get().terminal.make_command, cmake.project_path, [this, executable_path, project_path](int exit_status){ + auto default_build_path=CMake::get_default_build_path(project_path); + auto executable_path_string=executable_path.string(); + size_t pos=executable_path_string.find(project_path.string()); + if(pos!=std::string::npos) { + executable_path_string.replace(pos, project_path.string().size(), default_build_path.string()); + executable_path=executable_path_string; + } + Terminal::get().print("Compiling and running "+executable_path.string()+"\n"); + Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, executable_path, default_build_path](int exit_status){ compiling=false; if(exit_status==EXIT_SUCCESS) { auto executable_path_spaces_fixed=executable_path.string(); @@ -554,7 +561,7 @@ void Window::set_menu_actions() { } last_char=executable_path_spaces_fixed[c]; } - Terminal::get().async_process(executable_path_spaces_fixed, project_path, [this, executable_path](int exit_status){ + Terminal::get().async_process(executable_path_spaces_fixed, default_build_path, [this, executable_path](int exit_status){ Terminal::get().async_print(executable_path.string()+" returned: "+std::to_string(exit_status)+'\n'); }); } @@ -581,7 +588,7 @@ void Window::set_menu_actions() { if(cmake.project_path!="") { compiling=true; Terminal::get().print("Compiling project "+cmake.project_path.string()+"\n"); - Terminal::get().async_process(Config::get().terminal.make_command, cmake.project_path, [this](int exit_status){ + Terminal::get().async_process(Config::get().terminal.make_command, CMake::get_default_build_path(cmake.project_path), [this](int exit_status){ compiling=false; }); }