blob: a23246e4d0a88c1d844b44e0b084be4836a69324 [file] [log] [blame]
// Copyright 2018 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gcc_compiler_type_specific.h"
#include "glog/logging.h"
#include "linker/linker_input_processor/linker_input_processor.h"
#include "linker/linker_input_processor/thinlto_import_processor.h"
#include "path.h"
namespace devtools_goma {
bool GCCCompilerTypeSpecific::RemoteCompileSupported(const string& trace_id,
const CompilerFlags& flags,
bool verify_output) const {
const GCCFlags& gcc_flag = static_cast<const GCCFlags&>(flags);
if (gcc_flag.is_stdin_input()) {
LOG(INFO) << trace_id << " force fallback."
<< " cannot use stdin as input in goma backend.";
return false;
}
if (gcc_flag.has_wrapper()) {
LOG(INFO) << trace_id << " force fallback. -wrapper is not supported";
return false;
}
if (!verify_output && gcc_flag.mode() == GCCFlags::PREPROCESS) {
LOG(INFO) << trace_id
<< " force fallback. preprocess is usually light-weight.";
return false;
}
if (!enable_gch_hack_ && gcc_flag.is_precompiling_header()) {
LOG(INFO) << trace_id
<< " force fallback. gch hack is not enabled and precompiling.";
return false;
}
if (!enable_remote_link_ && gcc_flag.is_linking()) {
LOG(INFO) << trace_id << " force fallback linking.";
return false;
}
if (!enable_remote_clang_modules_ && gcc_flag.has_fmodules()) {
LOG(INFO) << trace_id << " force fallback -fmodules";
return false;
}
absl::string_view ext = file::Extension(gcc_flag.input_filenames()[0]);
if (ext == "s" || ext == "S") {
LOG(INFO) << trace_id
<< " force fallback. assembler should be light-weight.";
return false;
}
return true;
}
std::unique_ptr<CompilerInfoData>
GCCCompilerTypeSpecific::BuildCompilerInfoData(
const CompilerFlags& flags,
const string& local_compiler_path,
const std::vector<string>& compiler_info_envs) {
return compiler_info_builder_.FillFromCompilerOutputs(
flags, local_compiler_path, compiler_info_envs);
}
CompilerTypeSpecific::IncludeProcessorResult
GCCCompilerTypeSpecific::RunIncludeProcessor(
const string& trace_id,
const CompilerFlags& compiler_flags,
const CompilerInfo& compiler_info,
const CommandSpec& command_spec,
FileStatCache* file_stat_cache) {
DCHECK_EQ(CompilerFlagType::Gcc, compiler_flags.type());
const GCCFlags& flags = static_cast<const GCCFlags&>(compiler_flags);
if (flags.lang() == "ir") {
if (flags.thinlto_index().empty()) {
// No need to to read .imports file. imports is nothing.
return IncludeProcessorResult::Ok(std::set<string>());
}
// Otherwise, run ThinLTOImports.
return RunThinLTOImports(trace_id, flags);
}
if (flags.args().size() == 2 && flags.args()[1] == "--version") {
// for requester_env_.verify_command()
VLOG(1) << trace_id << " --version";
return IncludeProcessorResult::Ok(std::set<string>());
}
// LINK mode.
if (flags.mode() == GCCFlags::LINK) {
return RunLinkIncludeProcessor(trace_id, flags, compiler_info,
command_spec);
}
// go into the usual path.
return CxxCompilerTypeSpecific::RunIncludeProcessor(
trace_id, compiler_flags, compiler_info, command_spec, file_stat_cache);
}
bool GCCCompilerTypeSpecific::SupportsDepsCache(
const CompilerFlags& flags) const {
const GCCFlags& gcc_flags = static_cast<const GCCFlags&>(flags);
return gcc_flags.mode() == GCCFlags::COMPILE;
}
CompilerTypeSpecific::IncludeProcessorResult
GCCCompilerTypeSpecific::RunThinLTOImports(const string& trace_id,
const GCCFlags& flags) {
ThinLTOImportProcessor processor;
std::set<string> required_files;
if (!processor.GetIncludeFiles(flags.thinlto_index(), flags.cwd(),
&required_files)) {
LOG(ERROR) << trace_id << " failed to get ThinLTO imports";
return IncludeProcessorResult::ErrorToLog("failed to get ThinLTO imports");
}
return IncludeProcessorResult::Ok(std::move(required_files));
}
CompilerTypeSpecific::IncludeProcessorResult
GCCCompilerTypeSpecific::RunLinkIncludeProcessor(
const string& trace_id,
const GCCFlags& flags,
const CompilerInfo& compiler_info,
const CommandSpec& command_spec) {
LinkerInputProcessor linker_input_processor(flags.args(), flags.cwd());
std::set<string> required_files;
std::vector<string> system_library_paths;
if (!linker_input_processor.GetInputFilesAndLibraryPath(
compiler_info, command_spec, &required_files,
&system_library_paths)) {
return IncludeProcessorResult::ErrorToLog("failed to get input files " +
flags.DebugString());
}
IncludeProcessorResult result =
IncludeProcessorResult::Ok(std::move(required_files));
result.system_library_paths = std::move(system_library_paths);
return result;
}
// static
bool GCCCompilerTypeSpecific::enable_gch_hack_;
// static
bool GCCCompilerTypeSpecific::enable_remote_link_;
// static
bool GCCCompilerTypeSpecific::enable_remote_clang_modules_;
} // namespace devtools_goma