mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Teach the link subcommand to accept Clang-style LDFLAGS (#6741)
Add an optional additional set of positional parameters that can be passed to the `link` subcommand for Clang-style (or GCC-style) `LDFLAGS`. These can _also_ contain object files, etc., and in fact it is useful to allow them to contain object files in order to integrate the `carbon link` subcommand into a build system that mixes both link flags and object files. This at least happens with Bazel, and I suspect is common. Eventually, it would be nice to have sufficient semantics to handle all the varieties of links we want without resorting to this escape hatch, but that's likely a long way away and so it seems especially useful to allow falling back to Clang's flags as needed for now. This does somewhat directly surface the Clang implementation detail in the command line syntax, but I don't see a lot of good alternatives. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
46fb941b3c
commit
e00394ea92
@@ -15,12 +15,12 @@ auto LinkOptions::Build(CommandLine::CommandBuilder& b) -> void {
|
||||
.name = "OBJECT_FILE",
|
||||
.help = R"""(
|
||||
The input object files.
|
||||
|
||||
If empty, there must be extra Clang link arguments that provide object files
|
||||
intermingled with linking flags.
|
||||
)""",
|
||||
},
|
||||
[&](auto& arg_b) {
|
||||
arg_b.Required(true);
|
||||
arg_b.Append(&object_filenames);
|
||||
});
|
||||
[&](auto& arg_b) { arg_b.Append(&object_filenames); });
|
||||
|
||||
b.AddStringOption(
|
||||
{
|
||||
@@ -28,12 +28,28 @@ The input object files.
|
||||
.value_name = "FILE",
|
||||
.help = R"""(
|
||||
The linked file name. The output is always a linked binary.
|
||||
|
||||
If not provided, there must be extra Clang link arguments that include
|
||||
specifying the output of the link. This allows supporting build systems that
|
||||
intermingle the output flag with arbitrary other linker flags that need to use
|
||||
legacy parsing logic.
|
||||
)""",
|
||||
},
|
||||
[&](auto& arg_b) {
|
||||
arg_b.Required(true);
|
||||
arg_b.Set(&output_filename);
|
||||
});
|
||||
[&](auto& arg_b) { arg_b.Set(&output_filename); });
|
||||
|
||||
b.AddStringPositionalArg(
|
||||
{
|
||||
.name = "EXTRA_CLANG_LINK_ARGS",
|
||||
.help = R"""(
|
||||
Extra arguments to pass to Clang when forming the link command. This is
|
||||
primarily useful for expanding `LDFLAGS` or other baseline linking flags in a
|
||||
build system.
|
||||
|
||||
These can also be used to pass object files to the link in the event your build
|
||||
system mixes object files and linker flags.
|
||||
)""",
|
||||
},
|
||||
[&](auto& arg_b) { arg_b.Append(&extra_clang_args); });
|
||||
|
||||
codegen_options.Build(b);
|
||||
}
|
||||
@@ -69,8 +85,33 @@ auto LinkSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
|
||||
llvm::formatv("--target={0}", options_.codegen_options.target).str();
|
||||
clang_args.push_back(target_arg);
|
||||
|
||||
clang_args.push_back("-o");
|
||||
clang_args.push_back(options_.output_filename);
|
||||
if (!options_.output_filename.empty()) {
|
||||
clang_args.push_back("-o");
|
||||
clang_args.push_back(options_.output_filename);
|
||||
} else if (options_.extra_clang_args.empty()) {
|
||||
CARBON_DIAGNOSTIC(LinkOutputOptionMissing, Error,
|
||||
"no output specified to a link command and no extra "
|
||||
"Clang options that can provide an output");
|
||||
driver_env.emitter.Emit(LinkOutputOptionMissing);
|
||||
return {.success = false};
|
||||
}
|
||||
|
||||
if (options_.object_filenames.empty() && options_.extra_clang_args.empty()) {
|
||||
CARBON_DIAGNOSTIC(LinkObjectFilesMissing, Error,
|
||||
"no object files provided to link command and no extra "
|
||||
"Clang options that could provide them");
|
||||
driver_env.emitter.Emit(LinkObjectFilesMissing);
|
||||
return {.success = false};
|
||||
}
|
||||
|
||||
// Note that we append any extra Clang args before our object filenames. This
|
||||
// allows us to propagate object filenames that collide with Clang flags using
|
||||
// `--` before the filenames. While in theory, this could create a problem in
|
||||
// the presence of mixtures of object files in the two lists and the order
|
||||
// being dependent, we don't expect that in practice.
|
||||
clang_args.append(options_.extra_clang_args.begin(),
|
||||
options_.extra_clang_args.end());
|
||||
clang_args.push_back("--");
|
||||
clang_args.append(options_.object_filenames.begin(),
|
||||
options_.object_filenames.end());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user