diff --git a/src/command_line.cc b/src/command_line.cc index d032fef4..05b45650 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -501,7 +501,7 @@ struct Index_DoIdMap { perf(perf), is_interactive(is_interactive), write_to_disk(write_to_disk) { - assert(this->current); + assert(this->current); } }; @@ -1367,6 +1367,19 @@ bool QueryDbMainLoop(Config* config, EnsureEndsInSlash(config->cacheDirectory); MakeDirectoryRecursive(config->cacheDirectory); + // Ensure there is a resource directory. + if (config->resourceDirectory.empty()) { + config->resourceDirectory = GetWorkingDirectory(); +#if defined(_WIN32) + config->resourceDirectory += + std::string("../../clang_resource_dir/"); +#else + config->resourceDirectory += std::string("../clang_resource_dir/"); +#endif + } + config->resourceDirectory = NormalizePath(config->resourceDirectory); + LOG_S(INFO) << "Using -resource-dir=" << config->resourceDirectory; + // Set project root. config->projectRoot = NormalizePath(request->params.rootUri->GetPath()); @@ -1391,7 +1404,8 @@ bool QueryDbMainLoop(Config* config, Timer time; // Open up / load the project. - project->Load(config->extraClangArguments, project_path); + project->Load(config->extraClangArguments, project_path, + config->resourceDirectory); time.ResetAndPrint("[perf] Loaded compilation entries (" + std::to_string(project->entries.size()) + " files)"); diff --git a/src/config.h b/src/config.h index b0024c11..efbc046f 100644 --- a/src/config.h +++ b/src/config.h @@ -9,6 +9,9 @@ struct Config { std::string projectRoot; // Cache directory for indexed files. std::string cacheDirectory; + // Value to use for clang -resource-dir if not present in + // compile_commands.json. + std::string resourceDirectory; std::vector extraClangArguments; @@ -64,6 +67,7 @@ struct Config { }; MAKE_REFLECT_STRUCT(Config, cacheDirectory, + resourceDirectory, extraClangArguments, diff --git a/src/platform_win.cc b/src/platform_win.cc index ad44aaca..f62c1032 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -10,11 +10,9 @@ #include #include - #include #include - #include #include #include @@ -132,7 +130,8 @@ void PlatformInit() { // See http://stackoverflow.com/a/19535628 std::string GetWorkingDirectory() { char result[MAX_PATH]; - return std::string(result, GetModuleFileName(NULL, result, MAX_PATH)); + std::string binary_path(result, GetModuleFileName(NULL, result, MAX_PATH)); + return binary_path.substr(0, binary_path.find_last_of("\\/") + 1); } std::string NormalizePath(const std::string& path) { diff --git a/src/project.cc b/src/project.cc index 5ddee19d..6379df46 100644 --- a/src/project.cc +++ b/src/project.cc @@ -40,6 +40,7 @@ struct ProjectConfig { std::unordered_set angle_dirs; std::vector extra_flags; std::string project_dir; + std::string resource_dir; }; // TODO: See @@ -185,9 +186,10 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( result.args.push_back("-std=c++11"); } - // TODO: Add - // "-resource-dir=/home/jdufault/.vim/bundle/YouCompleteMe/third_party/ycmd/ycmd/../clang_includes", - // we can extract this from build dir. + // Add -resource-dir so clang can correctly resolve system includes like + // + if (!AnyStartsWith(result.args, "-resource-dir")) + result.args.push_back("-resource-dir=" + config->resource_dir); return result; } @@ -312,11 +314,13 @@ int ComputeGuessScore(const std::string& a, const std::string& b) { } // namespace void Project::Load(const std::vector& extra_flags, - const std::string& directory) { + const std::string& directory, + const std::string& resource_directory) { // Load data. ProjectConfig config; config.extra_flags = extra_flags; config.project_dir = directory; + config.resource_dir = resource_directory; entries = LoadCompilationEntriesFromDirectory(&config); // Cleanup / postprocess include directories. @@ -393,6 +397,7 @@ void CheckFlags(const std::string& directory, ProjectConfig config; config.project_dir = "/w/c/s/"; + config.resource_dir = "/w/resource_dir/"; CompileCommandsEntry entry; entry.directory = directory; @@ -424,13 +429,16 @@ void CheckFlags(std::vector raw, TEST_CASE("strip meta-compiler invocations") { CheckFlags( /* raw */ {"clang", "-lstdc++", "myfile.cc"}, - /* expected */ {"clang", "-lstdc++", "myfile.cc", "-xc++", "-std=c++11"}); + /* expected */ {"clang", "-lstdc++", "myfile.cc", "-xc++", "-std=c++11", + "-resource-dir=/w/resource_dir/"}); CheckFlags(/* raw */ {"goma", "clang"}, - /* expected */ {"clang", "-xc++", "-std=c++11"}); + /* expected */ {"clang", "-xc++", "-std=c++11", + "-resource-dir=/w/resource_dir/"}); CheckFlags(/* raw */ {"goma", "clang", "--foo"}, - /* expected */ {"clang", "--foo", "-xc++", "-std=c++11"}); + /* expected */ {"clang", "--foo", "-xc++", "-std=c++11", + "-resource-dir=/w/resource_dir/"}); } // Checks flag parsing for a random chromium file in comparison to what @@ -773,7 +781,8 @@ TEST_CASE("ycm") { "debian_jessie_amd64-sysroot", "-fno-exceptions", "-fvisibility-inlines-hidden", - "-xc++"}); + "-xc++", + "-resource-dir=/w/resource_dir/"}); } // Checks flag parsing for an example chromium file. @@ -1090,7 +1099,8 @@ TEST_CASE("chromium") { "debian_jessie_amd64-sysroot", "-fno-exceptions", "-fvisibility-inlines-hidden", - "-xc++"}); + "-xc++", + "-resource-dir=/w/resource_dir/"}); } TEST_CASE("Directory extraction") { diff --git a/src/project.h b/src/project.h index ce568f89..b74df809 100644 --- a/src/project.h +++ b/src/project.h @@ -36,7 +36,8 @@ struct Project { // all *.cpp, *.cc, *.h, and *.hpp files will be used. clang arguments can be // specified in a clang_args file located inside of |directory|. void Load(const std::vector& extra_flags, - const std::string& directory); + const std::string& directory, + const std::string& resource_directory); // Lookup the CompilationEntry for |filename|. If no entry was found this // will infer one based on existing project structure.