Error when passing multiple input files with --output (#6896)

Fixes #6895

Note this is just a short-term fix to avoid confusion, as the compile
structure needs to change on the whole.

Assisted-by: Google Antigravity with Gemini
This commit is contained in:
Jon Ross-Perkins
2026-03-13 16:07:12 +00:00
committed by GitHub
parent ffe8f8f67d
commit 6706162582
8 changed files with 55 additions and 11 deletions
+1 -1
View File
@@ -89,7 +89,7 @@ def _carbon_binary_impl(ctx):
inputs = depset(direct = srcs_reordered, transitive = dep_hdrs),
executable = toolchain_driver,
tools = depset(toolchain_data),
arguments = ["compile", "--output=" + out.path] +
arguments = ["compile", "--output=" + out.path, "--output-last-input-only"] +
[s.path for s in srcs_reordered] + extra_flags + ctx.attr.flags,
mnemonic = "CarbonCompile",
progress_message = "Compiling " + src.short_path,
+1 -1
View File
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
// EXTRA-ARGS: --target=x86_64-unknown-linux-gnu --output=%t
// EXTRA-ARGS: --output-last-input-only --target=x86_64-unknown-linux-gnu --output=%t
//
// TODO: Add a way to write some basic tests for object file outputs.
// AUTOUPDATE
+1
View File
@@ -28,6 +28,7 @@ CARBON_DIAGNOSTIC_KIND(DriverCommandLineParseFailed)
CARBON_DIAGNOSTIC_KIND(CompilePhaseFlagConflict)
CARBON_DIAGNOSTIC_KIND(CompilePreludeManifestError)
CARBON_DIAGNOSTIC_KIND(CompileInputNotRegularFile)
CARBON_DIAGNOSTIC_KIND(CompileMultipleInputsWithOutput)
CARBON_DIAGNOSTIC_KIND(CompileOutputFileOpenError)
CARBON_DIAGNOSTIC_KIND(CompileTargetInvalid)
CARBON_DIAGNOSTIC_KIND(ConfigFailedToReadDigest)
+1
View File
@@ -215,6 +215,7 @@ cc_library(
"//toolchain/check",
"//toolchain/codegen",
"//toolchain/diagnostics:emitter",
"//toolchain/diagnostics:format_providers",
"//toolchain/diagnostics:sorting_consumer",
"//toolchain/format",
"//toolchain/language_server",
+33 -8
View File
@@ -24,6 +24,7 @@
#include "toolchain/check/check.h"
#include "toolchain/codegen/codegen.h"
#include "toolchain/diagnostics/emitter.h"
#include "toolchain/diagnostics/format_providers.h"
#include "toolchain/diagnostics/sorting_consumer.h"
#include "toolchain/lex/lex.h"
#include "toolchain/lower/lower.h"
@@ -358,6 +359,17 @@ Whether to emit DWARF debug information.
arg_b.Default(true);
arg_b.Set(&include_debug_info);
});
b.AddFlag(
{
.name = "output-last-input-only",
.help = R"""(
Only write output for the last input file, ignoring all others.
TODO: This is a temporary workaround and should be removed once separate
compilation is better implemented.
)""",
},
[&](auto& arg_b) { arg_b.Set(&output_last_input_only); });
b.AddFlag(
{
.name = "verify-llvm-ir",
@@ -1028,11 +1040,8 @@ auto CompilationUnit::RunCodeGenHelper() -> bool {
llvm::sys::path::replace_extension(output_filename,
options_->asm_output ? ".s" : ".o");
} else {
// TODO: Handle the case where multiple input files were specified
// along with an output file name. That should either be an error or
// should produce a single LLVM IR module containing all inputs.
// Currently each unit overwrites the output from the previous one in
// this case.
CARBON_CHECK(total_ir_count_ == 1 || options_->output_last_input_only,
"Handled by CompileMultipleInputsWithOutput diagnostic");
}
CARBON_VLOG("Writing output to: {0}\n", output_filename);
@@ -1156,9 +1165,21 @@ auto CompileSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
}
}
int total_unit_count = prelude.size() + options_.input_filenames.size();
if (!options_.output_last_input_only && total_unit_count > 1 &&
!options_.output_filename.empty() && options_.output_filename != "-") {
CARBON_DIAGNOSTIC(
CompileMultipleInputsWithOutput, Error,
"writing {0} input file{0:s} to the same `--output` file would "
"overwrite the output file; for now, pass `--output-last-input-only` "
"if intended",
Diagnostics::IntAsSelect);
driver_env.emitter.Emit(CompileMultipleInputsWithOutput, total_unit_count);
return {.success = false};
}
// Prepare CompilationUnits before building scope exit handlers.
llvm::SmallVector<std::unique_ptr<CompilationUnit>> units;
int total_unit_count = prelude.size() + options_.input_filenames.size();
int unit_index = -1;
auto unit_builder = [&](llvm::StringRef filename) {
++unit_index;
@@ -1310,8 +1331,12 @@ auto CompileSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
"CodeGen should be the last stage");
// Codegen.
for (auto& unit : units) {
unit->RunCodeGen();
if (options_.output_last_input_only) {
units.back()->RunCodeGen();
} else {
for (const auto& unit : units) {
unit->RunCodeGen();
}
}
return make_result();
}
+1
View File
@@ -65,6 +65,7 @@ struct CompileOptions {
bool builtin_sem_ir = false;
bool prelude_import = false;
bool include_debug_info = true;
bool output_last_input_only = false;
bool run_llvm_verifier = true;
llvm::SmallVector<llvm::StringRef> exclude_dump_file_prefixes;
@@ -0,0 +1,16 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// Exclude the prelude import so that the number of prelude files isn't tested.
// ARGS: --include-diagnostic-kind compile --output=foo.o --no-prelude-import foo.carbon bar.carbon
//
// SET-CAPTURE-CONSOLE-OUTPUT
// clang-format off
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/driver/testdata/fail_multi_input_with_output.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/driver/testdata/fail_multi_input_with_output.carbon
// CHECK:STDERR: error: writing 2 input files to the same `--output` file would overwrite the output file; for now, pass `--output-last-input-only` if intended [CompileMultipleInputsWithOutput]
// CHECK:STDERR:
+1 -1
View File
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
// ARGS: -v compile --phase=codegen --target=x86_64-unknown-linux-gnu --output=%t %s
// ARGS: -v compile --phase=codegen --target=x86_64-unknown-linux-gnu --output=%t --output-last-input-only %s
//
// Verifies that various phases are included in vlog output.
//