* <<config_depend_mode,*depend_mode*>> is false.
* <<config_run_second_cpp,*run_second_cpp*>> is false.
* The compiler is not generating dependencies using `-MD` or `-MMD` (for MSVC,
- /showIncludes).
+ /showIncludes is added automatically if not specified by the user).
== Handling of newly created header files
void set_max_size(uint64_t value);
void set_run_second_cpp(bool value);
void set_temporary_dir(const std::string& value);
+ void set_msvc_dep_prefix(const std::string& value);
// Where to write configuration changes.
const std::string& config_path() const;
{
m_temporary_dir = value;
}
+
+inline void
+Config::set_msvc_dep_prefix(const std::string& value)
+{
+ m_msvc_dep_prefix = value;
+}
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);
}
}
+ 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,
Util::send_to_fd(
ctx, util::to_string_view(result->stderr_data), STDERR_FILENO);
Util::send_to_fd(
- ctx, util::to_string_view(result->stdout_data), STDOUT_FILENO);
+ ctx,
+ util::to_string_view(core::ShowIncludesParser::strip_includes(
+ ctx, std::move(result->stdout_data))),
+ STDOUT_FILENO);
auto failure = Failure(Statistic::compile_failed);
failure.set_exit_code(result->exit_status);
ctx, util::to_string_view(result->stderr_data), STDERR_FILENO);
// Send stdout after stderr, it makes the output clearer with MSVC.
Util::send_to_fd(
- ctx, util::to_string_view(result->stdout_data), STDOUT_FILENO);
+ ctx,
+ util::to_string_view(core::ShowIncludesParser::strip_includes(
+ ctx, std::move(result->stdout_data))),
+ STDOUT_FILENO);
return *result_key;
}
#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) {
- Util::send_to_fd(m_ctx, util::to_string_view(data), STDOUT_FILENO);
+ Util::send_to_fd(
+ m_ctx,
+ util::to_string_view(ShowIncludesParser::strip_includes(m_ctx, data)),
+ STDOUT_FILENO);
} else if (file_type == FileType::stderr_output) {
Util::send_to_fd(m_ctx, util::to_string_view(data), STDERR_FILENO);
} else {
return result;
}
+util::Bytes
+strip_includes(const Context& ctx, util::Bytes&& 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(util::to_string_view(stdout_data),
+ "\n",
+ Mode::include_empty,
+ IncludeDelimiter::yes)) {
+ if (!util::starts_with(line, ctx.config.msvc_dep_prefix())) {
+ new_stdout_text.append(line.data(), line.length());
+ }
+ }
+ return util::Bytes(new_stdout_text.data(), new_stdout_text.size());
+}
+
} // namespace core::ShowIncludesParser
#pragma once
+#include <util/Bytes.hpp>
+
#include <string_view>
#include <vector>
std::vector<std::string_view> tokenize(std::string_view file_content,
std::string_view prefix);
+util::Bytes strip_includes(const Context& ctx, util::Bytes&& stdout_data);
+
} // namespace core::ShowIncludesParser
// this program; if not, write to the Free Software Foundation, Inc., 51
// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#include "../src/Context.hpp"
#include "../src/core/ShowIncludesParser.hpp"
+#include "../src/util/string.hpp"
#include "TestUtil.hpp"
#include "third_party/doctest.h"
}
}
+TEST_CASE("ShowIncludesParser::strip_includes")
+{
+ Context ctx;
+ const util::Bytes input = util::to_span(
+ "First\n"
+ "Note: including file: foo\n"
+ "Second\n");
+
+ SUBCASE("empty output")
+ {
+ const util::Bytes result =
+ core::ShowIncludesParser::strip_includes(ctx, {});
+ CHECK(result.size() == 0);
+ }
+
+ SUBCASE("feature disabled")
+ {
+ const util::Bytes result =
+ core::ShowIncludesParser::strip_includes(ctx, util::Bytes(input));
+ CHECK(result == input);
+ }
+
+ ctx.auto_depend_mode = true;
+
+ SUBCASE("wrong compiler")
+ {
+ const util::Bytes result =
+ core::ShowIncludesParser::strip_includes(ctx, util::Bytes(input));
+ CHECK(result == input);
+ }
+
+ ctx.config.set_compiler_type(CompilerType::msvc);
+
+ SUBCASE("Simple output")
+ {
+ const util::Bytes result =
+ core::ShowIncludesParser::strip_includes(ctx, util::Bytes(input));
+ CHECK(result == util::to_span("First\nSecond\n"));
+ }
+
+ SUBCASE("Empty lines")
+ {
+ const util::Bytes result = core::ShowIncludesParser::strip_includes(
+ ctx,
+ util::to_span("First\n"
+ "\n"
+ "Note: including file: foo\n"
+ "\n"
+ "Second\n"
+ "\n"));
+ CHECK(result == util::to_span("First\n\n\nSecond\n\n"));
+ }
+
+ SUBCASE("CRLF")
+ {
+ const util::Bytes result = core::ShowIncludesParser::strip_includes(
+ ctx,
+ util::to_span("First\r\n"
+ "Note: including file: foo\r\n"
+ "Second\r\n"));
+ CHECK(result == util::to_span("First\r\nSecond\r\n"));
+ }
+
+ SUBCASE("Custom prefix")
+ {
+ ctx.config.set_msvc_dep_prefix("custom");
+ const util::Bytes result = core::ShowIncludesParser::strip_includes(
+ ctx,
+ util::to_span("First\n"
+ "custom: including file: foo\n"
+ "Second\n"
+ "Third custom line\n"));
+ CHECK(result == util::to_span("First\nSecond\nThird custom line\n"));
+ }
+}
+
TEST_SUITE_END();