124 lines
3.9 KiB
C++
124 lines
3.9 KiB
C++
//===-- Options.cpp -------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Options.h"
|
|
#include "clang/Driver/Driver.h"
|
|
#include "clang/Frontend/FrontendDiagnostic.h"
|
|
#include "llvm/Support/Program.h"
|
|
#include "llvm/TargetParser/Host.h"
|
|
|
|
using namespace clang::driver;
|
|
using namespace clang::driver::options;
|
|
using namespace llvm::opt;
|
|
using namespace llvm::MachO;
|
|
|
|
namespace clang {
|
|
namespace installapi {
|
|
|
|
bool Options::processDriverOptions(InputArgList &Args) {
|
|
// Handle inputs.
|
|
llvm::append_range(DriverOpts.FileLists, Args.getAllArgValues(OPT_INPUT));
|
|
|
|
// Handle output.
|
|
SmallString<PATH_MAX> OutputPath;
|
|
if (auto *Arg = Args.getLastArg(OPT_o)) {
|
|
OutputPath = Arg->getValue();
|
|
if (OutputPath != "-")
|
|
FM->makeAbsolutePath(OutputPath);
|
|
DriverOpts.OutputPath = std::string(OutputPath);
|
|
}
|
|
|
|
// Do basic error checking first for mixing -target and -arch options.
|
|
auto *ArgArch = Args.getLastArgNoClaim(OPT_arch);
|
|
auto *ArgTarget = Args.getLastArgNoClaim(OPT_target);
|
|
auto *ArgTargetVariant =
|
|
Args.getLastArgNoClaim(OPT_darwin_target_variant_triple);
|
|
if (ArgArch && (ArgTarget || ArgTargetVariant)) {
|
|
Diags->Report(clang::diag::err_drv_argument_not_allowed_with)
|
|
<< ArgArch->getAsString(Args)
|
|
<< (ArgTarget ? ArgTarget : ArgTargetVariant)->getAsString(Args);
|
|
return false;
|
|
}
|
|
|
|
auto *ArgMinTargetOS = Args.getLastArgNoClaim(OPT_mtargetos_EQ);
|
|
if ((ArgTarget || ArgTargetVariant) && ArgMinTargetOS) {
|
|
Diags->Report(clang::diag::err_drv_cannot_mix_options)
|
|
<< ArgTarget->getAsString(Args) << ArgMinTargetOS->getAsString(Args);
|
|
return false;
|
|
}
|
|
|
|
// Capture target triples first.
|
|
if (ArgTarget) {
|
|
for (const Arg *A : Args.filtered(OPT_target)) {
|
|
A->claim();
|
|
llvm::Triple TargetTriple(A->getValue());
|
|
Target TAPITarget = Target(TargetTriple);
|
|
if ((TAPITarget.Arch == AK_unknown) ||
|
|
(TAPITarget.Platform == PLATFORM_UNKNOWN)) {
|
|
Diags->Report(clang::diag::err_drv_unsupported_opt_for_target)
|
|
<< "installapi" << TargetTriple.str();
|
|
return false;
|
|
}
|
|
DriverOpts.Targets[TAPITarget] = TargetTriple;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Options::processLinkerOptions(InputArgList &Args) {
|
|
// TODO: add error handling.
|
|
|
|
// Required arguments.
|
|
if (const Arg *A = Args.getLastArg(options::OPT_install__name))
|
|
LinkerOpts.InstallName = A->getValue();
|
|
|
|
// Defaulted or optional arguments.
|
|
if (auto *Arg = Args.getLastArg(OPT_current__version))
|
|
LinkerOpts.CurrentVersion.parse64(Arg->getValue());
|
|
|
|
LinkerOpts.IsDylib = Args.hasArg(OPT_dynamiclib);
|
|
|
|
LinkerOpts.AppExtensionSafe =
|
|
Args.hasFlag(OPT_fapplication_extension, OPT_fno_application_extension,
|
|
/*Default=*/LinkerOpts.AppExtensionSafe);
|
|
|
|
if (::getenv("LD_NO_ENCRYPT") != nullptr)
|
|
LinkerOpts.AppExtensionSafe = true;
|
|
|
|
if (::getenv("LD_APPLICATION_EXTENSION_SAFE") != nullptr)
|
|
LinkerOpts.AppExtensionSafe = true;
|
|
return true;
|
|
}
|
|
|
|
Options::Options(DiagnosticsEngine &Diag, FileManager *FM,
|
|
InputArgList &ArgList)
|
|
: Diags(&Diag), FM(FM) {
|
|
if (!processDriverOptions(ArgList))
|
|
return;
|
|
|
|
if (!processLinkerOptions(ArgList))
|
|
return;
|
|
}
|
|
|
|
InstallAPIContext Options::createContext() {
|
|
InstallAPIContext Ctx;
|
|
// InstallAPI requires two level namespacing.
|
|
Ctx.BA.TwoLevelNamespace = true;
|
|
|
|
Ctx.BA.InstallName = LinkerOpts.InstallName;
|
|
Ctx.BA.CurrentVersion = LinkerOpts.CurrentVersion;
|
|
Ctx.BA.AppExtensionSafe = LinkerOpts.AppExtensionSafe;
|
|
Ctx.FT = DriverOpts.OutFT;
|
|
Ctx.OutputLoc = DriverOpts.OutputPath;
|
|
return Ctx;
|
|
}
|
|
|
|
} // namespace installapi
|
|
} // namespace clang
|