289 lines · cpp
1//===--- Haiku.cpp - Haiku ToolChain Implementations ------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Haiku.h"10#include "clang/Config/config.h"11#include "clang/Driver/CommonArgs.h"12#include "clang/Driver/Compilation.h"13#include "clang/Driver/SanitizerArgs.h"14#include "llvm/Support/Path.h"15 16using namespace clang::driver;17using namespace clang::driver::tools;18using namespace clang::driver::toolchains;19using namespace clang;20using namespace llvm::opt;21 22void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,23 const InputInfo &Output,24 const InputInfoList &Inputs,25 const ArgList &Args,26 const char *LinkingOutput) const {27 const auto &ToolChain = static_cast<const Haiku &>(getToolChain());28 const Driver &D = ToolChain.getDriver();29 const llvm::Triple &Triple = ToolChain.getTriple();30 const bool Static = Args.hasArg(options::OPT_static);31 const bool Shared = Args.hasArg(options::OPT_shared);32 ArgStringList CmdArgs;33 34 // Silence warning for "clang -g foo.o -o foo"35 Args.ClaimAllArgs(options::OPT_g_Group);36 // and "clang -emit-llvm foo.o -o foo"37 Args.ClaimAllArgs(options::OPT_emit_llvm);38 // and for "clang -w foo.o -o foo". Other warning options are already39 // handled somewhere else.40 Args.ClaimAllArgs(options::OPT_w);41 42 // Silence warning for "clang -pie foo.o -o foo"43 Args.ClaimAllArgs(options::OPT_pie);44 45 // -rdynamic is a no-op with Haiku. Claim argument to avoid warning.46 Args.ClaimAllArgs(options::OPT_rdynamic);47 48 if (!D.SysRoot.empty())49 CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));50 51 CmdArgs.push_back("--eh-frame-hdr");52 if (Static) {53 CmdArgs.push_back("-Bstatic");54 } else {55 if (Shared)56 CmdArgs.push_back("-shared");57 CmdArgs.push_back("--enable-new-dtags");58 }59 60 CmdArgs.push_back("-shared");61 62 if (!Shared)63 CmdArgs.push_back("--no-undefined");64 65 if (Triple.isRISCV64()) {66 CmdArgs.push_back("-X");67 if (Args.hasArg(options::OPT_mno_relax))68 CmdArgs.push_back("--no-relax");69 }70 71 assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");72 if (Output.isFilename()) {73 CmdArgs.push_back("-o");74 CmdArgs.push_back(Output.getFilename());75 }76 77 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,78 options::OPT_r)) {79 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));80 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbeginS.o")));81 if (!Shared)82 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("start_dyn.o")));83 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("init_term_dyn.o")));84 }85 86 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,87 options::OPT_s, options::OPT_t});88 ToolChain.AddFilePathLibArgs(Args, CmdArgs);89 90 if (D.isUsingLTO())91 addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs,92 D.getLTOMode() == LTOK_Thin);93 94 bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);95 addLinkerCompressDebugSectionsOption(ToolChain, Args, CmdArgs);96 AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);97 98 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,99 options::OPT_r)) {100 // Use the static OpenMP runtime with -static-openmp101 bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;102 addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);103 104 if (D.CCCIsCXX() && ToolChain.ShouldLinkCXXStdlib(Args))105 ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);106 107 // Silence warnings when linking C code with a C++ '-stdlib' argument.108 Args.ClaimAllArgs(options::OPT_stdlib_EQ);109 110 // Additional linker set-up and flags for Fortran. This is required in order111 // to generate executables. As Fortran runtime depends on the C runtime,112 // these dependencies need to be listed before the C runtime below (i.e.113 // AddRunTimeLibs).114 if (D.IsFlangMode() &&115 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {116 ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);117 ToolChain.addFortranRuntimeLibs(Args, CmdArgs);118 }119 120 if (NeedsSanitizerDeps)121 linkSanitizerRuntimeDeps(ToolChain, Args, CmdArgs);122 123 CmdArgs.push_back("-lgcc");124 125 CmdArgs.push_back("--push-state");126 CmdArgs.push_back("--as-needed");127 CmdArgs.push_back("-lgcc_s");128 CmdArgs.push_back("--no-as-needed");129 CmdArgs.push_back("--pop-state");130 131 CmdArgs.push_back("-lroot");132 133 CmdArgs.push_back("-lgcc");134 135 CmdArgs.push_back("--push-state");136 CmdArgs.push_back("--as-needed");137 CmdArgs.push_back("-lgcc_s");138 CmdArgs.push_back("--no-as-needed");139 CmdArgs.push_back("--pop-state");140 }141 142 // No need to do anything for pthreads. Claim argument to avoid warning.143 Args.claimAllArgs(options::OPT_pthread, options::OPT_pthreads);144 145 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,146 options::OPT_r)) {147 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));148 CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));149 }150 151 ToolChain.addProfileRTLibs(Args, CmdArgs);152 153 const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());154 C.addCommand(std::make_unique<Command>(JA, *this,155 ResponseFileSupport::AtFileCurCP(),156 Exec, CmdArgs, Inputs, Output));157}158 159/// Haiku - Haiku tool chain which can call as(1) and ld(1) directly.160 161Haiku::Haiku(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)162 : Generic_ELF(D, Triple, Args) {163 164 GCCInstallation.init(Triple, Args);165 166 getFilePaths().push_back(concat(getDriver().SysRoot, "/boot/system/lib"));167 getFilePaths().push_back(concat(getDriver().SysRoot, "/boot/system/develop/lib"));168 169 if (GCCInstallation.isValid())170 getFilePaths().push_back(GCCInstallation.getInstallPath().str());171}172 173void Haiku::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,174 llvm::opt::ArgStringList &CC1Args) const {175 const Driver &D = getDriver();176 177 if (DriverArgs.hasArg(options::OPT_nostdinc))178 return;179 180 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {181 SmallString<128> Dir(D.ResourceDir);182 llvm::sys::path::append(Dir, "include");183 addSystemInclude(DriverArgs, CC1Args, Dir.str());184 }185 186 if (DriverArgs.hasArg(options::OPT_nostdlibinc))187 return;188 189 // Add dirs specified via 'configure --with-c-include-dirs'.190 StringRef CIncludeDirs(C_INCLUDE_DIRS);191 if (!CIncludeDirs.empty()) {192 SmallVector<StringRef, 5> dirs;193 CIncludeDirs.split(dirs, ":");194 for (StringRef dir : dirs) {195 StringRef Prefix =196 llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";197 addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);198 }199 return;200 }201 202 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,203 "/boot/system/non-packaged/develop/headers"));204 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,205 "/boot/system/develop/headers/os"));206 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,207 "/boot/system/develop/headers/os/app"));208 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,209 "/boot/system/develop/headers/os/device"));210 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,211 "/boot/system/develop/headers/os/drivers"));212 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,213 "/boot/system/develop/headers/os/game"));214 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,215 "/boot/system/develop/headers/os/interface"));216 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,217 "/boot/system/develop/headers/os/kernel"));218 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,219 "/boot/system/develop/headers/os/locale"));220 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,221 "/boot/system/develop/headers/os/mail"));222 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,223 "/boot/system/develop/headers/os/media"));224 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,225 "/boot/system/develop/headers/os/midi"));226 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,227 "/boot/system/develop/headers/os/midi2"));228 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,229 "/boot/system/develop/headers/os/net"));230 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,231 "/boot/system/develop/headers/os/opengl"));232 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,233 "/boot/system/develop/headers/os/storage"));234 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,235 "/boot/system/develop/headers/os/support"));236 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,237 "/boot/system/develop/headers/os/translation"));238 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,239 "/boot/system/develop/headers/os/add-ons/graphics"));240 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,241 "/boot/system/develop/headers/os/add-ons/input_server"));242 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,243 "/boot/system/develop/headers/os/add-ons/mail_daemon"));244 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,245 "/boot/system/develop/headers/os/add-ons/registrar"));246 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,247 "/boot/system/develop/headers/os/add-ons/screen_saver"));248 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,249 "/boot/system/develop/headers/os/add-ons/tracker"));250 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,251 "/boot/system/develop/headers/os/be_apps/Deskbar"));252 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,253 "/boot/system/develop/headers/os/be_apps/NetPositive"));254 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,255 "/boot/system/develop/headers/os/be_apps/Tracker"));256 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,257 "/boot/system/develop/headers/3rdparty"));258 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,259 "/boot/system/develop/headers/bsd"));260 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,261 "/boot/system/develop/headers/glibc"));262 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,263 "/boot/system/develop/headers/gnu"));264 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,265 "/boot/system/develop/headers/posix"));266 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,267 "/boot/system/develop/headers/gcc/include"));268 addSystemInclude(DriverArgs, CC1Args, concat(D.SysRoot,269 "/boot/system/develop/headers"));270}271 272void Haiku::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,273 llvm::opt::ArgStringList &CC1Args) const {274 addSystemInclude(DriverArgs, CC1Args,275 concat(getDriver().SysRoot, "/boot/system/develop/headers/c++/v1"));276}277 278Tool *Haiku::buildLinker() const { return new tools::haiku::Linker(*this); }279 280bool Haiku::HasNativeLLVMSupport() const { return true; }281 282SanitizerMask Haiku::getSupportedSanitizers() const {283 SanitizerMask Res = ToolChain::getSupportedSanitizers();284 285 Res |= SanitizerKind::Address;286 287 return Res;288}289