// Is the compiler being asked to output dependencies?
bool generating_dependencies = false;
- // Is the compiler being asked to output includes (MSVC -showIncludes)?
- bool generating_includes = false;
-
// The dependency target in the dependency file (the object file unless
// overridden via e.g. -MT or -MQ).
std::optional<std::string> dependency_target;
log_file,
max_files,
max_size,
- msvc_dep_prefix,
namespace_,
path,
pch_external_checksum,
{"log_file", {ConfigItem::log_file}},
{"max_files", {ConfigItem::max_files}},
{"max_size", {ConfigItem::max_size}},
- {"msvc_dep_prefix", {ConfigItem::msvc_dep_prefix}},
{"namespace", {ConfigItem::namespace_}},
{"path", {ConfigItem::path}},
{"pch_external_checksum", {ConfigItem::pch_external_checksum}},
{"LOGFILE", "log_file"},
{"MAXFILES", "max_files"},
{"MAXSIZE", "max_size"},
- {"MSVC_DEP_PREFIX", "msvc_dep_prefix"},
{"NAMESPACE", "namespace"},
{"PATH", "path"},
{"PCH_EXTSUM", "pch_external_checksum"},
case ConfigItem::max_size:
return format_cache_size(m_max_size);
- case ConfigItem::msvc_dep_prefix:
- return m_msvc_dep_prefix;
-
case ConfigItem::namespace_:
return m_namespace;
m_max_size = Util::parse_size(value);
break;
- case ConfigItem::msvc_dep_prefix:
- m_msvc_dep_prefix = Util::expand_environment_variables(value);
- break;
-
case ConfigItem::namespace_:
m_namespace = Util::expand_environment_variables(value);
break;
const std::string& log_file() const;
uint64_t max_files() const;
uint64_t max_size() const;
- const std::string& msvc_dep_prefix() const;
const std::string& path() const;
bool pch_external_checksum() const;
const std::string& prefix_command() const;
std::string m_log_file;
uint64_t m_max_files = 0;
uint64_t m_max_size = 5ULL * 1000 * 1000 * 1000;
- std::string m_msvc_dep_prefix;
std::string m_path;
bool m_pch_external_checksum = false;
std::string m_prefix_command;
return m_max_size;
}
-inline const std::string&
-Config::msvc_dep_prefix() const
-{
- return m_msvc_dep_prefix;
-}
-
inline const std::string&
Config::path() const
{
std::unique_ptr<MiniTrace> mini_trace;
#endif
- bool auto_depend_mode = false;
-
// Register a temporary file to remove at program exit.
void register_pending_tmp_file(const std::string& path);
return Statistic::none;
}
- if (args[i] == "-showIncludes") {
- args_info.generating_includes = true;
- state.dep_args.push_back(args[i]);
- return Statistic::none;
- }
-
if (args[i] == "-fprofile-arcs") {
args_info.profile_arcs = true;
state.common_args.push_back(args[i]);
}
}
- if (ctx.config.depend_mode() && !args_info.generating_includes
- && ctx.config.compiler_type() == CompilerType::msvc) {
- ctx.auto_depend_mode = true;
- args_info.generating_includes = true;
- args_info.depend_extra_args.push_back("-showIncludes");
- }
-
return {
preprocessor_args,
extra_args_to_hash,
#include <core/Manifest.hpp>
#include <core/Result.hpp>
#include <core/ResultRetriever.hpp>
-#include <core/ShowIncludesParser.hpp>
#include <core/Statistics.hpp>
#include <core/StatsLog.hpp>
#include <core/exceptions.hpp>
std::string stderr_data;
};
-// Extract the used includes from -showIncludes output in stdout. Note that we
-// cannot distinguish system headers from other includes here.
-static std::optional<Digest>
-result_key_from_includes(Context& ctx,
- Hash& hash,
- const std::string& stdout_data)
-{
- for (std::string_view token : core::ShowIncludesParser::tokenize(
- stdout_data, ctx.config.msvc_dep_prefix())) {
- const std::string path = Util::make_relative_path(ctx, token);
- remember_include_file(ctx, path, hash, false, &hash);
- }
-
- // Explicitly check the .pch file as it is not mentioned in the
- // includes output.
- if (!ctx.args_info.included_pch_file.empty()) {
- std::string pch_path =
- Util::make_relative_path(ctx, ctx.args_info.included_pch_file);
- hash.hash(pch_path);
- remember_include_file(ctx, pch_path, hash, false, nullptr);
- }
-
- const bool debug_included = getenv("CCACHE_DEBUG_INCLUDED");
- if (debug_included) {
- print_included_files(ctx, stdout);
- }
-
- return hash.digest();
-}
-
// Execute the compiler/preprocessor, with logic to retry without requesting
// colored diagnostics messages if that fails.
static nonstd::expected<DoExecuteResult, Failure>
// We can output stderr immediately instead of rerunning the compiler.
Util::send_to_fd(ctx, result->stderr_data, STDERR_FILENO);
- Util::send_to_fd(ctx,
- core::ShowIncludesParser::strip_includes(
- ctx, std::move(result->stdout_data)),
- STDOUT_FILENO);
+ Util::send_to_fd(ctx, result->stdout_data, STDOUT_FILENO);
auto failure = Failure(Statistic::compile_failed);
failure.set_exit_code(result->exit_status);
if (ctx.config.depend_mode()) {
ASSERT(depend_mode_hash);
- if (ctx.args_info.generating_dependencies) {
- result_key = result_key_from_depfile(ctx, *depend_mode_hash);
- } else if (ctx.args_info.generating_includes) {
- result_key =
- result_key_from_includes(ctx, *depend_mode_hash, result->stdout_data);
- } else {
- ASSERT(false);
- }
+ result_key = result_key_from_depfile(ctx, *depend_mode_hash);
if (!result_key) {
return nonstd::make_unexpected(Statistic::internal_error);
}
// Everything OK.
Util::send_to_fd(ctx, result->stderr_data, STDERR_FILENO);
// Send stdout after stderr, it makes the output clearer with MSVC.
- Util::send_to_fd(ctx,
- core::ShowIncludesParser::strip_includes(
- ctx, std::move(result->stdout_data)),
- STDOUT_FILENO);
+ Util::send_to_fd(ctx, result->stdout_data, STDOUT_FILENO);
return *result_key;
}
ctx.config.set_run_second_cpp(true);
}
- if (ctx.config.depend_mode()) {
- const bool deps = ctx.args_info.generating_dependencies
- && ctx.args_info.output_dep != "/dev/null";
- const bool includes = ctx.args_info.generating_includes;
- if (!ctx.config.run_second_cpp() || (!deps && !includes)) {
- LOG_RAW("Disabling depend mode");
- ctx.config.set_depend_mode(false);
- }
+ if (ctx.config.depend_mode()
+ && (!ctx.args_info.generating_dependencies
+ || ctx.args_info.output_dep == "/dev/null"
+ || !ctx.config.run_second_cpp())) {
+ LOG_RAW("Disabling depend mode");
+ ctx.config.set_depend_mode(false);
}
if (ctx.storage.has_remote_storage()) {
ResultExtractor.cpp
ResultInspector.cpp
ResultRetriever.cpp
- ShowIncludesParser.cpp
Statistics.cpp
StatisticsCounters.cpp
StatsLog.cpp
#include <Context.hpp>
#include <Stat.hpp>
-#include <core/ShowIncludesParser.hpp>
#include <core/exceptions.hpp>
#include <core/wincompat.hpp>
#include <fmtmacros.hpp>
data.size());
if (file_type == FileType::stdout_output) {
- std::string str = util::to_string(util::to_string_view(data));
- Util::send_to_fd(m_ctx,
- ShowIncludesParser::strip_includes(m_ctx, std::move(str)),
- STDOUT_FILENO);
+ Util::send_to_fd(m_ctx, util::to_string_view(data), STDOUT_FILENO);
} else if (file_type == FileType::stderr_output) {
Util::send_to_fd(m_ctx, util::to_string_view(data), STDERR_FILENO);
} else {
+++ /dev/null
-// Copyright (C) 2022 Joel Rosdahl and other contributors
-//
-// See doc/AUTHORS.adoc for a complete list of contributors.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// this program; if not, write to the Free Software Foundation, Inc., 51
-// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-#include "ShowIncludesParser.hpp"
-
-#include <Context.hpp>
-#include <Util.hpp>
-#include <util/string.hpp>
-
-namespace core::ShowIncludesParser {
-
-std::vector<std::string_view>
-tokenize(std::string_view file_content, std::string_view prefix)
-{
- // -showIncludes output is written to stdout together with other messages.
- // Every line of it is '<prefix> <spaces> <file>', prefix is 'Note: including
- // file:' in English but can be localized.
-
- if (prefix.empty()) {
- prefix = "Note: including file:";
- }
-
- std::vector<std::string_view> result;
- // This will split at each \r or \n, but that simply means there will be empty
- // "lines".
- for (std::string_view line : Util::split_into_views(file_content, "\r\n")) {
- if (util::starts_with(line, prefix)) {
- size_t pos = prefix.size();
- while (pos < line.size() && isspace(line[pos])) {
- ++pos;
- }
- std::string_view include = line.substr(pos);
- if (!include.empty()) {
- result.push_back(include);
- }
- }
- }
- return result;
-}
-
-std::string
-strip_includes(const Context& ctx, std::string&& stdout_data)
-{
- using util::Tokenizer;
- using Mode = Tokenizer::Mode;
- using IncludeDelimiter = Tokenizer::IncludeDelimiter;
-
- if (stdout_data.empty() || !ctx.auto_depend_mode
- || ctx.config.compiler_type() != CompilerType::msvc) {
- return std::move(stdout_data);
- }
-
- std::string new_stdout_text;
- for (const auto line : Tokenizer(
- stdout_data, "\n", Mode::include_empty, IncludeDelimiter::yes)) {
- if (!util::starts_with(line, "Note: including file:")) {
- new_stdout_text.append(line.data(), line.length());
- }
- }
- return new_stdout_text;
-}
-
-} // namespace core::ShowIncludesParser
+++ /dev/null
-// Copyright (C) 2022 Joel Rosdahl and other contributors
-//
-// See doc/AUTHORS.adoc for a complete list of contributors.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along with
-// this program; if not, write to the Free Software Foundation, Inc., 51
-// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-#pragma once
-
-#include <string_view>
-#include <vector>
-
-class Context;
-
-namespace core::ShowIncludesParser {
-
-std::vector<std::string_view> tokenize(std::string_view file_content,
- std::string_view prefix);
-
-std::string strip_includes(const Context& ctx, std::string&& stdout_data);
-
-} // namespace core::ShowIncludesParser
CHECK(config.log_file().empty());
CHECK(config.max_files() == 0);
CHECK(config.max_size() == static_cast<uint64_t>(5) * 1000 * 1000 * 1000);
- CHECK(config.msvc_dep_prefix().empty());
CHECK(config.path().empty());
CHECK_FALSE(config.pch_external_checksum());
CHECK(config.prefix_command().empty());
"log_file = $USER${USER} \n"
"max_files = 17\n"
"max_size = 123M\n"
- "msvc_dep_prefix = Note: including file:\n"
"path = $USER.x\n"
"pch_external_checksum = true\n"
"prefix_command = x$USER\n"
CHECK(config.log_file() == FMT("{0}{0}", user));
CHECK(config.max_files() == 17);
CHECK(config.max_size() == 123 * 1000 * 1000);
- CHECK(config.msvc_dep_prefix() == "Note: including file:");
CHECK(config.path() == FMT("{}.x", user));
CHECK(config.pch_external_checksum());
CHECK(config.prefix_command() == FMT("x{}", user));
"log_file = lf\n"
"max_files = 4711\n"
"max_size = 98.7M\n"
- "msvc_dep_prefix = mdp\n"
"namespace = ns\n"
"path = p\n"
"pch_external_checksum = true\n"
"(test.conf) log_file = lf",
"(test.conf) max_files = 4711",
"(test.conf) max_size = 98.7M",
- "(test.conf) msvc_dep_prefix = mdp",
"(test.conf) namespace = ns",
"(test.conf) path = p",
"(test.conf) pch_external_checksum = true",