void CompilationDatabase::Initialize() { Open(); if(!IsOpened()) return; // get list of files created by cmake FileNameVector_t files = GetCompileCommandsFiles(); // pick codelite's compilation database created by codelite-cc // - convert it to compile_commands.json // - append it the list of files wxFileName clCustomCompileFile = GetFileName(); clCustomCompileFile.SetExt("db.txt"); if(clCustomCompileFile.Exists()) { wxFileName compile_commands = ConvertCodeLiteCompilationDatabaseToCMake(clCustomCompileFile); if(compile_commands.IsOk()) { files.push_back(compile_commands); } } // Sort the files by modification time std::sort(files.begin(), files.end(), wxFileNameSorter()); for(size_t i = 0; i < files.size(); ++i) { ProcessCMakeCompilationDatabase(files.at(i)); } }
FileNameVector_t CompilationDatabase::GetCompileCommandsFiles() const { wxFileName databaseFile(GetFileName()); wxFileName fn(databaseFile); // Usually it will be under the top folder fn.RemoveLastDir(); // Since we can have multiple "compile_commands.json" files, we take the most updated file // Prepare a list of files to check FileNameVector_t files; std::queue<std::pair<wxString, int> > dirs; // we start with the current path dirs.push(std::make_pair(fn.GetPath(), 0)); const int MAX_DEPTH = 2; // If no files were found, scan 2 levels only while(!dirs.empty()) { std::pair<wxString, int> curdir = dirs.front(); dirs.pop(); if(files.empty() && (curdir.second > MAX_DEPTH)) { CL_DEBUG("Could not find compile_commands.json files while reaching depth 2, aborting"); break; } wxFileName fn(curdir.first, "compile_commands.json"); if(fn.Exists()) { CL_DEBUGS("CompilationDatabase: found file: " + fn.GetFullPath()); files.push_back(fn); } // Check to see if there are more directories to recurse wxDir dir; if(dir.Open(curdir.first)) { wxString dirname; bool cont = dir.GetFirst(&dirname, "", wxDIR_DIRS); while(cont) { wxString new_dir; new_dir << curdir.first << wxFileName::GetPathSeparator() << dirname; dirs.push(std::make_pair(new_dir, curdir.second + 1)); dirname.Clear(); cont = dir.GetNext(&dirname); } } } return files; }
FileNameVector_t CompilationDatabase::GetCompileCommandsFiles() const { wxFileName databaseFile(GetFileName()); wxFileName fn(databaseFile); // Usually it will be under the top folder fn.RemoveLastDir(); // Since we can have multiple "compile_commands.json" files, we take the most updated file // Prepare a list of files to check FileNameVector_t files; std::queue<wxString> dirs; // we start with the current path dirs.push(fn.GetPath()); while(!dirs.empty()) { wxString curdir = dirs.front(); dirs.pop(); wxFileName fn(curdir, "compile_commands.json"); if(fn.Exists() /*&& // file exists (fn.GetModificationTime().GetTicks() > databaseFile.GetModificationTime().GetTicks())*/) // and its newer than the database file { CL_DEBUGS("CompilationDatabase: found file: " + fn.GetFullPath()); files.push_back(fn); } // Check to see if there are more directories to recurse wxDir dir; if(dir.Open(curdir)) { wxString dirname; bool cont = dir.GetFirst(&dirname, "", wxDIR_DIRS); while(cont) { wxString new_dir; new_dir << curdir << wxFileName::GetPathSeparator() << dirname; dirs.push(new_dir); dirname.Clear(); cont = dir.GetNext(&dirname); } } } return files; }