void ClangCodeCompletion::OnBuildStarting(clBuildEvent& e) { e.Skip(); CHECK_CLANG_ENABLED_RET(); // Determine the compilation database CompilationDatabase cdb; cdb.Open(); cdb.Close(); // Set the compilation database environment variable ::wxSetEnv(wxT("CL_COMPILATION_DB"), cdb.GetFileName().GetFullPath()); // If this is NOT a custom project, set the CXX and CC environment wxString project = e.GetProjectName(); wxString config = e.GetConfigurationName(); BuildConfigPtr bldConf = WorkspaceST::Get()->GetProjBuildConf(project, config); if( bldConf && !bldConf->IsCustomBuild()) { wxString cxx = bldConf->GetCompiler()->GetTool(wxT("CXX")); wxString cc = bldConf->GetCompiler()->GetTool(wxT("CC")); cxx.Prepend(wxT("codelitegcc ")); cc.Prepend(wxT("codelitegcc ")); ::wxSetEnv("CXX", cxx); ::wxSetEnv("CC" , cc); } }
FileTypeCmpArgs_t ClangDriver::DoPrepareCompilationArgs(const wxString& projectName, const wxString& sourceFile, wxString& projectPath, wxString& pchfile) { FileTypeCmpArgs_t cmpArgs; cmpArgs.insert(std::make_pair(FileExtManager::TypeSourceC, wxArrayString())); cmpArgs.insert(std::make_pair(FileExtManager::TypeSourceCpp, wxArrayString())); wxArrayString args; wxString errMsg; wxArrayString& cppCompileArgs = cmpArgs[FileExtManager::TypeSourceCpp]; wxArrayString& cCompileArgs = cmpArgs[FileExtManager::TypeSourceC]; // Build the TU file name wxFileName fnSourceFile(sourceFile); pchfile << WorkspaceST::Get()->GetWorkspaceFileName().GetPath() << wxFileName::GetPathSeparator() << wxT(".clang"); { wxLogNull nl; wxMkdir(pchfile); } pchfile << wxFileName::GetPathSeparator() << fnSourceFile.GetFullName() << wxT(".TU"); CompilationDatabase cdb; static bool once = false; if(!cdb.IsOk() && !once) { once = true; wxString msg; msg << _("Could not locate compilation database or database version is not up-to-date: ") << cdb.GetFileName().GetFullPath() << wxT("\n\n") << _("This file should be created automatically for you.\nIf you don't have it, please run a full rebuild " "of your workspace\n\n") << _("If this is a custom build project (i.e. project that uses a custom makefile),\nplease set the CXX " "and CC environment variables like this:\n") << _("CXX=codelite-cc g++\n") << _("CC=codelite-cc gcc\n\n"); clMainFrame::Get()->GetMainBook()->ShowMessage( msg, true, PluginManager::Get()->GetStdIcons()->LoadBitmap(wxT("messages/48/tip")), ButtonDetails(), ButtonDetails(), ButtonDetails(), CheckboxDetails(wxT("CodeCompletionMissingCompilationDB"))); } else { cdb.Open(); if(cdb.IsOpened()) { CL_DEBUG(wxT("Loading compilation flags for file: %s"), fnSourceFile.GetFullPath().c_str()); wxString compilationLine, cwd; cdb.CompilationLine(fnSourceFile.GetFullPath(), compilationLine, cwd); cdb.Close(); CompilerCommandLineParser cclp(compilationLine, cwd); cclp.MakeAbsolute(cwd); CL_DEBUG(wxT("Loaded compilation flags: %s"), compilationLine.c_str()); args.insert(args.end(), cclp.GetIncludesWithPrefix().begin(), cclp.GetIncludesWithPrefix().end()); args.insert(args.end(), cclp.GetMacrosWithPrefix().begin(), cclp.GetMacrosWithPrefix().end()); args.Add(cclp.GetStandardWithPrefix()); } } const TagsOptionsData& options = TagsManagerST::Get()->GetCtagsOptions(); /////////////////////////////////////////////////////////////////////// // add global clang include paths wxString strGlobalIncludes = options.GetClangSearchPaths(); // expand any macros from the include paths strGlobalIncludes = MacroManager::Instance()->Expand(strGlobalIncludes, PluginManager::Get(), projectName); wxArrayString globalIncludes = wxStringTokenize(strGlobalIncludes, wxT("\n\r"), wxTOKEN_STRTOK); for(size_t i = 0; i < globalIncludes.GetCount(); i++) { wxFileName fn(globalIncludes.Item(i).Trim().Trim(false), wxT("")); fn.MakeAbsolute(projectPath); cppCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str())); cCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str())); } /////////////////////////////////////////////////////////////////////// // Workspace setting additional flags /////////////////////////////////////////////////////////////////////// // Include paths wxArrayString workspaceIncls, dummy; LocalWorkspaceST::Get()->GetParserPaths(workspaceIncls, dummy); for(size_t i = 0; i < workspaceIncls.GetCount(); i++) { wxFileName fn(workspaceIncls.Item(i).Trim().Trim(false), wxT("")); fn.MakeAbsolute(WorkspaceST::Get()->GetWorkspaceFileName().GetPath()); cppCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str())); cCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str())); } // Macros wxString strWorkspaceMacros; LocalWorkspaceST::Get()->GetParserMacros(strWorkspaceMacros); wxArrayString workspaceMacros = wxStringTokenize(strWorkspaceMacros, wxT("\n\r"), wxTOKEN_STRTOK); for(size_t i = 0; i < workspaceMacros.GetCount(); i++) { cppCompileArgs.Add(wxString::Format(wxT("-D%s"), workspaceMacros.Item(i).Trim().Trim(false).c_str())); cCompileArgs.Add(wxString::Format(wxT("-D%s"), workspaceMacros.Item(i).Trim().Trim(false).c_str())); } // C++ 11 / 14 size_t workspaceFlags = LocalWorkspaceST::Get()->GetParserFlags(); if(workspaceFlags & LocalWorkspace::EnableCpp11) { cppCompileArgs.Add(wxT("-std=c++11")); cCompileArgs.Add(wxT("-std=c++11")); } if(workspaceFlags & LocalWorkspace::EnableCpp14) { cppCompileArgs.Add(wxT("-std=c++14")); cCompileArgs.Add(wxT("-std=c++14")); } /////////////////////////////////////////////////////////////////////// // Project setting additional flags /////////////////////////////////////////////////////////////////////// BuildConfigPtr buildConf = ManagerST::Get()->GetCurrentBuildConf(); if(buildConf) { wxString projSearchPaths = buildConf->GetCcSearchPaths(); wxArrayString projectIncludePaths = wxStringTokenize(projSearchPaths, wxT("\r\n"), wxTOKEN_STRTOK); for(size_t i = 0; i < projectIncludePaths.GetCount(); i++) { wxFileName fn(MacroManager::Instance() ->Expand(projectIncludePaths.Item(i), PluginManager::Get(), ManagerST::Get()->GetActiveProjectName()), wxT("")); fn.MakeAbsolute(WorkspaceST::Get()->GetWorkspaceFileName().GetPath()); cppCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str())); cCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str())); } wxString strProjectMacros = buildConf->GetClangPPFlags(); wxArrayString projectMacros = wxStringTokenize(strProjectMacros, wxT("\n\r"), wxTOKEN_STRTOK); for(size_t i = 0; i < projectMacros.GetCount(); i++) { cppCompileArgs.Add(wxString::Format(wxT("-D%s"), projectMacros.Item(i).Trim().Trim(false).c_str())); cCompileArgs.Add(wxString::Format(wxT("-D%s"), projectMacros.Item(i).Trim().Trim(false).c_str())); } if(buildConf->IsClangC11()) { cppCompileArgs.Add(wxT("-std=c++11")); cCompileArgs.Add(wxT("-std=c++11")); } if(buildConf->IsClangC14()) { cppCompileArgs.Add(wxT("-std=c++14")); cCompileArgs.Add(wxT("-std=c++14")); } } cppCompileArgs.insert(cppCompileArgs.end(), args.begin(), args.end()); cCompileArgs.insert(cCompileArgs.end(), args.begin(), args.end()); // Remove some of the flags which are known to cause problems to clang int where = wxNOT_FOUND; where = cppCompileArgs.Index(wxT("-fno-strict-aliasing")); if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where); where = cppCompileArgs.Index(wxT("-mthreads")); if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where); where = cppCompileArgs.Index(wxT("-pipe")); if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where); where = cppCompileArgs.Index(wxT("-fmessage-length=0")); if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where); where = cppCompileArgs.Index(wxT("-fPIC")); if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where); // Now do the same for the "C" arguments where = cCompileArgs.Index(wxT("-fno-strict-aliasing")); if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where); where = cCompileArgs.Index(wxT("-mthreads")); if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where); where = cCompileArgs.Index(wxT("-pipe")); if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where); where = cCompileArgs.Index(wxT("-fmessage-length=0")); if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where); where = cCompileArgs.Index(wxT("-fPIC")); if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where); return cmpArgs; }